Files
mmcghen f9e22e872f Run 13: the full world - four towns, resources, bonds, spatial grid
World scaled 3x (768x768) with all four towns at compass points, each
running its own soul culture: North generational, South nature, West
materialist (new profile), East selfish. Two new resources: Ore (metal
tier) and Herb (medicine - mends health, reason to forage, trade good).
Spatial hash grid replaces O(n^2) proximity scans (soul pressure,
neighbor, teacher) - 3.6x headless speedup at ~80 NPCs. First social
verb beyond work: pair-bonds - settled adults who keep warm company pair
up; warmth now accrues from proximity not only gifts; bonds break at
death. Reproduction deferred (bonds-first per plan).

The four-town thesis fully realized on one engine (240-day run):
North know 1.27 clean, South nourish 0.85 clean, West prosperous but
debris 0.23, East hungriest 0.60 and lowest knowledge 1.08. Positive
cultures stay soul-clean, negative ones carry real debris, all from
behavior weights - nothing scripted. 99 bonds, 80 deaths, four living
societies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 17:04:19 -04:00

128 lines
5.0 KiB
C#

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)
// Knowledge culture (SPEC §5): how readily this soul absorbs from
// others, and how deliberately it passes on what it knows. The North's
// whole identity lives in these two numbers.
public float Absorption = 1f; // learning rate multiplier
public float TeachingDrive = 0f; // how much being near this soul teaches
public static SoulProfile NatureSoul() => new()
{
Type = SoulType.Nature,
Generosity = 0.9f,
Sustainability = 0.9f,
CommunityBias = 0.8f,
StatusBias = 0.1f,
Accumulation = 0.1f,
Absorption = 1.0f,
TeachingDrive = 0.3f, // knowledge passes casually, by living together
};
/// <summary>
/// North-weighted profile: reverence for lineage, strong communal pull,
/// modest material appetite. Their signature system — generational
/// knowledge transfer (SPEC §5) — arrives with the expansion phase;
/// until then they differ from the South in temperament, not verbs.
/// </summary>
public static SoulProfile GenerationalSoul() => new()
{
Type = SoulType.Generational,
Generosity = 0.8f,
Sustainability = 0.8f,
CommunityBias = 0.95f,
StatusBias = 0.15f,
Accumulation = 0.2f,
Absorption = 1.6f, // raised to receive what elders hand down
TeachingDrive = 0.9f, // and to hand it down in turn — the whole culture
};
/// <summary>
/// West-weighted profile: worth measured in visible possessions
/// (DESIGN.md). They build — even communally — but for display, so they
/// expand shelters hard (status is size); moderate generosity, moderate
/// hoarding, little interest in learning or teaching. A functioning town
/// whose surplus goes to ostentation rather than resilience.
/// </summary>
public static SoulProfile MaterialistSoul() => new()
{
Type = SoulType.Materialist,
Generosity = 0.4f,
Sustainability = 0.6f,
CommunityBias = 0.6f,
StatusBias = 0.9f,
Accumulation = 0.6f,
Absorption = 0.9f,
TeachingDrive = 0.2f,
};
/// <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,
Absorption = 0.7f, // they take, but rarely sit still to learn
TeachingDrive = 0.0f, // and teach no one anything, ever
};
}