Working title 'tgame' is provisional. Top-level samples/ and docs/samples/ are gitignored; visual/art pipeline lives outside this repo.
308 lines
21 KiB
Markdown
308 lines
21 KiB
Markdown
# Expedition Engagement & The Latent Party Matrix
|
||
|
||
Continuation of 2026-05-12 brainstorm. Extends [04-expeditions.md](04-expeditions.md) and builds on [17-foldins-2026-05-12.md](17-foldins-2026-05-12.md). Loose design notes, not a spec.
|
||
|
||
## Premise
|
||
|
||
The Steam pivot ([17-foldins](17-foldins-2026-05-12.md)) reframed pacing from mobile pop-ins to in-session minutes. A 5-min mobile pickup didn't need a spine — the pop-in was the spine. A 30–90 minute Steam session does. The session needs an arc that opens, escalates, resolves.
|
||
|
||
**The expedition is the session spine.** A run is the contained arc: launch → orchestrate → recall → wind down. Everything else — crafting, hire pool, patron orders — happens *around* and *during* the run, but the expedition is what gives the session shape.
|
||
|
||
The concern that prompted this work: "is there enough to actually *do* in this game?" Diagnosis — "always something shiny" was sized for the entire 5-min interaction. For a Steam session, the shiny-pulse is texture, not structure. The expedition has to do the structural work.
|
||
|
||
## Sealed-run principle
|
||
|
||
**Once an expedition launches, the player cannot reach into it.** No mid-flight gear swap, no resupply courier, no mid-run provisioning, no remote orders. The party is in the field on its own; the player is the home base.
|
||
|
||
Engagement lives in the book-ends and the event stream:
|
||
|
||
1. **The Brief** — pre-flight planning, party assembly, provisioning, routing
|
||
2. **The Stream** — in-flight event responses (decisions only, no material interference)
|
||
3. **The Report** — post-flight debrief, haul triage, narrative compile
|
||
|
||
This rule is intentional. In-flight intervention destroys the morning-after test (cultivates compulsive check-ins) and trivializes the planning surface (any pre-flight mistake is recoverable mid-run). Sealing the run forces commitment, makes planning matter, and respects the player's time.
|
||
|
||
## Three engagement surfaces
|
||
|
||
### 1. The Brief
|
||
|
||
Pre-flight is a real puzzle, not a checkbox. Working surfaces:
|
||
|
||
- **Routing within the zone.** A destination isn't a single picker. Each zone has *paths* — Ravenwood has river road (slow, safe), ridge cut (fast, exposed), old culvert (capability-gated: needs torch + Lettered). Different paths bias different material distributions, event tables, and risk profiles.
|
||
- **Declared goal.** "We're after moonpetal" / "open hunt" / "patron job" / "discovery run." Biases event resolution and drop weights toward the goal. The party plays *toward* what you told them.
|
||
- **Risk dial.** Cautious / Standard / Aggressive. Modulates how the party auto-resolves events the player ignores. Aggressive Dora pushes into the cave-in; Cautious Dora retreats. Distinct from trait disposition — this is *party temperament for this run*.
|
||
- **Provisioning as commitment.** Carry capacity is shared between outbound provisions (rations, kits, consumables) and inbound haul. Bring 2 extra rations = stay longer, but 2 fewer slots for return loot. Real trade-off.
|
||
- **Party-comp synergies that read.** Tooltip-surfaces both known synergies (from Library entries earned through play) and budget shape. The build *takes shape* visibly as the player slots members.
|
||
|
||
### 2. The Stream
|
||
|
||
In-flight events are the only interactivity, so they have to work harder than flavor pings. Event class taxonomy:
|
||
|
||
- **Flavor pings (~70%)** — zero-choice texture. AI-batchable. Carry tone and party-chemistry signal.
|
||
- **Light decisions (~20%)** — binary, low stakes, fast.
|
||
- **Capability-puzzle events (~5%)** — gated on party composition. "Cave-in. Strong clears it; Lettered reads the inscription; Lucky finds the cache. Your party has Strong only — push through or detour?" Party comp retroactively matters.
|
||
- **Chain events (~3%)** — multi-stage. Event 3 plants a clue; event 7 calls back; event 11 closes. A single thread stretches across the run.
|
||
- **NPC encounters (~2%)** — recurring named strangers across runs. Build relationships that pay off in future expeditions or patron emergence.
|
||
|
||
Critical: events shape the *report*, not just the loot. Choices ripple into the post-run library entry, into trait shifts, into character titles earned. Decisions echo.
|
||
|
||
### 3. The Report
|
||
|
||
Debrief is a verb, not a popup:
|
||
|
||
- **Triage sort.** Haul drops as a pile to sort — stockpile / sell-queue / patron-order / gift-to-engineer. Some materials are time-sensitive (fresh moonpetal sells higher, ages in-session).
|
||
- **Story compile.** Run produced N notable moments. Player picks which becomes the Library entry — editorial agency over the narrative record.
|
||
- **Trait evolution moment.** "Dora was tested in the cave-in. Mark her: Tested, Scarred, or let it pass?" Small post-run decision that shapes roster development.
|
||
- **Patron payoff.** If the run filled an order, the handoff is its own beat — Aldric pleased/displeased, rep shifts, named NPC reacts.
|
||
|
||
## Optional rhythm: legs
|
||
|
||
Single in-flight interactivity that respects the sealed-run principle: **between-leg check-ins.**
|
||
|
||
An expedition has discrete phases — Approach → Subzone A → (optionally) Subzone B → Return. Inside a leg: pure event stream, auto-resolve baseline. Between legs: party radios in with a real decision-gate. *"We've cleared the foothills, hauling 6 ore. Push into the deep pit (Tier 4, better drops) or beat retreat?"*
|
||
|
||
The player is answering a check-in, not reaching into the run. The party's already there; the player is choosing the next leg's character. FTL-map shape inside one expedition. Adds rhythmic decision points without breaking the seal.
|
||
|
||
Trade-off: doubles authoring surface (per-leg event tables). Working position: include legs but keep most expeditions to 2 legs (Approach + Single Subzone + Return); 3-leg expeditions are higher-tier opt-ins.
|
||
|
||
## Token-budget party model
|
||
|
||
A party isn't *just* who's there — it's the shape of the budgets those people contribute to. Small World–inspired: each combination plays differently because the token flow is different.
|
||
|
||
Working set of budgets:
|
||
|
||
| Budget | What it spends on | Contributors |
|
||
|---|---|---|
|
||
| **Reach** | Legs unlocked, depth into zone | Scouts, Halflings, light-encumbrance, certain consumables |
|
||
| **Stamina** | Each event drains; party retreats when empty | Steady, Brave, healers, ration prep, alchemy supplies |
|
||
| **Carry** | Haul capacity | Strong, pack animals, saddlebags, Bag of Holding |
|
||
| **Insight** | Unlocks capability-puzzle events (Lettered, perceptive, lore) | Scholars, Lettered trait, certain heritages |
|
||
| **Standing** | NPC encounters, trades, negotiations | Merchants, Charming, faction-tagged characters |
|
||
|
||
A party's *build* is its budget shape. Same headcount, different shape, different game. The number on the screen matters less than the readability of the shape — players should see *what kind of party* this is at a glance.
|
||
|
||
## Builds as a real noun
|
||
|
||
Budget shapes have natural archetypes. Players name them in their heads:
|
||
|
||
- **The Foothold** — Steady gatherer + Brave defender. Tall Stamina, short Reach. Predictable run.
|
||
- **The Wedge** — Halfling scout + Lettered scholar. Tall Reach + Insight, almost no Carry. Library-hunter.
|
||
- **The Plunder Run** — Greedy gatherer + Drunk beastmaster + soldier. Tall Carry, weird Stamina, rich event texture.
|
||
- **The Quiet Path** — Stealth-tagged pair. Skips encounter events. Low ceiling, high consistency.
|
||
- **The Wraith Detail** — Necromancy-aligned trio for Ravenwood. Death-resistant in that biome; would die in a meadow.
|
||
- **The Mentor Run** — Master + Apprentice. Slow, but apprentice gains trait shifts faster. Investment, not haul.
|
||
|
||
These aren't designer-authored archetypes shipped with the game. They're *emergent shapes* players discover and name. The system has to *produce* them, not enumerate them.
|
||
|
||
The hire pool constrains exploration (you don't pick the ideal party, you pick from who applied) — which forces players into combos they wouldn't have chosen voluntarily. That's where surprise lives.
|
||
|
||
## The latent party matrix (MBTI-adjacent)
|
||
|
||
This is the structural core. A four-axis latent model that determines a party's chemistry — never exposed to the player, always shaping outcomes.
|
||
|
||
### Why this works
|
||
|
||
A 4-axis matrix is the smallest authoring surface that produces emergent character chemistry at scale:
|
||
|
||
- **16 types from 4 binary axes** — vastly more compressible than authoring pair-by-pair (6 traits × 6 = 36 pairs before heritage/class/gear)
|
||
- **Each axis is independently meaningful** — author behavior per-axis, compositions inherit naturally
|
||
- **AI batches cleanly along axes** — "write events for high-Curious, high-Wandering, conflicted-Engagement parties in Burned Hills" is a tractable prompt; "write events for Brom + Miles" is not
|
||
- **Player folk-knowledge tracks coherence, not labels** — humans notice patterns without naming them. "Brom and Dora always find weird stuff" is exactly what happens when output filters through a consistent latent space
|
||
|
||
The fact that it's **never surfaced** is what makes it work. The moment players see "Brom: ENFP," the magic is gone — optimization replaces mythology. Hidden, it stays folklore.
|
||
|
||
### MBTI-adjacent, not literal MBTI
|
||
|
||
The four-axis discipline is what we want. The I/E/S/N/T/F/J/P labels carry corporate-workshop baggage and validity debates we don't need to inherit. Internal labels for tgame, mapped roughly to the MBTI shape:
|
||
|
||
| Axis | Pole A | Pole B | MBTI rough-equivalent | What it modulates |
|
||
|---|---|---|---|---|
|
||
| **Engagement** | Bold (+) ←→ Withdrawn (−) | E / I | How often events fire vs. get sidestepped |
|
||
| **Lens** | Concrete (+) ←→ Curious (−) | S / N | Drop bias — mundane resources vs. unusual/lore/cursed/whimsical |
|
||
| **Disposition** | Pragmatic (+) ←→ Sentimental (−) | T / F | Auto-resolve defaults — takes the loot vs. rescues the captive |
|
||
| **Tether** | Disciplined (+) ←→ Wandering (−) | J / P | Route adherence vs. tangent-following |
|
||
|
||
A party type is the 4-tuple of axis tilts. 16 archetypes if axes are treated as binary; in practice the axes are continuous and the type is the *shape of the vector*.
|
||
|
||
### The math
|
||
|
||
Each character has a latent 4-vector, computed from heritage + traits + class. Each axis ranges roughly [−1, +1].
|
||
|
||
```
|
||
# Character vector composition
|
||
character.vector = clamp(
|
||
heritage.bias_vector
|
||
+ sum(trait.modifier_vector for trait in character.traits)
|
||
+ class.bias_vector,
|
||
min=-1, max=+1
|
||
)
|
||
```
|
||
|
||
**Example: Brom — Human, Brave, Soldier**
|
||
|
||
| Component | Engagement | Lens | Disposition | Tether |
|
||
|---|---|---|---|---|
|
||
| Human heritage | 0 | 0 | 0 | 0 |
|
||
| Brave trait | +0.5 | 0 | +0.2 | 0 |
|
||
| Soldier class | +0.3 | 0 | 0 | +0.2 |
|
||
| **Brom** | **+0.8** | **0** | **+0.2** | **+0.2** |
|
||
|
||
**Example: Dora — Halfling, Lucky + Cautious, Gatherer**
|
||
|
||
| Component | Engagement | Lens | Disposition | Tether |
|
||
|---|---|---|---|---|
|
||
| Halfling heritage | −0.3 | +0.2 | 0 | −0.4 |
|
||
| Lucky trait | 0 | +0.4 | 0 | +0.1 |
|
||
| Cautious trait | −0.4 | 0 | 0 | +0.2 |
|
||
| Gatherer class | 0 | +0.1 | −0.1 | 0 |
|
||
| **Dora** | **−0.7** | **+0.7** | **−0.1** | **−0.1** |
|
||
|
||
### Party aggregation
|
||
|
||
Per-axis combination:
|
||
|
||
```
|
||
for each axis:
|
||
member_values = [m.vector[axis] for m in party]
|
||
party.vector[axis] = mean(member_values)
|
||
|
||
if all(v >= 0 for v in member_values) or all(v <= 0 for v in member_values):
|
||
party.conflicted[axis] = False
|
||
else:
|
||
party.conflicted[axis] = True
|
||
```
|
||
|
||
**Important:** simple averaging produces muddy mid-types and erases chemistry. The conflicted-axis flag preserves the *interesting case* — when members pull opposite directions, that's not a wash, that's a distinct latent state with its own event class.
|
||
|
||
**Example: Brom + Dora party**
|
||
|
||
| Axis | Brom | Dora | Mean | Conflicted? | Reading |
|
||
|---|---|---|---|---|---|
|
||
| Engagement | +0.8 | −0.7 | +0.05 | **Yes** | They push-pull on every encounter |
|
||
| Lens | 0 | +0.7 | +0.35 | No | Tilts Curious |
|
||
| Disposition | +0.2 | −0.1 | +0.05 | No | Mildly mixed, neither pole |
|
||
| Tether | +0.2 | −0.1 | +0.05 | No | Roughly balanced |
|
||
|
||
Reading: **mildly Curious, conflicted Engagement, neutral on the rest.** Their runs will be characterized by argument-events on engagement (push vs. retreat) and a bias toward unusual finds. Always weird, sometimes glorious, sometimes a mess. Player notices: *"Brom and Dora always find strange stuff."*
|
||
|
||
**Example: Miles + Reynold (both Drunk + Gatherer + Brave)** — heavily Wandering, neutral Engagement (both Brave + both wandering = high Tether-negative + high Engagement-positive), mildly Curious. Reading: **Bold + Wandering + Curious.** They engage everything, follow every tangent, find weird things — but they also *come back drunk with immaculate pelts* because both are Gatherers with high quality bias on hide. Different flavor entirely from Brom+Dora.
|
||
|
||
### Event weighting
|
||
|
||
Each authored event has axis affinities — required (hard gate), preferred (soft weight), and conflict-affinity (events that only fire when an axis is conflicted).
|
||
|
||
```
|
||
def event_weight(event, party):
|
||
weight = 1.0
|
||
for axis in AXES:
|
||
# Hard gates
|
||
if event.required[axis] is not None:
|
||
if sign(party.vector[axis]) != sign(event.required[axis]):
|
||
return 0
|
||
if abs(party.vector[axis]) < event.required_magnitude[axis]:
|
||
return 0
|
||
|
||
# Soft preferences
|
||
if event.preferred[axis] is not None:
|
||
if sign(party.vector[axis]) == sign(event.preferred[axis]):
|
||
weight *= 1 + abs(party.vector[axis]) * AFFINITY_STRENGTH
|
||
|
||
# Conflict bonus
|
||
if event.prefers_conflicted[axis] and party.conflicted[axis]:
|
||
weight *= CONFLICTED_BONUS
|
||
|
||
return weight
|
||
```
|
||
|
||
Same shape applies to **material drop tables.** Drops are tagged with axis affinities; the sampler weights drops by party shape. A high-Curious + Wandering party in Burned Hills doesn't get the same haul as a high-Concrete + Disciplined party in the same biome. **Same zone, different game.**
|
||
|
||
### Signal-to-noise
|
||
|
||
For folk-knowledge to register, the latent type has to *visibly* skew outcomes. Working targets:
|
||
|
||
- Tilted axes (|value| > 0.5) should produce **>75/25** bias in event sampling on that axis's affinities
|
||
- Conflicted axes should fire conflict-specific events at **>30%** rate when both poles are represented
|
||
- Signature finds (rare items, named events, library-worthy moments) should be **latent-gated** so they happen *to* characters who have the right chemistry, not randomly
|
||
|
||
Players should notice a party's chemistry within **3–5 runs** of the same pairing. If the curve is longer than that, the system isn't doing its job.
|
||
|
||
### AI authoring loop
|
||
|
||
This is what makes the matrix economically viable. Authoring is per-axis-shape, not per-character-pair.
|
||
|
||
```
|
||
prompt: "Generate 30 expedition events for the Burned Hills biome,
|
||
targeting a party reading [high Bold, high Curious, neutral Disposition,
|
||
high Wandering, conflicted on nothing]. Tone: darker WoW × Shrek.
|
||
~70% flavor pings, ~25% light decisions, ~5% substantive moments.
|
||
Tag each with required/preferred axis affinities."
|
||
|
||
→ AI produces a tagged event pool.
|
||
→ Runtime sampler weights toward party-matching events.
|
||
```
|
||
|
||
A few hundred prompts cover 16 types × ~5 biomes × ~3 leg-stages at sufficient density. The pool tags itself. Adding events post-launch is the same pipeline, indefinitely. **The system gets richer over time without redesigning anything.**
|
||
|
||
Signature events — the rare, character-naming ones — gate to specific latent shapes. "Found the 90lb onyx" only fires for high-Curious + Wandering parties, so when it happens to *your* Brom and Dora, it feels like *their* story. Because it is.
|
||
|
||
## Material properties as expression of party choice
|
||
|
||
This is the closing loop — the part that makes the matrix more than a flavor system. **Material properties are exposed *through* the party profile.**
|
||
|
||
### The pipeline
|
||
|
||
```
|
||
Party latent vector
|
||
↓
|
||
Material drop weights (tagged by axis affinity)
|
||
↓
|
||
Material properties surface based on what comes back
|
||
↓
|
||
Recipes reflect the materials available
|
||
↓
|
||
Crafted items express the materials' character
|
||
↓
|
||
Items carry the tone of the run that produced them
|
||
```
|
||
|
||
A whimsical party (high Curious + high Wandering) brings back whimsical materials — odd provenances, unusual properties, cursed-by-storage edge cases. Those materials demand recipes that handle their character. The recipes the player actually engages with are the recipes that work with *what they have to work with*. The crafted items inherit the absurdity.
|
||
|
||
A pragmatic party (high Concrete + high Disciplined) brings back clean ore, predictable hides, standard botanicals. Their recipes are the clean ones. Their items are the reliable ones.
|
||
|
||
### Tone emerges from play
|
||
|
||
**The game is agnostic to the "best" path.** There is no canonically optimal flavor. Players gravitate naturally to combinations that resonate with them — some lean whimsy, some lean grim, some lean efficient. The game's tonal character on a given save is *produced by* the player's pairing choices.
|
||
|
||
This is structurally significant:
|
||
|
||
- **No tone authored by the designer.** The whimsy / seriousness mix on a given save is a player-driven outcome. Two players have demonstrably different games.
|
||
- **Recipes don't drive expedition choices; expedition choices drive which recipes matter.** This inverts the conventional crafting-game flow. Materials → recipes → items, not the other way around.
|
||
- **Absurd parties get absurd items, which fuel more absurdity.** A whimsy spiral is *positively reinforced* by play. So is a serious spiral. The player's gravitational well deepens with each run.
|
||
- **No "wrong" way to play.** Min-maxing optimal Concrete + Disciplined builds produces a coherent serious-craft game. Min-maxing chaotic Curious + Wandering produces a coherent whimsy game. Both are legitimate, both are deep.
|
||
|
||
This is the design pillar this whole session was building toward. The expedition system + party matrix + material properties together form a **player-expression engine** — the player's flavor of the game emerges from their roster choices, not from a tone dial the designer set.
|
||
|
||
### Property exposure mechanics
|
||
|
||
Materials have multiple layers of identity ([14-materials.md](14-materials.md) covers type + quality):
|
||
|
||
- **Provenance** — where it came from (Burned Hills moonsilver smelts hotter than Mire moonsilver). Set on drop.
|
||
- **State** — fresh / aged / cured / cursed-by-storage. Time-evolves.
|
||
- **Properties** — discovered through use. First few crafts surface property hints. Library populates.
|
||
- **Axis tags** — invisible to player; biased by the producing party's latent vector. Drives what *can* be discovered, what *can* be crafted.
|
||
|
||
A high-Curious party's haul might include moonsilver tagged with whimsy-affinity. That moonsilver, when used in a recipe, biases the output toward absurd variants — propeller-hat results, rhinestone-decorations, lumbass-bread effects. The player doesn't see the tags. They just notice: *"the things I make with this kind of party always come out weird."*
|
||
|
||
## Open threads
|
||
|
||
- **Axis selection** — Engagement / Lens / Disposition / Tether is a working set. Want to prototype with placeholder axes and verify event ideas slot in naturally before locking. The four axes are load-bearing; wrong axes produce bland or contradictory output.
|
||
- **Combination math** — current sketch is per-axis mean + conflicted flag. May need to weight by trait strength (Brave is louder on Engagement than Cautious; Drunk is loud on Tether but mild on Lens). Sim-tuneable.
|
||
- **Conflicted-axis event density** — too many conflict events makes mixed parties feel like a mess. Too few makes the conflict-as-spice mechanic vanish. Target ~30% fire rate when conditions met, tune in sim.
|
||
- **Folk-knowledge surfacing aids** — beyond just outcomes, do we audio-tell, visually-tell, narratively-tell what kind of run this is? Subtle cues (different music sting, different report tone, different narrator voice) help players read the chemistry without spelling it out.
|
||
- **Stable-pairing pull** — folk knowledge requires repeated pairings. Current roster mechanics (mix-and-match, hire pool churn) may pull against this. Bond-via-shared-runs is the natural lever; may need other nudges (paired training, paired equipment, shared dwellings) to keep ~3–5 favorite duos in heavy rotation.
|
||
- **Material property authoring** — how many distinct properties per material category? How are they procedurally generated vs. hand-authored? AI batching here is similar to event authoring; same pipeline likely applies.
|
||
- **Surfacing without exposing** — Library entries that say "Brom and Dora have an unusual rapport in the field" are surfacing the *consequence* without exposing the math. How explicit does this go? Too explicit = "MBTI score." Too implicit = invisible. Target the middle: Library notes *patterns observed*, never *underlying axes*.
|
||
|
||
## What this commits to
|
||
|
||
Nothing yet — this is brainstorm notes. But the design is now coherent enough that the next session can move on whether the player-expression engine is the right pillar to anchor on, or whether it's overreach for a 6-month solo build. The sim ([17-foldins § Data pipeline](17-foldins-2026-05-12.md)) will need to model latent-axis dynamics to estimate authoring cost, content variety per save, and whether the folk-knowledge curve actually lands in 3–5 runs.
|