South town MVP: world sim, seasons, granary, contrast test + findings
Godot 4.7 C# world simulation per SPEC.md (with 2026-07-21 amendments). 15 NPCs, 5-state machine, demand-driven work, soul-imprint triad data model, seasons with winter frost, granary, need-based gift economy, selfish-soul contrast wiring, daily/per-villager/gift CSV logging. FINDINGS.md documents the four soak experiments: the dead paradise, the buffers winning, the emergent hungry gap, and the contrast test proving the four-town thesis (and that selfishness wins until the soul-consequence layer exists). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
namespace WorldSim;
|
||||
|
||||
/// <summary>
|
||||
/// Soul types — the four founding philosophies (SPEC §1).
|
||||
/// MVP uses Nature only; the others exist so nothing hardcodes a single type.
|
||||
/// </summary>
|
||||
public enum SoulType
|
||||
{
|
||||
Nature, // South — take only what you need
|
||||
Generational, // North — reverence for lineage
|
||||
Materialist, // West — worth measured in visible possessions
|
||||
Selfish, // East — personal gain, no guilt attached
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The soul imprint triad (SPEC §2 amendment, DESIGN.md debris model).
|
||||
/// The soul itself never changes — these are the layers over it.
|
||||
/// MVP behavior may read only Total, but all three sources are carried
|
||||
/// so later phases (residual-soul verdicts, awareness thresholds,
|
||||
/// source-specific clearing) need no data migration.
|
||||
/// </summary>
|
||||
public class SoulImprint
|
||||
{
|
||||
public float SelfRegard; // internal — how the soul sees itself
|
||||
public float OthersRegard; // internal — how the soul sees others
|
||||
public float ExternalPerception; // external — what others' souls pressed onto it
|
||||
|
||||
public float Total => (SelfRegard + OthersRegard + ExternalPerception) / 3f;
|
||||
public float Radiance => 1f - Total;
|
||||
|
||||
public void Clamp()
|
||||
{
|
||||
SelfRegard = Math.Clamp(SelfRegard, 0f, 1f);
|
||||
OthersRegard = Math.Clamp(OthersRegard, 0f, 1f);
|
||||
ExternalPerception = Math.Clamp(ExternalPerception, 0f, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behavior weights per soul type (SPEC §9). Constrained emergence:
|
||||
/// these weights pick WHICH valid option an NPC takes, never WHETHER
|
||||
/// a solution exists. Swappable per type — the engine stays agnostic.
|
||||
/// </summary>
|
||||
public class SoulProfile
|
||||
{
|
||||
public SoulType Type;
|
||||
|
||||
public float Generosity; // trade ratios, spontaneous help
|
||||
public float Sustainability; // harvest caps (South: ~50% of a node)
|
||||
public float CommunityBias; // communal-first building, socializing pull
|
||||
public float StatusBias; // West: visible-wealth preference (unused in MVP)
|
||||
public float Accumulation; // East: hoarding pressure (unused in MVP)
|
||||
|
||||
public static SoulProfile NatureSoul() => new()
|
||||
{
|
||||
Type = SoulType.Nature,
|
||||
Generosity = 0.9f,
|
||||
Sustainability = 0.9f,
|
||||
CommunityBias = 0.8f,
|
||||
StatusBias = 0.1f,
|
||||
Accumulation = 0.1f,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// East-weighted profile — not part of MVP behavior, but defined now for
|
||||
/// the end-of-MVP contrast test (SPEC §11 amendment): 3 selfish NPCs
|
||||
/// dropped into the South town to prove weights alone change the society.
|
||||
/// </summary>
|
||||
public static SoulProfile SelfishSoul() => new()
|
||||
{
|
||||
Type = SoulType.Selfish,
|
||||
Generosity = 0.1f,
|
||||
Sustainability = 0.2f,
|
||||
CommunityBias = 0.1f,
|
||||
StatusBias = 0.5f,
|
||||
Accumulation = 0.9f,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user