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})"; } }