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.
79 lines
2.8 KiB
C#
79 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace IslaApocalypse.Core
|
|
{
|
|
/// <summary>
|
|
/// ⭐ THE TRANSFORMATION / RECIPE SEAM — the bridge between the two material schemas.
|
|
/// → `Design - Data - Material Schema.md` §3, D-054.
|
|
///
|
|
/// Terrain materials are RESOURCES that refine and combine into BUILDING materials —
|
|
/// e.g. sand + clay + rock → concrete. That relationship is the survival loop, and keeping the
|
|
/// two schemas distinct with a transformation between them is what stops it collapsing into
|
|
/// "the same material tagged differently".
|
|
///
|
|
/// ⚠⚠ THIS REGISTRY IS DELIBERATELY EMPTY, AND THAT IS THE POINT.
|
|
///
|
|
/// The recipes themselves are DEFERRED. Designing the resource tree now would be a
|
|
/// biomes-premature-style over-commitment — the exact mistake the rewrite exists to undo.
|
|
/// But the SEAM EXISTS NOW: the architecture has the hole, so filling it later is new ROWS and
|
|
/// never a rewrite.
|
|
///
|
|
/// Do not add recipes here without a design decision that says the tree is ready.
|
|
/// </summary>
|
|
public static class RecipeRegistry
|
|
{
|
|
private static readonly List<Recipe> _recipes = new();
|
|
|
|
// ===== NO SEED ROWS. See the class comment — the emptiness is the design. =====
|
|
|
|
/// <summary>Append a recipe. Append-only, same as the material registries.</summary>
|
|
public static void Register(Recipe recipe)
|
|
{
|
|
if (recipe == null) throw new ArgumentNullException(nameof(recipe));
|
|
_recipes.Add(recipe);
|
|
}
|
|
|
|
public static IReadOnlyList<Recipe> All => _recipes;
|
|
public static int Count => _recipes.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// One transformation: some quantity of terrain-derived inputs produces a building material.
|
|
///
|
|
/// ⚠ SHAPE ONLY. The exact recipe FORMAT is an open note in the design doc — inputs may grow
|
|
/// tools, stations, time or byproducts. This is the minimum that makes the seam real enough to
|
|
/// compile against, not a committed format.
|
|
/// </summary>
|
|
public sealed class Recipe
|
|
{
|
|
/// <summary>Input material keys and their amounts. Terrain-derived resources.</summary>
|
|
public IReadOnlyList<RecipeInput> Inputs { get; }
|
|
|
|
/// <summary>The building material produced.</summary>
|
|
public MaterialKey Output { get; }
|
|
|
|
/// <summary>How much of <see cref="Output"/> one application yields.</summary>
|
|
public int OutputAmount { get; }
|
|
|
|
public Recipe(IReadOnlyList<RecipeInput> inputs, MaterialKey output, int outputAmount)
|
|
{
|
|
Inputs = inputs ?? throw new ArgumentNullException(nameof(inputs));
|
|
Output = output;
|
|
OutputAmount = outputAmount;
|
|
}
|
|
}
|
|
|
|
/// <summary>One input line of a <see cref="Recipe"/>.</summary>
|
|
public readonly struct RecipeInput
|
|
{
|
|
public readonly MaterialKey Material;
|
|
public readonly int Amount;
|
|
|
|
public RecipeInput(MaterialKey material, int amount)
|
|
{
|
|
Material = material;
|
|
Amount = amount;
|
|
}
|
|
}
|
|
}
|