islaApocalypse-v2/Core/Scripts/BuildingMaterial.cs
beezm 9107b0822b Phase 0: clean project skeleton for the v2 rewrite
Stands up the CODE_REPO the rewrite is written into (D-049, D-058). Godot 4.7.2 /
.NET 8 / Godot.NET.Sdk 4.7.2. Nothing is generated, meshed, or ported — this is the
shell and the two data contracts.

Four layers, each with its boundary stated in a directory README:
  Core/    math + data only, and engine-free — depends on nothing above it
  Server/  authoritative logic                (empty this phase)
  Client/  rendering                          (empty this phase)
  Tools/   the offline generator — may NOT reference Client   (Phase 1 fills it)

Contracts (compiling stubs, no algorithms):
  - Column model (D-053): a 2D grid of columns, each a stack of (material, thickness)
    runs, any material at any depth. Air is the TOP RUN — there is no air-vs-solid
    height branch, and no surface-height accessor exists to reintroduce one. Water is
    not a band; it stays an overlay.
  - Material schemas (D-054): terrain and building as two append-only registries,
    bridged by a recipe seam that is deliberately EMPTY. Identity is a registry key,
    never a serialized ordinal. Mesh style is per-ORIGIN and is not a material field.

Rails, so Phase 1 inherits them rather than rediscovering them:
  - GenerationScale: MapSize is a parameter, everything derives from it, nothing uses
    a raw pixel number. Tightening over the reference — decorrelation offsets are
    declared in map widths, not pixels (chat1/00 §4.2).
  - ToolingPaths: config/blueprint/output paths all env-overridable, resolved in one
    place, so a batch cannot touch the developer's live files.
  - FileSafety: the permanent no-deletion rules as throws rather than sentences.

user:// isolation: project name and use_custom_user_dir both pin the runtime dir to
~/.local/share/islaApocalypse-v2/, away from the old prototype's preserved seeds and
batches. Tools/Scenes/UserDirProbe.tscn confirms it rather than assuming it.
2026-08-19 20:21:12 -04:00

64 lines
2.3 KiB
C#

namespace IslaApocalypse.Core
{
/// <summary>
/// A row in the BUILDING material schema — what players construct with.
/// → `Design - Data - Material Schema.md` §2, D-054.
///
/// ⚠ DELIBERATELY A SEPARATE SCHEMA FROM <see cref="TerrainMaterial"/>, 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 <see cref="RecipeRegistry"/>, not a shared row type.
///
/// ⚠ NO MESH-STYLE FIELD HERE EITHER — same rule, same reason. See <see cref="TerrainMaterial"/>.
///
/// APPEND-ONLY. Adding a material is one new row.
/// </summary>
public sealed class BuildingMaterial
{
/// <summary>Identity. A registry key, not an ordinal.</summary>
public MaterialKey Key { get; }
/// <summary>Human-facing name. Presentation only.</summary>
public string DisplayName { get; }
/// <summary>
/// How far this material carries structural support from an anchor, before decay.
/// → `Design - Systems - Structural Integrity.md` (D-055: per-material reach).
/// </summary>
public float SupportReach { get; }
/// <summary>How fast support falls off across that reach. 0 = no decay, 1 = immediate.</summary>
public float SupportDecay { get; }
/// <summary>Weight the material imposes on what carries it.</summary>
public float Weight { get; }
/// <summary>Damage the material absorbs before failing.</summary>
public float Durability { get; }
/// <summary>
/// Runtime-only dense index. ⚠⚠ NEVER SERIALIZED — see <see cref="TerrainMaterial.RuntimeIndex"/>.
/// </summary>
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})";
}
}