Checkpoint ink architecture updates
This commit is contained in:
+74
-3
@@ -41,6 +41,20 @@ Use `-> TURN` at the end of a chosen atomic weave when play should continue at t
|
||||
|
||||
Choice text is written from Valerie's perspective before the action. It may describe intention, attention, posture, or immediate action. It must not reveal what the branch will discover after the choice.
|
||||
|
||||
Dialogue choices use a stricter form. If the choice represents a spoken line, the visible choice text must contain that line. If the addressee matters and is not obvious from the room or weave, put the addressee into the bold action phrase before the colon:
|
||||
|
||||
```ink
|
||||
* [__Prüfe Viktor__: „Welche Zeile betrifft Sie, Herr Nowak?“]
|
||||
```
|
||||
|
||||
Do not write dialogue choices as post-hoc summaries such as:
|
||||
|
||||
```ink
|
||||
* [__Frage__: Viktor, weshalb er wirklich mitreist.]
|
||||
```
|
||||
|
||||
Neutral UI verbs such as `Frage`, `Sage`, `Antworte`, and `Sprich` are too weak for ordinary dialogue. Prefer verbs that name Valerie's social move, such as `Prüfe`, `Wahre Form`, `Entwaffne`, `Benenne`, `Schone`, `Trotze`, `Reize`, or `Zügle dich`. Non-dialogue choices may omit a quoted line when they represent physical action, attention, traversal, or examination rather than speech.
|
||||
|
||||
Good:
|
||||
|
||||
```ink
|
||||
@@ -53,19 +67,22 @@ Bad:
|
||||
* [__Prüfe__: Die Tür zu den Wagen zweiter und dritter Klasse. #key:w]
|
||||
```
|
||||
|
||||
Use Ink's built-in visit tracking for simple “this knot has been seen” facts. Do not create parallel flags such as `seen_train_compartment`. Use `LIST` state only for semantic progress, encounter chains, timetable state, locations, character-generation facts, tutorials, and other authored state that has meaning beyond a knot visit.
|
||||
Use Ink's built-in visit tracking for simple “this knot/choice/gather has been seen or chosen” facts. Do not create parallel flags such as `seen_train_compartment`. Use `LIST` state only for semantic progress, encounter chains, timetable state, locations, character-generation facts, tutorials, and other authored state that has meaning beyond a knot visit.
|
||||
|
||||
## Helper Conventions
|
||||
|
||||
Author-facing helper functions live in `data/ink-src/eibenreith/helpers.ink` and are documented in comments there. Important families:
|
||||
|
||||
- `route_*`: Valerie route counters such as `route_composure` and `route_sapphic`.
|
||||
- `route_repeated(route_id, amount)`, `route_is_highest(route_id)`, `route_is_clear(route_id, margin)`, `route_beats(route_id, other_route_id, margin)`: route-pattern heuristics. Use `composure`, `detective`, `lover`, `sapphic`, `careless`, or `eccentric` as `RouteId` values.
|
||||
- `time_*`, `day_*`, `slot_*`, `episode_*`: timetable and episode control.
|
||||
- `meal_*`: arrival-day meal plan.
|
||||
- `loc_*`, `enter_room`, `present`, `companion_*`: traversal, room setup, and companion presence.
|
||||
- `alone`, `alone_with(character)`: privacy checks for dialogue that should only surface without witnesses or with exactly one companion.
|
||||
- `state_*`: ordered high-watermark encounter/progress state.
|
||||
- `mark`, `has`, `lacks`: exact checklist facts.
|
||||
- `tutorial`: returns true once and marks the tutorial as shown.
|
||||
- `claim_choice_gate(gate)`: transient choice-surface arbitration. Use only to allow at most one choice from a prioritized family, especially `#auto` groups.
|
||||
- `rel_*`: relationship counters and two-value relationship-axis queries.
|
||||
|
||||
Relationship counters use only the standard value pairs declared in `characters.ink`:
|
||||
@@ -78,6 +95,60 @@ Relationship counters use only the standard value pairs declared in `characters.
|
||||
|
||||
Do not add per-character custom relationship dimensions. If a concept does not fit the shared matrix, express it in prose or in a semantic encounter `LIST`.
|
||||
|
||||
Relationship values are impressions held by the named character about Valerie. `viktor_insightful` means Viktor experiences Valerie as insightful. It does not mean Viktor behaves insightfully.
|
||||
|
||||
## Tracking Domains
|
||||
|
||||
Keep the four tracking domains strictly separated:
|
||||
|
||||
- Route heuristics are for Valerie's general reputation, repeated social pattern, and ending-state coloration. Use route counters and `route_*` query helpers for these.
|
||||
- The character matrix is for what a named character thinks about Valerie and how that character reacts to her presence and actions. `viktor_insightful` means Viktor reads Valerie as insightful.
|
||||
- Callbacks are for one concrete choice taken or one concrete piece of content shown. Use Ink's named option/gather/knot tracking with labels such as `(asked_viktor_role)` and conditions such as `{train_compartment_bucket.asked_viktor_role}`. Do not create `cb_*` facts for ordinary callbacks.
|
||||
- Encounter state trackers are for off-screen plotlines, knowledge chains, reached goals, NPC actions, relationship progress along a plotline, and other one-way progress. They must never track that one piece of content has merely played.
|
||||
|
||||
Use a named Ink callback when later content remembers one concrete earlier choice:
|
||||
|
||||
```ink
|
||||
* (send_carriage_ahead_from_village) [__Verfüge__: Die Kutsche mit Gepäck und Nachricht vorausschicken.]
|
||||
...
|
||||
|
||||
* {village_detour_exits.send_carriage_ahead_from_village} [__Erinnere__: An die vorausgeschickte Kutsche.]
|
||||
```
|
||||
|
||||
Use a separate semantic `LIST` with the `state_*` helpers whenever a tracker expresses a linear process. This also applies to small two-state processes such as "begun" and "completed"; if completion implies beginning, it is a progress tracker, not a pair of loose facts.
|
||||
|
||||
Use `state_reach(first_state)` when authoring the moment that begins the chain. Use `state_reach_if_started(later_state)` when an action can advance or complete a chain only if the player has already begun that line. The helper checks the chain automatically, so authors do not need to write noisy paired conditions such as `{state_reached(start)} ~ state_reach(done)`.
|
||||
|
||||
Use `state_started(state)` and `state_unstarted(state)` only when content must explicitly test the null/non-null state of a progress chain. Do not add a fake `none` or `unknown` item to every list just to represent the empty state.
|
||||
|
||||
Prefer multiple small parallel progress trackers over one large state chain when that better matches the encounter. Inkle-style knowledge bases work by advancing separate knowledge/progress lines independently, then querying their combination in content.
|
||||
|
||||
Use exact facts through `mark`, `has`, and `lacks` only for coherent groups of independent facts that can be true separately and do not imply order, such as tutorial display or mutually exclusive outcome facts.
|
||||
|
||||
Never put mutually exclusive alternatives into one `state_reach` list. For example, `public_mask_established` and `public_mask_strained` are exact facts, not ordered states; reaching one must not imply the other.
|
||||
|
||||
Use route and relationship helpers only as heuristics. They should color tone, summaries, repeated social readings, and available flavor, not replace callbacks to exact choices.
|
||||
|
||||
## Choice-Surface Gates
|
||||
|
||||
`claim_choice_gate(gate)` returns true only for the first condition that claims the given gate while the current choice surface is being built. It is reset automatically at the start of `provide_choices`.
|
||||
|
||||
Use it when several choices can be valid at the same time but the surface must offer only one of them. The main use case is prioritized `#auto` families:
|
||||
|
||||
```ink
|
||||
* {state_reached(freshen_up_done)} {claim_choice_gate(return_auto)} [AUTO: Viktors Rückkehr nach Frischmachen] #auto:return(2)
|
||||
...
|
||||
-> TURN
|
||||
|
||||
* {state_reached(explore_train_done)} {claim_choice_gate(return_auto)} [AUTO: Viktors Rückkehr nach Erkundung] #auto:return(2)
|
||||
...
|
||||
-> TURN
|
||||
```
|
||||
|
||||
The source order of the atoms is the priority order. Auto choices are not randomized by the UI; the first ready auto choice is selected like a normal Ink choice. The gate prevents lower-priority choices from surfacing on the same choice build. Put `claim_choice_gate(...)` last in the condition list, after all ordinary availability checks, so a false candidate cannot consume the gate. The shared `#auto:key(delay)` prevents the same auto family from firing again too soon on later builds. Use the colon form for keyed auto tags on choice lines; bracketed `#auto[key](delay)` is not Ink-compatible there.
|
||||
|
||||
Do not use gates as story memory. World state belongs in Ink callbacks, `state_*` progress chains, or `mark/has/lacks` facts.
|
||||
|
||||
## Implemented Tag Forms
|
||||
|
||||
Use bracket tags for titles, filenames, and longer text:
|
||||
@@ -175,11 +246,11 @@ Auto choices are ordinary Ink choices with a developer-facing choice text in `[.
|
||||
* {condition} [AUTO: Ereignisname] #auto(2)
|
||||
-> event
|
||||
|
||||
* {condition} [AUTO: Ereignisname] #auto[tunnel](2)
|
||||
* {condition} [AUTO: Ereignisname] #auto:tunnel(2)
|
||||
-> event
|
||||
```
|
||||
|
||||
`#auto` fires as soon as it is the first ready auto choice. `#auto(2)` waits at least two UI choice turns since the previous global auto trigger. `#auto[keyword](2)` waits only against the same keyword, so unrelated auto groups do not throttle each other. Use the global form when two different authored events must not fire immediately after each other.
|
||||
`#auto` fires as soon as it is the first ready auto choice. `#auto(2)` waits at least two UI choice turns since the previous global auto trigger. `#auto:keyword(2)` waits only against the same keyword, so unrelated auto groups do not throttle each other. Use the global form when two different authored events must not fire immediately after each other. Use the colon form for keyed auto tags on choice lines.
|
||||
|
||||
## Popup And End-State Tags
|
||||
|
||||
|
||||
Reference in New Issue
Block a user