Fix contact transitions and dining car access
This commit is contained in:
+31
-5
@@ -78,11 +78,12 @@ Author-facing helper functions live in `data/ink-src/eibenreith/helpers.ink` and
|
||||
- `time_*`, `day_*`, `slot_*`, `episode_*`: timetable and episode control.
|
||||
- `meal_*`: arrival-day meal plan.
|
||||
- `loc_*`, `enter_room`, `present`, `companion_*`: traversal, room setup, and companion presence.
|
||||
- `first_meeting(character)`, `reunion(character)`, `parting(character)`: contact-manager transitions for the one choice surface after a character first appears, reappears, or stops being present.
|
||||
- `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.
|
||||
- `claim_choice_gate_if(gate, available)`: transient choice-surface arbitration. Use only to allow at most one valid 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`:
|
||||
@@ -131,24 +132,49 @@ Use route and relationship helpers only as heuristics. They should color tone, s
|
||||
|
||||
## 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`.
|
||||
`claim_choice_gate_if(gate, available)` returns true only for the first valid 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)
|
||||
+ {claim_choice_gate_if(return_auto, reunion(viktor) && state_reached(freshen_up_done))} [AUTO: Viktors Rückkehr nach Frischmachen] #auto
|
||||
...
|
||||
-> TURN
|
||||
|
||||
* {state_reached(explore_train_done)} {claim_choice_gate(return_auto)} [AUTO: Viktors Rückkehr nach Erkundung] #auto:return(2)
|
||||
+ {claim_choice_gate_if(return_auto, reunion(viktor) && state_reached(explore_train_done))} [AUTO: Viktors Rückkehr nach Erkundung] #auto
|
||||
...
|
||||
-> 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.
|
||||
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. Use `claim_choice_gate_if(gate, available)` when availability is conditional; pass the whole availability expression as the second parameter so false candidates cannot consume the gate.
|
||||
|
||||
Do not use gates as story memory. World state belongs in Ink callbacks, `state_*` progress chains, or `mark/has/lacks` facts.
|
||||
|
||||
## Character Contact Manager
|
||||
|
||||
Character contact is managed centrally in `helpers.ink`. Authors should not add room-specific flags such as `viktor_back_in_compartment`, `met_viktor_here`, or `seen_viktor_leave`. `loc_move_to(...)` updates the player location, moves active companions, and refreshes contact state.
|
||||
|
||||
Use:
|
||||
|
||||
```ink
|
||||
{present(viktor)}
|
||||
{first_meeting(viktor)}
|
||||
{reunion(viktor)}
|
||||
{parting(viktor)}
|
||||
{alone()}
|
||||
{alone_with(viktor)}
|
||||
```
|
||||
|
||||
`first_meeting`, `reunion`, and `parting` are transition checks. They are true only for the first choice surface after the transition happened. The next turn clears them centrally in `provide_choices`. Authors must not call `contact_clear_transitions()` or any other cleanup helper from content. This makes the transitions suitable for immediate one-shot auto reactions:
|
||||
|
||||
```ink
|
||||
+ {claim_choice_gate_if(return_auto, reunion(viktor) && state_reached(freshen_up_done))} [AUTO: Viktors Rückkehr nach Frischmachen] #auto
|
||||
...
|
||||
-> TURN
|
||||
```
|
||||
|
||||
Companions are characters in the `companions` list. When Valerie traverses with `loc_move_to(...)`, companions automatically move to the new location before contact is updated. `companion_join(character)` and `companion_leave(character)` only change whether a character follows Valerie; they are not story-memory flags. Character starting positions and initial companion state belong in episode setup. If several characters are placed manually before play resumes, call `contact_sync()` once after setup to establish contact without firing a meeting or reunion reaction.
|
||||
|
||||
## Implemented Tag Forms
|
||||
|
||||
Use bracket tags for titles, filenames, and longer text:
|
||||
|
||||
Reference in New Issue
Block a user