namespace IslaApocalypse.Core
{
///
/// A row in the BUILDING material schema — what players construct with.
/// → `Design - Data - Material Schema.md` §2, D-054.
///
/// ⚠ DELIBERATELY A SEPARATE SCHEMA FROM , NOT A TAG ON ONE TABLE.
/// Natural stone and a placed stone block are not the same thing tagged differently: one is a
/// resource you harvest, the other is something you craft and build with. One tagged table was
/// considered and REJECTED — it blurs the resource→product relationship that IS the survival
/// loop, and invites the two concerns to bleed into each other the way biomes bled into terrain.
/// The bridge between the two schemas is , not a shared row type.
///
/// ⚠ NO MESH-STYLE FIELD HERE EITHER — same rule, same reason. See .
///
/// APPEND-ONLY. Adding a material is one new row.
///
public sealed class BuildingMaterial
{
/// Identity. A registry key, not an ordinal.
public MaterialKey Key { get; }
/// Human-facing name. Presentation only.
public string DisplayName { get; }
///
/// How far this material carries structural support from an anchor, before decay.
/// → `Design - Systems - Structural Integrity.md` (D-055: per-material reach).
///
public float SupportReach { get; }
/// How fast support falls off across that reach. 0 = no decay, 1 = immediate.
public float SupportDecay { get; }
/// Weight the material imposes on what carries it.
public float Weight { get; }
/// Damage the material absorbs before failing.
public float Durability { get; }
///
/// Runtime-only dense index. ⚠⚠ NEVER SERIALIZED — see .
///
public int RuntimeIndex { get; internal set; } = -1;
public BuildingMaterial(
MaterialKey key,
string displayName,
float supportReach,
float supportDecay,
float weight,
float durability)
{
Key = key;
DisplayName = displayName;
SupportReach = supportReach;
SupportDecay = supportDecay;
Weight = weight;
Durability = durability;
}
public override string ToString() => $"BuildingMaterial({Key})";
}
}