docs(composer): the system should invent worlds -- design session notes
A long design conversation, written down as it happened. The headline: the op stack's "Phase 3" is REOPENED. Asked what the world was missing, Jahni described exactly it -- the system assembling worlds from data assets and a seed -- so the 2026-08-16 handoff's "do NOT start Phase 3" is superseded. Then a correction that moved the whole thing a level deeper: he does not want to author strates either. The system must INVENT them. He authors raw content (operators, meshes, materials, sounds, creatures) and tags it; everything above that is composed and measured. Decided along the way: worlds are wiped every 6-12 months, which dissolves the "generation is frozen forever once public" problem -- generation is frozen only within a season. Shared player builds are blueprint structures, vote-ranked. Housing is an instanced level built from a snapshot of land the player chose. Danger is depth x a per-strate multiplier, not a sort. Every strate has a findable entrance and exit -- built first, generated around. The range problem turned out cheap: don't roll 73 parameters independently (that is what makes mush), blend known-good ones with FStrateGenerationParams::Lerp, which already exists and already blends the whole field set. Ranges come from the spread of the existing corpus, not from authored numbers. Verified against the code: the X-macro is in sync with the struct, only Alpha differs. Recurring mechanism, arrived at three separate times: measure, don't declare -- and promote what measures well back into the corpus, so the system's vocabulary grows from its own history. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DPUuCtn5zTLui6WybLbkNb
This commit is contained in:
1 parent
451ebcb776
commit
d8f7dabee8
1 file changed
+702
@@ -0,0 +1,702 @@
|
||||
# COMPOSER-NOTES.md — running notes on the world-composer conversation
|
||||
|
||||
> Started 2026-08-17. Small on purpose: what we decided, what's still open, what must not be
|
||||
> forgotten. Not a design doc — that comes later, if it earns it.
|
||||
|
||||
## The idea, in one line
|
||||
|
||||
**Jahni authors the vocabulary; the system writes the sentences.** He makes data assets (ops, biomes,
|
||||
deco sets, set-pieces, whole handmade levels/strates); the system assembles strates and worlds out of
|
||||
them from the seed, *logically*.
|
||||
|
||||
This is op-stack **Phase 3 + a composer layer above it**. The 2026-08-16 handoff's "do NOT start
|
||||
Phase 3" is **superseded** — it closed the door on the one thing he actually wants.
|
||||
|
||||
## Decided
|
||||
|
||||
- **Ambition level (c):** the seed invents parameters within authored ranges. Not preset-picking.
|
||||
- **Two seeds differ in everything** — not the same strates spawn, nor the details.
|
||||
- **⭐ Primordial law:** *every strate has an entrance and an exit, exposed to air, findable.*
|
||||
- **Handmade content plugs in** as stamps **and** as whole strates (e.g. a unique boss strate) —
|
||||
entries in the pool with special placement rules.
|
||||
- **Build the connections first, generate around them.** Reachability by construction, not by luck.
|
||||
Precedent: the (0,0) spine is already a guaranteed vertical connector. Generate-then-check gets
|
||||
brutal at 8 strates/world.
|
||||
- **Validation is 3 layers:** (1) construct-by-design so the law can't break, (2) *measurable* checks
|
||||
for accidents — air fraction, continuous walkable surface, feature size vs voxel scale, strate
|
||||
height sanity, (3) **reject-and-resample**: fold the attempt number into the hash
|
||||
(`hash(seed, strateSlot, attempt)`) so every seed still yields a valid world and peers stay in
|
||||
lockstep.
|
||||
- **The AI good/bad judge is second, not first.** Not a fool idea — but the cost is *labels*, and
|
||||
Jahni is the only labeller. Layers 1–3 remove the numeric garbage; what's left is genuine taste,
|
||||
a much smaller job. The dataset then accumulates for free from seeds he plays and reacts to.
|
||||
- **F4 save/load is the LOCK on the density field, not a feature.** Everything field-changing lands
|
||||
before it. The composer is the largest field-changing work that exists ⇒ far ahead of F4.
|
||||
- **Acceptance criteria get stated up front and confirmed by Jahni** — never inferred. (The
|
||||
bit-identity criterion was self-imposed and cost 3 weeks; peer determinism never required matching
|
||||
an older build. Determinism = same build, all machines. Version stability = a gen-version byte.)
|
||||
|
||||
## Open
|
||||
|
||||
- What makes a **world** coherent above the strate level? (depth-driven rules? tag adjacency? an arc?)
|
||||
- What is a strate *as a unit the composer picks* — pool + tags + depth bands? Fixed count per world?
|
||||
- "**Findable**" ≠ "reachable". Reachable is a number; findable is placement (light, airflow,
|
||||
landmark, terrain funnelling you toward it). Whose job, and how expressed?
|
||||
- Where do the authored **ranges** live, and can they be context-dependent (this op's range depends
|
||||
on what else is in the stack)?
|
||||
|
||||
## Hazards — do not forget
|
||||
|
||||
- ⚠️ **Box-verdict bounds under (c).** T1.d / `ClassifyTile` bounds are proved today against
|
||||
*hand-set* params. If the seed invents params, every bound must hold across the whole authored
|
||||
**range**, not a value. Wrong ⇒ a tile wrongly proved uniform ⇒ no geometry, no collision, no
|
||||
error, player falls through the floor. The only silent failure mode in the system.
|
||||
- ⚠️ **`ClassifyTile` proves anything below `TerrainZ` solid** and skips meshing — it will silently
|
||||
delete 3D caves inside mountains unless guarded.
|
||||
- ⚠️ **Validation must itself be deterministic** across every machine that runs it — including a
|
||||
future headless Linux dedicated server, where float behaviour may not match the Windows client.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — the FEEL: magical, not logical
|
||||
|
||||
Jahni corrected the direction. He does **not** want a geologically reasoned world. He wants it to feel
|
||||
**magical** — the game throwing countless worlds at the player, *of any kind, any size, any
|
||||
peculiarity*. Examples he gave: an alien-looking surface strate; a **"dreamcore"** strate — repetitive
|
||||
patterns, a strange sense of emptiness.
|
||||
|
||||
- **Adjacency rules: CONFIRMED** (he agrees with those).
|
||||
- **Depth-as-meaning: UNDECIDED.** The old model was "deeper ⇒ weirder, stranger, spookier"; he is no
|
||||
longer sure that's right. Do not assume it.
|
||||
- ⚠️ My earlier pitch ("coherence makes the world *readable*; depth should mean heat/pressure/danger")
|
||||
was arguing for a **different game**. Dropped.
|
||||
|
||||
**Reframe that survives his goal:** coherence lives **inside** a strate, not across the stack. The
|
||||
strate is the unit of authorship — one complete, committed idea, thoroughly itself. Placement can be
|
||||
arbitrary; the strate still feels authored.
|
||||
|
||||
Ideas on the table (none decided):
|
||||
- **Rarity instead of depth.** Weird strates are *rare*, not *deep* — you could hit dreamcore at
|
||||
−200 m. Descent feels like drawing cards, which serves "countless worlds" better than a gradient.
|
||||
- **Strangeness needs ordinary to be strange against.** Guarantee a share of grounded strates so the
|
||||
weird ones land. A rule about the **mix**, not about depth.
|
||||
- **Adjacency rules become PACING rules:** no two alike in a row; a grounded strate sets up a weird
|
||||
one; special pairs (flooded over lava) earn a real transition.
|
||||
- **Size and count are free variables** — a 40 m crawlspace strate vs a 2 km cathedral. Cheap to
|
||||
vary, huge effect on feel. "Any size" was explicit in his description.
|
||||
- The **unique boss strate** implies a *destination without a gradient*. An end is enough; every step
|
||||
need not escalate.
|
||||
|
||||
**Open question left hanging:** does the world have a **bottom the player knows about**? "Boss strate"
|
||||
implies an end; "countless worlds" implies endless. Those pull in opposite directions.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — what the GAME is (context that reshapes the above)
|
||||
|
||||
**Fantasy exploration + combat RPG.** Medieval-ish, progressing toward better / more modern
|
||||
infrastructure but staying inside fantasy. Side systems: **housing and farming**. Needs **bosses**,
|
||||
and **fights that don't feel "blergh."**
|
||||
|
||||
Consequences for the composer:
|
||||
|
||||
- **Progression needs difficulty to correlate with position — but not by killing the magic.**
|
||||
Proposal: **draw strates freely (rarity, any kind, any size), then SORT the drawn set by their own
|
||||
danger rating.** Identity stays random; difficulty comes out ordered by construction. Depth then
|
||||
means *danger* without ever meaning *weirdness*.
|
||||
- ⚠️ **Housing is the real lock on the density field — harder than F4 save/load.** A house has a
|
||||
*location* in a world that must keep existing. Once players build, the generator's output for that
|
||||
seed is frozen forever. Everything field-changing must land before housing ships.
|
||||
- **Farming/housing need buildable space:** flat-ish, stable, safe, reachable, probably surface. A
|
||||
composer that only makes dramatic terrain has nowhere to put a farm. Likely: strate 0 stays the
|
||||
grounded home base.
|
||||
- **F8 (ore veins) is promoted from reward-loop polish to BACKBONE.** "Progression to better
|
||||
infrastructure" is a tech tree, and a tech tree needs a supply chain. Ore quality should ride the
|
||||
same danger ordering.
|
||||
- **Fights need fightable space.** Default caves are hostile to good combat — cramped, no sightlines,
|
||||
bad camera. Good fights want verticality, cover, chokepoints, room to retreat. ⇒ the composer must
|
||||
treat **arenas as a first-class output**, not hope one occurs. This is exactly why boss strates are
|
||||
handmade.
|
||||
|
||||
**Next open question:** is the home base fixed on the surface with the descent run as **expeditions**
|
||||
(go down, come back up — cf. F14 lift/teleport anchors), or is it a **one-way descent**? Decides
|
||||
whether strates are re-entered or passed through once, and shapes the entrance/exit law.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — the world is a PUBLIC SHARED ARTIFACT (the biggest constraint yet)
|
||||
|
||||
- **Home = a hand-authored city, above ground, with a big opening inside** (the descent hub). Not
|
||||
generated. Ties to the primordial law: the city opening *is* the hand-placed entrance to strate 1.
|
||||
- Natural buildable space where the world offers it; otherwise **terrain-editing tools** for players.
|
||||
Underground building: undecided, idea is alive.
|
||||
- **Strates are revisitable and permanent to the player's view** — "fetch fish at the crystalline lake
|
||||
in strate X" must be a valid quest. Places are *discovered*, and **discoveries get shared online**.
|
||||
- **Players share BUILDS across worlds.** Everyone's world is the same world, so a bridge one player
|
||||
builds can propagate to other players' worlds if it's liked. Community feeling of exploration.
|
||||
Jahni: "it all fails without players." Landmark **names** may propagate the same way.
|
||||
- **Landmarks need names** — from a word pool or similar.
|
||||
|
||||
### What this forces
|
||||
|
||||
- ⚠️ **Version stability is now a REAL requirement, and I was too casual about it earlier.** A
|
||||
gen-version byte migrates a save file. It cannot migrate a *community's shared knowledge*. Once
|
||||
wikis, quests, videos and shared builds cite "the crystalline lake at (X,Y,Z)", the density field is
|
||||
frozen **globally and permanently**, not per-save. ⇒ **The composer must be finished before the
|
||||
world becomes public.** (This does NOT revive bit-identity to the OLD system — matching a dead
|
||||
build was always pointless. It sharpens *when* the future freeze lands.)
|
||||
- **The diff layer is already the correct transport for shared builds:** position + compact
|
||||
modification records, deterministic to apply, "replicate diff events, never geometry". A shared
|
||||
build is a diff patch with an address.
|
||||
- ⭐ **The composer must emit a WORLD MANIFEST, not just a density field.** A list of everything
|
||||
notable it placed — stable ID, type, position, extent, strate. Otherwise nothing can *name* the
|
||||
crystalline lake, no quest can reference it, no map can mark it, no wiki can cite it, no fast travel
|
||||
can target it. The composer already knows what it placed; it just has to write it down instead of
|
||||
discarding it. **Cheap now, enormously expensive to retrofit.**
|
||||
- **Naming = two layers.** (1) A **deterministic procedural name** from a word pool, so every landmark
|
||||
has the *same* name for every player *before anyone visits it* — that is the substrate that makes
|
||||
quests and wikis possible at all. (2) An optional **community name** that propagates like builds and
|
||||
overrides the default. Beloved names win; nothing is ever nameless.
|
||||
- **Shared-build hazards to design in, not bolt on:** two builds claiming the same place; a build that
|
||||
seals an entrance/exit and **violates the primordial law**; and content moderation — auto-propagating
|
||||
user-built voxel content into strangers' worlds needs a report/reject/rollback path, and shared
|
||||
builds must be individually removable client-side.
|
||||
|
||||
**Open fork:** does a shared build travel as **raw terrain edits** (voxel diff) or as **placed
|
||||
structure pieces** (a prefab/building system)? Completely different to transmit, validate and moderate.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — shared builds: BLUEPRINTS, not terrain diffs (fork resolved)
|
||||
|
||||
**Decided:** shared builds are **defined blueprint structures** (a parent/children blueprint family
|
||||
made for construction), *not* raw terrain edits. Raw voxel edits are too hard to constrain.
|
||||
|
||||
**Vote system (Jahni's):** votes drive a priority list. Unvoted / negatively voted ⇒ back of the
|
||||
queue. Sufficiently negative ⇒ **invalidated for sharing, never pulled again.** Where two builds
|
||||
compete for the same zone, higher votes ⇒ better chance to appear.
|
||||
|
||||
### Why blueprints are the right call beyond moderation
|
||||
- **Payload is tiny:** blueprint class ID + transform + variation params. Bytes, not a voxel diff.
|
||||
- **Validatable without simulating voxels** — bounds are known, so "does it seal a passage / violate
|
||||
the primordial law" is a cheap check.
|
||||
- ⭐ **It survives content updates.** Change the blueprint asset and every placed instance updates.
|
||||
A baked voxel diff can never be improved after the fact.
|
||||
|
||||
### Open design issues on the vote loop
|
||||
- ⚠️ **Cold start / rich-get-richer.** A build must be *seen* to be voted on; if appearance is ranked
|
||||
by votes, new builds never appear ⇒ never get votes. Reserve a fraction of appearances for
|
||||
new/unvoted builds (explore vs exploit).
|
||||
- **Rank by confidence, not raw count** — otherwise an old build with 1000 votes permanently outranks
|
||||
a better new one with 10. Some **time decay** too, or the top calcifies and the world stops changing.
|
||||
- **"Never pulled again" is a hard delete** — needs volume thresholds, not just ratio, so a small
|
||||
group can't bury a build. Keep it soft/reversible server-side even if permanent to clients.
|
||||
- Blueprint construction shrinks the crude-content surface but does not remove it (pieces can still be
|
||||
arranged). Report + rollback path still required.
|
||||
|
||||
### ⭐ Proposal: build SLOTS, not free coordinates
|
||||
The composer marks **candidate build sites** in the world manifest (type, extent, strate — a bridge
|
||||
site across a chasm, a shrine site at a passage mouth, a camp site on a ledge). Shared builds then
|
||||
compete for *slots*, not arbitrary positions. Placement becomes valid by construction, "the zone" gets
|
||||
a concrete definition, and conflict resolution is just "who wins this slot."
|
||||
|
||||
### ⚠️ Tension to resolve: canon vs roll
|
||||
Earlier: the world is the *same* for everyone, so a wiki can cite it. But vote-weighted "more chances
|
||||
to appear" implies each player **rolls** which builds they get. Both can't be fully true.
|
||||
Proposed split: **terrain and landmarks are canon (identical for all); shared builds are a roll.**
|
||||
The wiki cites natural features; builds are the variable garnish.
|
||||
Also: **pin a build once a player has seen it** — the world may gain builds over time, but shouldn't
|
||||
silently lose one you've come to know (or built your house next to).
|
||||
**Player claims beat shared builds** — a shared build must never roll into player-owned ground.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — SEASONS: worlds are wiped (this dissolves the freeze problem)
|
||||
|
||||
**Decided:**
|
||||
- The **base generation** — everything defined at generation time — **is** the shared world, identical
|
||||
for everyone. **Shared builds are a LAYER ON TOP** that adds to it. (Confirms the canon/roll split.)
|
||||
- **New and unvoted builds must be rolled in deliberately**, to give new players and new builds a
|
||||
chance. Confirmed.
|
||||
- ⭐ **A world is STATIC once published, until it is WIPED** — perhaps every 6–12 months — to make
|
||||
room for generation changes and other evolution.
|
||||
|
||||
### What seasons change (important — supersedes my earlier warning)
|
||||
- ⚠️ I said two messages ago that once the world goes public the density field is frozen **globally and
|
||||
permanently**, so the composer had to be *finished* first. **With wipes that is false, and it's the
|
||||
best news in this conversation.** Generation is frozen only **within a season**. Every wipe is a free
|
||||
window to change noise, ops, bounds, archetypes, anything.
|
||||
- ⇒ The composer can ship **imperfect and improve every cycle**. No need to get it right before contact
|
||||
with players. Bit-identity anxiety is now dead permanently — worlds are *expected* to differ by
|
||||
version, by design.
|
||||
- ⇒ **A world = seed + generator version + publish date.** Stamp the generator version into the
|
||||
published world; that stamp is the whole of "version stability" now.
|
||||
- ⇒ Concrete unblock: **T2.a (SIMD noise)** and anything else that changes generator output was parked
|
||||
in `fable-idea.md` because it shifts seeds. At a wipe boundary that cost is **zero**. Same for the
|
||||
large-seed noise-collapse fix in `AUDIT-2026-07.md`.
|
||||
|
||||
### ⭐ Proposal: the BLUEPRINT LIBRARY is what survives a wipe
|
||||
Your house dies with the world; your **design** doesn't. If shared builds are blueprint structures,
|
||||
the corpus of player creations can persist **across** seasons — so the vote/priority pool grows richer
|
||||
every cycle instead of resetting, and returning players carry something forward into a fresh world.
|
||||
That makes the wipe survivable for the housing/farming players, who otherwise lose the most.
|
||||
|
||||
**Knowledge dying at the wipe is a FEATURE.** Re-discovery is the loop; a wiped world resets the
|
||||
"everything is already solved and on the wiki" state that eventually kills exploration games. The
|
||||
community re-explores together, which is the exact feeling Jahni is after. The **hand-authored city**
|
||||
stays constant across seasons — the anchor of familiarity.
|
||||
|
||||
### Open
|
||||
- **What else survives a wipe?** Account progression / unlocks / recipes / reputation / cosmetics?
|
||||
Nothing? (Pure reset is brutal on housing + farming players.)
|
||||
- **One world at a time globally, or several shards on different seeds?**
|
||||
- **Does singleplayer/offline get a permanent world**, or do wipes apply there too? (Many seasonal
|
||||
games run a permanent realm alongside the seasonal one.)
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — wipe scope, housing, and the vote pool
|
||||
|
||||
**Decided:**
|
||||
- **The wipe is world-only.** Everything else survives (account progression etc.).
|
||||
- **The vote/build pool does NOT survive a seed change** — nothing would be placed correctly. It is
|
||||
wiped, with **rewards for the top builders** (titles etc.), tiered by population (10/50/100/1000).
|
||||
- **Housing → "instanced worlds":** custom personal worlds that are never wiped. Jahni finds this
|
||||
*slightly sad* — it cuts the player out of the strates and the shared world. Underground building
|
||||
still undecided.
|
||||
- **Everyone shares one seed**, until the game is big enough to offer "reboots" (shards).
|
||||
- **Singleplayer** was never the intent (online-first), but may become an option.
|
||||
|
||||
### Refinement: placement dies, DESIGN needn't
|
||||
A blueprint build has two separable parts: **where it sits** (chasm-specific, absolutely world-bound —
|
||||
Jahni is right that this cannot survive) and **the design itself** (pieces in relative arrangement,
|
||||
placement-independent). So:
|
||||
- **Shared/competitive pool: WIPED.** And the strongest argument isn't placement — placement *could*
|
||||
be re-matched to new slots by fit. It's **fairness**: carrying the corpus forward means season 2
|
||||
opens already full of season 1's voted builds, and every new player competes against an entrenched
|
||||
corpus forever. A fresh pool gives each season a fresh creative economy.
|
||||
- **Personal library: KEPT (private).** A player keeps their own designs, so they can rebuild a
|
||||
beloved house in the new world and re-submit it to the new pool. **The loss is the location, not the
|
||||
work** — that is what makes a wipe emotionally survivable.
|
||||
- **Titles carrying across** is what lets *reputation* survive when the builds don't — a season ending
|
||||
rather than a deletion. Optional knob: a small roll-boost for proven builders, which also softens
|
||||
the cold-start problem (watch that it doesn't recreate rich-get-richer).
|
||||
|
||||
### ⭐ The "slightly sad" instanced world may not be necessary
|
||||
**The hand-authored city is already wipe-proof** — it isn't generated, so a generation change can't
|
||||
invalidate it. Put persistent housing **there** (a district / plots / interiors, city-adjacent
|
||||
authored farmland) and it survives every wipe with **no instancing at all**, keeping players inside
|
||||
the shared world and visible to each other at the social hub. Instancing then shrinks to the standard,
|
||||
small MMO problem of interiors/plots rather than whole private worlds.
|
||||
|
||||
### ⚠️ HAZARD — a never-wiped *generated* instanced world reintroduces the freeze problem
|
||||
If a personal world is generated by generator v3 and is never wiped, then v3 must be kept alive
|
||||
**forever** — every old code path, every old bound, pinned per world — or that player's world breaks.
|
||||
That is the "support every version forever" trap, in a side corner, undoing exactly what seasons just
|
||||
bought. Avoid by making persistent personal space **non-generated** (authored plot / city district),
|
||||
or by regenerating it each season and **re-placing the blueprints** (possible precisely because
|
||||
blueprint builds are placement-independent).
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — housing: bake the plot (and why a MESH is the wrong bake)
|
||||
|
||||
**Constraints from Jahni:**
|
||||
- **The social hub is later** — infrastructure + difficulty. Not now.
|
||||
- ⚠️ **The surface is very limited, on purpose** — story-wise it is *why* players descend for space and
|
||||
resources. ⇒ **housing everyone on the surface does not scale**, so the "put housing in the
|
||||
hand-authored city" idea above does not hold as the general answer.
|
||||
- **His proposal:** bake the player's generated instance into a **mesh**, so the plot no longer depends
|
||||
on the generation system. Players can switch or destroy their house anytime; otherwise it's safe.
|
||||
|
||||
**That solves the version-pinning hazard properly** — a baked region needs no generator, so no old
|
||||
generator has to be kept alive. Right instinct.
|
||||
|
||||
### ⭐ Refinement: snapshot the FIELD, not the mesh
|
||||
Bake the sampled **density + material IDs** for the bounded plot region, not triangles:
|
||||
- **A mesh can't be dug.** Housing/farming ship alongside player terrain-editing tools; a baked mesh
|
||||
kills that inside the one place players care most about.
|
||||
- **A mesh freezes the plot against every future mesher/material improvement** (Transvoxel, normals,
|
||||
surface-class polygroups, F6 masks). That just moves the museum problem from the generator to the
|
||||
mesher. A field snapshot re-meshes with whatever the current mesher is.
|
||||
- Density fields **compress very well** — most of a plot is uniformly solid or uniformly air.
|
||||
- ⚠️ **The plot must be BOUNDED** or storage scales with ambition.
|
||||
|
||||
Architecturally this is: **a per-region override source in the generation path** — "this region has a
|
||||
stored field, read it instead of evaluating the op stack."
|
||||
|
||||
### ⭐ Same mechanism ships hand-authored content
|
||||
A hand-made boss strate or a distributed handmade level **is** a stored field region. The override
|
||||
source Jahni needs for houses is the same one he needs for authored levels/stamps. **One feature, two
|
||||
uses — build it once.**
|
||||
|
||||
### On the wipe, for a plot
|
||||
Simplest split: **the house travels, the ground doesn't.** Blueprints are placement-independent, so
|
||||
they re-place in the new world; the terrain regenerates. Avoids having to blend a baked plot into
|
||||
fresh generated terrain (seams at the plot edge) — which would otherwise need a reserved "homestead
|
||||
slot" plus a blend skirt. Keep that harder option in reserve, don't build it first.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — housing: SETTLED
|
||||
|
||||
- **Personal housing = an instanced level**, not a place in the shared world. Their own tiny world;
|
||||
never wiped, never re-placed.
|
||||
- ⭐ **The plot's ground is a snapshot of land the player CHOSE** in the shared world and claimed.
|
||||
Their home is *from* somewhere. After a wipe it is the last surviving fragment of a world that no
|
||||
longer exists — the wipe becomes meaningful rather than lossy, and the descent gains a second motive
|
||||
beyond resources: finding somewhere worth living.
|
||||
- **One template level, populated from save data** — a stored field region + a list of blueprint
|
||||
transforms. **Not** one `.umap` per player (cooked assets can't be made at runtime).
|
||||
- **Invites needed** — houses can be shared/visited.
|
||||
- **Time-based growth computed from elapsed real time on entry**, not ticked (the instance isn't
|
||||
loaded while the player is away).
|
||||
|
||||
⇒ **Concrete plugin work implied:** a **stored-field source** for the voxel world (read a saved region
|
||||
instead of evaluating the op stack) **+ its save format**. Same feature ships hand-authored levels /
|
||||
boss strates. Bounded region size is the one thing to fix early.
|
||||
|
||||
---
|
||||
|
||||
## STILL AWAITING JAHNI'S RULING (my proposals — do NOT treat as decided)
|
||||
|
||||
1. **World manifest** — the composer emits a list of everything notable it placed (stable ID, type,
|
||||
position, extent, strate). Needed for landmark names, quest references, maps, fast travel, and
|
||||
build slots. Biggest architectural consequence of anything proposed here.
|
||||
2. **Danger rating + sort** — draw strates freely (any kind, any size, any rarity), then order the
|
||||
drawn set by their own danger rating, so depth means *difficulty* without ever meaning *weirdness*.
|
||||
3. **The mix rule** — guarantee a share of grounded/plausible strates so the strange ones land.
|
||||
Strangeness needs ordinary to be strange against.
|
||||
4. **Build slots** — the composer marks candidate build sites; shared builds compete for *slots*
|
||||
rather than free coordinates.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — RULINGS from Jahni on the four proposals
|
||||
|
||||
### 1. World manifest — ✅ ACCEPTED, "must not be expensive"
|
||||
**Make it free by inverting it: the manifest is not an export, it is the PLAN.**
|
||||
The composer's layout pass runs *first* — pick strates, place connections, place landmarks/rooms/
|
||||
arenas — and that decision list **is** the manifest. The density field is generated *from* it. So it
|
||||
is never derived by scanning terrain (which is what would be expensive and unreliable).
|
||||
- **Only explicitly placed decisions go in** — landmarks, rooms/POIs, lakes, arenas, entrances/exits,
|
||||
build sites. **Not** emergent terrain features (every rock, every ledge).
|
||||
- Rough size: ~8 strates × 50–200 entries × ~32–64 B ⇒ **~100 KB per world**. Computed once, identical
|
||||
for every player.
|
||||
- **Names are computed, not stored:** `hash(entryID, seed)` → word pool. Zero storage.
|
||||
- Must be computable **without generating terrain** — it is upstream of the field, not downstream.
|
||||
|
||||
### 2. Danger rating — ✅ ACCEPTED. Drives **mobs, environmental hazards, and loot**.
|
||||
Refinements proposed:
|
||||
- **Danger is a RANGE per strate archetype, rolled per world** ⇒ one dreamcore asset yields a gentle
|
||||
dreamcore *and* a terrifying one. Multiplies variety with no extra authoring, and serves "two seeds
|
||||
differ in everything."
|
||||
- A strate asset therefore specifies its **theme/identity**, not its inhabitants; mob/hazard/loot pools
|
||||
are selected by **danger × theme tags**. Strates become reusable across the whole curve.
|
||||
- **Ore quality rides the danger tier** ⇒ F8's supply chain and the difficulty curve are one axis.
|
||||
- ⚠️ **Sort with jitter, not strictly.** Perfectly monotonic escalation reads flat; an occasional
|
||||
easier strate after a hard one gives relief and pacing.
|
||||
|
||||
### 3. The mix rule — ✅ ACCEPTED, sharpened by Jahni:
|
||||
**dreamcore should be QUITE RARE, so players are puzzled when they find it "because it doesn't have
|
||||
its place there."**
|
||||
⇒ The effect is *not-belonging*, which is stronger than rarity alone:
|
||||
- **Anomalous strates must NOT be blended in.** Normal neighbours get a coherent transition; an
|
||||
anomaly gets a **hard cut** — the wrongness lives in the seam. The adjacency system needs a flag for
|
||||
"this strate deliberately does not reconcile with its neighbours."
|
||||
- Rare enough that a player may go a whole season without seeing one ⇒ in a single shared world, an
|
||||
anomaly becomes **community news** ("there's a dreamcore strate at −1400 this season"). Rarity plus
|
||||
one shared seed turns it into an event.
|
||||
|
||||
### 4. Build slots — ⚠️ "not bad but needs refining". Refinement:
|
||||
- **Slots do not restrict building.** Players build anywhere valid. A slot is the **qualification for
|
||||
auto-propagation**: build in a slot and your build is eligible to spread to everyone; build freely
|
||||
and it is still yours, still visitable, still shareable by invite — just not auto-distributed.
|
||||
Resolves freedom vs safe validation without taking anything away.
|
||||
- **Slots are DERIVED from the manifest, not separately authored** — a chasm entry implies a crossing,
|
||||
a passage mouth implies a marker/shrine, a ledge implies a camp. No new authoring burden.
|
||||
- **A slot = position + shape constraint** (span, clearance, orientation) so blueprint fit is a
|
||||
mechanical check, which is what makes propagation safe.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — danger: Z-MULTIPLIER, not a sort (Jahni's model — adopted, it beats mine)
|
||||
|
||||
**Decided:** no sorting pass. **Danger = a function of depth (Z) × the strate's own multiplier**, with
|
||||
a **rare chance of a less-difficult strate appearing deep**.
|
||||
|
||||
**Why it's better than my sort:**
|
||||
- **Local, not global.** Danger is computed per strate from its Z — no whole-world ordering pass, and a
|
||||
strate's danger is knowable without knowing the rest of the world's strate list.
|
||||
- **Fully decouples identity from placement.** Any strate can appear at any depth; depth supplies the
|
||||
danger. That serves "any world, any kind, anywhere" better than sorting ever could — sorting
|
||||
implicitly binds a strate's identity to a position in the curve.
|
||||
- **The rare exception is a designed feature, not the fudge-factor jitter I proposed.**
|
||||
- ⭐ **It makes danger ANOMALIES possible in both directions**, which sorting structurally cannot:
|
||||
- **Respite strate** — unexpectedly calm, deep. Don't leave it as "lower numbers": make it a
|
||||
*designed type*. Quiet, visibly calmer, fewer mobs — a sanctuary. Natural home for a safe camp,
|
||||
a merchant, a landmark, a breather in the descent.
|
||||
- **Danger spike near the surface** — the "something is very wrong here" beat. Players find it early,
|
||||
die, and come back for it later. Pairs perfectly with the anomaly/dreamcore concept (out of place
|
||||
in *difficulty*, not only in *look*), and in one shared world it becomes season-wide news.
|
||||
|
||||
**Caveats to build in:**
|
||||
- ⚠️ **Clamp the multiplier range so the depth term dominates on average**, or the curve stops being
|
||||
reliable and progression breaks. Rare exceptions are a feature; a noisy curve is a bug.
|
||||
- ⚠️ **The exception must be LEGIBLE.** Unsignalled difficulty variance reads as bad tuning, not
|
||||
design. Each anomaly needs a tell.
|
||||
- ⚠️ **Danger must be readable at a strate's ENTRANCE**, before the player commits. A surprise easy
|
||||
strate is a gift; a surprise deadly one without warning is just an unfair death. Give the entrance a
|
||||
broadcast — visual/audio/NPC warning/UI readout fed from the manifest. Warned-and-ignored is
|
||||
memorable; unwarned is unfair.
|
||||
- Danger becomes a **manifest property** of each strate, so quests, UI and loot tables all read it from
|
||||
one place.
|
||||
- The **mix rule (grounded vs anomalous) is independent of this** and still stands.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — WHAT THE CODE ACTUALLY SAYS (read pass, no changes made)
|
||||
|
||||
### ⭐ The composer already exists in embryo: `UVoxelStrateManager::Initialize`
|
||||
`Private/VoxelStrateManager.cpp:29`, roughly 100 lines. It already does the job's skeleton:
|
||||
1. loads `Settings->StratePool` (soft ptrs) and **Fisher-Yates shuffles it** with
|
||||
`FRandomStream(WorldSeed)`;
|
||||
2. walks `TotalStrates` slots, taking `Settings->FixedStrates[i]` where pinned, else cycling the
|
||||
shuffled pool (`ShuffledPool[PoolCursor % Num]`);
|
||||
3. computes each slot's Z range from `Definition->StrateHeightInChunks`, leaving
|
||||
`InterStrateGapChunks` of bedrock between;
|
||||
4. calls `GeneratePassages` — deterministic passages between consecutive strates.
|
||||
|
||||
**This runs BEFORE any terrain and its result (`StrateLayout`) is what the density field is derived
|
||||
from.** That is exactly the "manifest is the plan, not an export" architecture — it already exists.
|
||||
The composer is an *expansion of this function*, not a new system.
|
||||
|
||||
### ⭐ The manifest can cost ZERO storage — it needs to be ENUMERABLE, not stored
|
||||
`FStrateLandmark` placement (`VoxelContentManager.cpp:1263 UpdateLandmarks`) is **hash-lattice**:
|
||||
cell = `SpacingChunks` chunks, position = lattice point + hash jitter
|
||||
(`VoxelHash::Mix(H ^ ...)`), plus a `PassageMouth` anchor mode that enumerates the finite passage
|
||||
list. The file's own comment: *"cost scales with the NUMBER of landmarks in range, not the area."*
|
||||
⇒ "what notable things are in this region?" is already a **pure deterministic function**, answerable
|
||||
without generating terrain and without streaming. So the manifest is an **index computed on demand**,
|
||||
not a baked table. That fully answers Jahni's "it must not be expensive."
|
||||
|
||||
### ✅ Already exists — do NOT redesign these
|
||||
- **`EVoxelStrateTransition::Hard`** (per strate, on its lower boundary) **is** the "anomaly must not
|
||||
blend" mechanism. Already authored per strate. Gradient / Hard / Interleaved.
|
||||
- **Height already varies 1–256 chunks** (~8 m to ~2 km). "Any size" is supported today.
|
||||
- **`GameplayTags` on `UVoxelStrateDefinition`** — the tag vocabulary for adjacency rules and
|
||||
mob/hazard/loot selection is already there, and the module already depends on GameplayTags.
|
||||
- **`UVoxelTerrainOpDefinition`** — ops ARE already data assets (12 types: Terrace, LayerLines,
|
||||
Ribbing, Cliff, Scallop, Overhang, Arch, Column, Pit, Chimney, Dome, Pinch), referenced from the
|
||||
strate's `TerrainOperations`, merged by `BuildParamsFromDefinition`.
|
||||
- **Landmarks** already carry `AnchorMode`, `SpacingChunks`, `JitterFraction`, `SpawnProbability`,
|
||||
`ExclusionRadiusChunks`, `Priority` — F7's placement machinery, built. **This is the seed of build
|
||||
slots**: slots are landmarks of a "build site" kind.
|
||||
|
||||
### ❌ Genuinely missing for the composer
|
||||
- **No rarity.** The pool is a flat `TArray` shuffled uniformly. Dreamcore-should-be-rare needs a
|
||||
weighted entry (`{Def, Weight, Tags, allowed depth band…}`), not a bare array.
|
||||
- **Pool CYCLES** (`PoolCursor % Num`) when `TotalStrates` > pool size ⇒ repeats in a fixed order.
|
||||
"Two seeds differ in everything" needs a weighted draw instead.
|
||||
- **No danger concept anywhere** in the strate definition or settings. Needs the Z-multiplier model.
|
||||
- **No adjacency rules** — nothing prevents two alike in a row, nothing expresses "sets up" pairs.
|
||||
- ⭐ **The op COMPOSITION is hardcoded C++**: `BuildTunnelNetworkStack` / `BuildMazeStack` /
|
||||
`BuildSurfaceStack` … one builder per archetype, in `VoxelDensityOpStack.cpp` (252 KB). The *ops*
|
||||
are composable; the *composition* is not data. **This is exactly the Phase 3 gap — the machine was
|
||||
built and never fed.** Confirmed against the code, not inferred.
|
||||
|
||||
### ⚠️ Constraints discovered
|
||||
- **Layout = f(seed, pool CONTENTS, pool ORDER).** `FRandomStream` + Fisher-Yates over
|
||||
`Settings->StratePool` means **adding or reordering one strate in the pool changes every world**.
|
||||
⇒ new strate types can only land **at a wipe**. Consistent with the season model, but it must be
|
||||
stated: mid-season content additions cannot touch the pool.
|
||||
- ⚠️ **`FStrateGenerationParams` is a giant flat param bag** with an X-macro (`VF_STRATE_PARAM_FIELDS`)
|
||||
driving its `Lerp` blend. Ambition level **(c)** wants **authored ranges per parameter**, and there
|
||||
is no natural home for a per-field range in a flat struct of that size. **This is the main
|
||||
engineering obstacle to (c)** and the next thing worth designing.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — the pool entry, and DERIVING distribution instead of authoring it
|
||||
|
||||
Jahni's objection to the pool-entry proposal (weight / max / min per entry): that is still
|
||||
**hand-authoring the world's composition**. He wants the game to produce its own worlds.
|
||||
Real distinction: he authors the **vocabulary**; he does not want to author the **distribution**.
|
||||
|
||||
### ⭐ The unifying move: MEASURE each assembled strate, don't declare its numbers
|
||||
Reuse the coarse validation pass already required for garbage detection (low-res sample of the strate,
|
||||
once at world creation: air fraction, walkable surface, feature size, connectivity). It produces
|
||||
*numbers about the place* — use them for everything, not just yes/no. **One pass, three uses.**
|
||||
|
||||
| Was going to be authored | Derived instead |
|
||||
|---|---|
|
||||
| **Weight (rarity)** | **Outlier-ness**: distance from the pool's centroid in measurement space. Dreamcore is rare *because it is unlike everything else*. Self-correcting — author five dreamcore-ish strates and they stop being outliers, which is the right answer. |
|
||||
| **Danger multiplier** | **Measured**: verticality (fall distance), openness (sightlines / room to retreat), traversal difficulty (climb/swim share), darkness. Discovered from what the strate generates. |
|
||||
| **Max per world** | **Weight decay on draw** — an entry's weight drops sharply each time it's picked. Rare things don't repeat; common things recur without dominating. No per-entry number. |
|
||||
| **Min per world (the mix rule)** | **One GLOBAL dial**: "a world's total strangeness may not exceed X." One knob for the whole game instead of one per strate. |
|
||||
| Some descriptive **tags** | Measurable too — flooded = water volume, vertical = aspect ratio, open = mean free space. |
|
||||
|
||||
### Honest limits (stated to Jahni)
|
||||
- **Intent can never be derived** — which strate is the boss's, which is fixed at the top. Authored,
|
||||
always, and rightly.
|
||||
- **A measurement can be wrong about how a place FEELS** (measures ordinary, plays unsettling).
|
||||
⇒ **derived by default, with an optional per-entry override that is normally empty.** The escape
|
||||
hatch exists without being an obligation on every strate.
|
||||
|
||||
⇒ Jahni's remaining authoring job: **make strates, and turn two or three global dials.**
|
||||
|
||||
**Through-line worth noting:** this is the same answer as the AI-judge discussion — *measure, don't
|
||||
declare* — and it reuses the same pass. The design is cohering on one mechanism.
|
||||
|
||||
**Still on the table from the earlier proposal:** adjacency rules as a small tag-rule list in settings
|
||||
(no two alike adjacent / `Anomaly` needs a `Grounded` neighbour above / max run length), the draw must
|
||||
never fail (fallback entry), and making the draw order-independent — `hash(seed, slotIndex, attempt)`
|
||||
over a pool sorted by a stable key, so reordering the asset in the editor stops changing every world.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — ⛔ CORRECTION: Jahni does NOT want to author strates either
|
||||
|
||||
The line above — *"Jahni's remaining authoring job: make strates, and turn two or three global
|
||||
dials"* — is **WRONG**. His words: *"I'm not pretty happy to make strates forever, that's actually
|
||||
the opposite. If I could never make any new strate myself and have it do it itself would be genius."*
|
||||
|
||||
**⇒ The system must INVENT strates, not arrange authored ones.** I had the composer one level too
|
||||
shallow for this entire conversation. Re-derive from here.
|
||||
|
||||
### What that means architecturally
|
||||
- **A strate stops being an asset and becomes generated data.** `UVoxelStrateDefinition` survives as a
|
||||
struct (the generator needs its fields) but nobody fills it in the editor — the **composer** fills
|
||||
it: draws operators, rolls parameters, assigns materials/content, and hands the generator a strate
|
||||
that has never existed before and won't exist after the wipe.
|
||||
- The **strate pool / weights / min / max** design above is therefore obsolete as stated. Rarity,
|
||||
danger and mix must be properties of *invented* strates, measured after assembly (the measurement
|
||||
idea survives the correction — it is *more* necessary now, not less).
|
||||
|
||||
### ⭐ The grammar for inventing a stack ALREADY EXISTS in code
|
||||
`EVoxelOpRole` (in `Public/VoxelDensityOp.h`): **`FieldSource`** (what the field IS) ·
|
||||
**`Combiner`** (how fields merge) · **`DetailModifier`** · **`StructuralPost`** (spine → seal →
|
||||
passage, appended automatically, never author-omittable). A valid stack already has a defined shape:
|
||||
one source, some modifiers, structural post last. "Invent a strate" = draw a source, draw modifiers,
|
||||
roll parameters, in an order the roles already constrain. **The constraint system is sitting there
|
||||
unused.**
|
||||
|
||||
### Where the hard part moved
|
||||
- **Coherence was free when a human authored the strate. It is not free now.** A maze op + an overhang
|
||||
op + a flooded op at incompatible scales = mush. This is the garbage problem at full strength, and
|
||||
it is why the **AI-judge idea makes much more sense in this light** — it was never about judging
|
||||
hand-made content, it is about judging *invented* content, in a space too large to eyeball.
|
||||
- **Dressing must be coherent too** — palette, mood, decorations, creatures, audio. Drawn independently
|
||||
you get crystal formations in a lava flow. ⇒ the composer draws a **theme** first, then pulls
|
||||
operators, materials, decorations, creatures and audio carrying that theme's tags.
|
||||
- ⚠️ **The RANGE problem is no longer "at some point" — it is the centre of the design.** The ranges
|
||||
*are* the space the system invents inside.
|
||||
|
||||
### Open question put to Jahni
|
||||
**Where is the floor of authoring?** Proposed: the **raw content** — operators, meshes, materials,
|
||||
sounds, creatures — plus their tags. Those are the atoms; everything above (strates, worlds, layout,
|
||||
danger, rarity) is composed and measured. Every operator added then *multiplies* with every other one
|
||||
instead of adding one more place. **Or does he want the system to invent operators too?**
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — floor CONFIRMED; op invention parked
|
||||
|
||||
**Floor of authoring = raw content + tags.** Operators, meshes, materials, sounds, creatures, music —
|
||||
tagged. Jahni accepts this ("I'd need to be thorough and tag every enemy, music and whatnot").
|
||||
Nothing above that (strates, worlds, layout, danger, rarity) is authored.
|
||||
|
||||
### Inventing operators — parked, but not impossible
|
||||
- ❌ **New KINDS of operator cannot be invented** ("warp the domain by noise", "carve capsules along a
|
||||
spline"). Those are ideas expressed as code ⇒ program synthesis. Bad bet, not where the value is.
|
||||
- ✅ **Discovering good COMBINATIONS and promoting them into named reusable units** is real and
|
||||
buildable: a sub-stack that measures well becomes one building block. From the composer's view that
|
||||
*is* a new operator. **Compounds across seasons** — season 1's discoveries are season 2's vocabulary.
|
||||
- ⚠️ **Do not chase it early.** ~20 ops with rolled parameters already spans a space vastly larger than
|
||||
a hundred seasons could explore. **The scarce resource is judgment, not vocabulary** — an hour on
|
||||
measurement/validation/the model beats an hour widening a space we use a rounding error of.
|
||||
|
||||
### Why the tagging burden is smaller than it sounds
|
||||
- **Per-ASSET, not per-place.** Tag a bat once ⇒ every world, every season, forever. Cost scales with
|
||||
content, not with number of places. *This is the actual payoff of inventing strates rather than
|
||||
authoring them.*
|
||||
- **GameplayTags are hierarchical and already a plugin dependency** — `Theme.Volcanic` reaches every
|
||||
volcanic context with no enumeration.
|
||||
- **Some coherence needs no tags:** palette can be sampled from a material's dominant colour and
|
||||
clustered. A decoration whose colours sit in the strate's family fits, unstated.
|
||||
- **Lazy:** untagged content is simply never drawn. Ship with 20 enemies and 3 tracks; add more
|
||||
whenever. Nothing breaks, the pool just gets richer.
|
||||
|
||||
**NEXT:** the range problem (now central, not a footnote).
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — THE RANGE PROBLEM (designed; verified against the code)
|
||||
|
||||
### Verified facts (not remembered — checked)
|
||||
- `FStrateGenerationParams` has **73 scalar fields** (+1 bool). **Not hundreds** — tractable.
|
||||
- ✅ **The X-macro is IN SYNC.** `VF_STRATE_PARAM_FIELDS` covers 75 entries; the only struct scalar
|
||||
missing from it is `Alpha`, which *is* the blend weight and is correctly excluded. CODEMAP's warned
|
||||
trap (add a field, forget the macro, blends silently reset it to default) **has not bitten**.
|
||||
⇒ `FStrateGenerationParams::Lerp` already blends the whole parameter set, and is already load-bearing
|
||||
at strate boundaries. **Add a test asserting macro ≡ struct so this stays true.**
|
||||
- `VoxelStrateTypes.h`: **135 `ClampMin`, 52 `ClampMax`** across 216 UPROPERTYs. Most fields have no
|
||||
upper bound. Paired min/max fields exist (`MinRoomRadius`/`MaxRoomRadius`, `TunnelMin/MaxRadius`,
|
||||
`RoomFloorCutMin/Max`) and some fields carry relational `EditCondition`s.
|
||||
|
||||
### Why rolling parameters fails (the reason to state plainly)
|
||||
The coherent region of a 73-dimensional space is a vanishingly thin sheet; uniform sampling in a box
|
||||
never lands on it. The problem is not wrong ranges — it is that **independent rolling destroys the
|
||||
CORRELATIONS** that make a parameter set coherent (room spacing ↔ room radius ↔ tunnel length ↔ strate
|
||||
height). This is very likely what Jahni was sensing when he reached for an AI judge.
|
||||
|
||||
### ⭐ The design: don't roll parameters — BLEND KNOWN-GOOD ONES
|
||||
1. **Corpus** = known-good parameter vectors. Seeded by Jahni's existing hand-authored strate assets.
|
||||
2. **Roll** = pick 2–3 parents (weighted), **blend with random weights**, then jitter.
|
||||
3. **Reuse `FStrateGenerationParams::Lerp`** — it already does exactly this, over exactly this field
|
||||
set, and the world working already tests it. Build nothing.
|
||||
4. **Constraint satisfaction is FREE:** a convex combination preserves every relation that holds in
|
||||
both parents (`Min ≤ Max` stays true). Correlations survive because they were never broken.
|
||||
5. ⭐ **Ranges come from the CORPUS SPREAD** — per field, how much it varies across existing strates —
|
||||
**not from authored numbers and not from the clamps.** Clamps are "don't type nonsense" limits, not
|
||||
"this makes a good world" limits. *Measure, don't declare*, again.
|
||||
6. **Clamps = hard safety net only.** Never the roll range.
|
||||
|
||||
### Escaping the convex hull
|
||||
Blending alone only reaches *between* existing points. Escapes: jitter slightly past the corpus;
|
||||
deliberate **extrapolation** past a parent away from the centroid (riskier ⇒ validate harder); and
|
||||
⭐ **PROMOTION** — every invented strate that measures well and survives players joins the corpus.
|
||||
Season 1 blends ~6 strates; season 5 blends 200 discovered ones. **The system's imagination grows from
|
||||
its own history, and the game gets stranger as it ages.** (Third appearance of this mechanism today:
|
||||
discovered ops, discovered strates, discovered parameter regions. It is the spine of the design.)
|
||||
|
||||
### ⚠️ Honest caveats
|
||||
- **UPROPERTY metadata is editor-only** — `ClampMin`/`ClampMax` do not exist in a packaged build.
|
||||
⇒ bake them at cook time via a small editor commandlet walking the struct by reflection. Small,
|
||||
real, one-time work.
|
||||
- **Clamp coverage is partial** (52 of ~73 have no max). The net has holes; don't lean on it.
|
||||
- **A few fields are not tunables** — `StrateTopWorldZ` / `StrateBottomWorldZ` are runtime Z bounds.
|
||||
Needs an explicit **exclusion list** for rolling.
|
||||
- **Bools can't be blended** — roll feature toggles by probability, or inherit from the dominant parent.
|
||||
- ⚠️ **The corpus is small today** (~6 strates), so blending alone will not feel like "countless
|
||||
worlds" in season 1. ⇒ **early variety must come from STRUCTURE, not parameters** — *which* operators
|
||||
are in the stack at all. 20 ops choose 5 is already thousands of distinct stacks.
|
||||
**Rule: vary structure aggressively, vary parameters conservatively — shift the ratio as the corpus
|
||||
grows.**
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-17 — theme coherence narrowed; findability first step
|
||||
|
||||
- **Thematic mismatch is mostly FINE** — Jahni: a lava flow *could* have crystal formations, it was a
|
||||
bad example. ⇒ my "coherent dressing" worry was overstated. **The real garbage is GEOMETRIC**:
|
||||
operators at incompatible *scales* producing mush. Smaller and more mechanical than feared.
|
||||
- ⭐ **Multiple fitting tags per asset is the mechanism, not a compromise.** One tag per thing = rigid
|
||||
buckets. Several tags = a graph with overlaps, and **the overlaps are where the system finds
|
||||
combinations Jahni didn't plan that still hang together** — which is the "magical" effect he wants.
|
||||
He describes assets; themes emerge from co-occurrence rather than being assigned.
|
||||
- **Jahni's expected first big job:** create themes and tag content with multiple fitting tags.
|
||||
- **Findability, first step:** a **subtle beacon glow**, initially for debugging. Note it is *not*
|
||||
throwaway — the debug beacon **is** the real solution in programmer art. The placement logic is
|
||||
identical; only delivery changes later (light spilling from the passage, a draft, a shift in
|
||||
ambience). Build the ugly version; ship a reskin.
|
||||
Reference in new issue
Block a user