Checkpoint ink architecture updates
This commit is contained in:
@@ -43,6 +43,7 @@ VAR current_episode_bucket = -> empty_bucket
|
||||
VAR current_episode_start = -> empty_bucket
|
||||
VAR current_episode_end = -> empty_bucket
|
||||
VAR current_game_bucket = -> game_bucket
|
||||
VAR claimed_choice_gates = ()
|
||||
|
||||
VAR slot_early_morning_episode = no_episode
|
||||
VAR slot_mid_morning_episode = episode_train_intro
|
||||
@@ -78,6 +79,7 @@ VAR slot_late_night_episode = no_episode
|
||||
|
||||
|
||||
=== provide_choices ===
|
||||
~ claimed_choice_gates = ()
|
||||
{
|
||||
- room_seen_on_enter():
|
||||
<- current_moment_bucket
|
||||
@@ -92,6 +94,34 @@ VAR slot_late_night_episode = no_episode
|
||||
-> DONE
|
||||
|
||||
|
||||
// Claim a transient gate for this single choice-surface build.
|
||||
//
|
||||
// This is not story state. It is cleared at the start of provide_choices and is
|
||||
// used only to arbitrate between multiple choices that could otherwise surface
|
||||
// together, especially prioritized #auto choices. The first condition in source
|
||||
// order that claims a gate returns true; later claims of the same gate return
|
||||
// false until the next choice surface is built.
|
||||
//
|
||||
// Use sparingly, and only where the surface must offer at most one item from a
|
||||
// family. Normal story memory belongs in Ink callbacks, state_* chains, or
|
||||
// mark/has/lacks facts.
|
||||
//
|
||||
// Example:
|
||||
// Put claim_choice_gate last in the condition list. Earlier conditions should
|
||||
// prove that the choice is valid before this side-effecting helper consumes the
|
||||
// gate.
|
||||
//
|
||||
// * {state_reached(freshen_up_done)} {claim_choice_gate(return_auto)} [...] #auto:return(2)
|
||||
=== function claim_choice_gate(gate) ===
|
||||
{
|
||||
- claimed_choice_gates ? gate:
|
||||
~ return false
|
||||
- else:
|
||||
~ claimed_choice_gates += gate
|
||||
~ return true
|
||||
}
|
||||
|
||||
|
||||
=== empty_bucket ===
|
||||
-> DONE
|
||||
|
||||
@@ -157,6 +187,18 @@ VAR route_eccentric = 0
|
||||
// - route_reached(route, amount): true when the counter is >= amount.
|
||||
// - route_between(route, min, max): true when the counter is within the
|
||||
// inclusive range min..max.
|
||||
// - route_value(route_id): returns a route counter by RouteId LIST item.
|
||||
// - route_total(): total number of route-marking choices taken.
|
||||
// - route_beats(route_id, other_route_id, margin): true when one route is ahead
|
||||
// of another by at least margin.
|
||||
// - route_repeated(route_id, amount): true when a route has been chosen at
|
||||
// least amount times. Use for "player keeps choosing this mode" heuristics.
|
||||
// - route_is_highest(route_id): true when a route is tied for or holds the
|
||||
// highest current route total and has been chosen at least once.
|
||||
// - route_is_clear(route_id, margin): true when a route leads every other route
|
||||
// by at least margin. Use this for strong heuristic tone changes.
|
||||
// - route_share_reached(route_id, numerator, denominator): true when a route is
|
||||
// at least numerator/denominator of all route-marking choices.
|
||||
//
|
||||
// Route counters are simple totals, not Ingold-style two-value axes. Do not use
|
||||
// them with relationship matrix helpers.
|
||||
@@ -194,6 +236,76 @@ VAR route_eccentric = 0
|
||||
=== function route_between(value, min, max) ===
|
||||
~ return value >= min && value <= max
|
||||
|
||||
=== function route_value(route_id) ===
|
||||
{
|
||||
- route_id ? composure:
|
||||
~ return route_composure
|
||||
- route_id ? detective:
|
||||
~ return route_detective
|
||||
- route_id ? lover:
|
||||
~ return route_lover
|
||||
- route_id ? sapphic:
|
||||
~ return route_sapphic
|
||||
- route_id ? careless:
|
||||
~ return route_careless
|
||||
- route_id ? eccentric:
|
||||
~ return route_eccentric
|
||||
- else:
|
||||
~ return 0
|
||||
}
|
||||
|
||||
=== function route_total() ===
|
||||
~ return route_composure + route_detective + route_lover + route_sapphic + route_careless + route_eccentric
|
||||
|
||||
=== function route_best_value() ===
|
||||
{
|
||||
- route_composure >= route_detective && route_composure >= route_lover && route_composure >= route_sapphic && route_composure >= route_careless && route_composure >= route_eccentric:
|
||||
~ return route_composure
|
||||
- route_detective >= route_composure && route_detective >= route_lover && route_detective >= route_sapphic && route_detective >= route_careless && route_detective >= route_eccentric:
|
||||
~ return route_detective
|
||||
- route_lover >= route_composure && route_lover >= route_detective && route_lover >= route_sapphic && route_lover >= route_careless && route_lover >= route_eccentric:
|
||||
~ return route_lover
|
||||
- route_sapphic >= route_composure && route_sapphic >= route_detective && route_sapphic >= route_lover && route_sapphic >= route_careless && route_sapphic >= route_eccentric:
|
||||
~ return route_sapphic
|
||||
- route_careless >= route_composure && route_careless >= route_detective && route_careless >= route_lover && route_careless >= route_sapphic && route_careless >= route_eccentric:
|
||||
~ return route_careless
|
||||
- route_eccentric >= route_composure && route_eccentric >= route_detective && route_eccentric >= route_lover && route_eccentric >= route_sapphic && route_eccentric >= route_careless:
|
||||
~ return route_eccentric
|
||||
- else:
|
||||
~ return 0
|
||||
}
|
||||
|
||||
=== function route_beats(route_id, other_route_id, margin) ===
|
||||
~ return route_value(route_id) - route_value(other_route_id) >= margin
|
||||
|
||||
=== function route_repeated(route_id, amount) ===
|
||||
~ return route_value(route_id) >= amount
|
||||
|
||||
=== function route_is_highest(route_id) ===
|
||||
~ return route_value(route_id) > 0 && route_value(route_id) >= route_best_value()
|
||||
|
||||
=== function route_is_clear(route_id, margin) ===
|
||||
{
|
||||
- route_id ? composure:
|
||||
~ return route_composure > 0 && route_composure - route_detective >= margin && route_composure - route_lover >= margin && route_composure - route_sapphic >= margin && route_composure - route_careless >= margin && route_composure - route_eccentric >= margin
|
||||
- route_id ? detective:
|
||||
~ return route_detective > 0 && route_detective - route_composure >= margin && route_detective - route_lover >= margin && route_detective - route_sapphic >= margin && route_detective - route_careless >= margin && route_detective - route_eccentric >= margin
|
||||
- route_id ? lover:
|
||||
~ return route_lover > 0 && route_lover - route_composure >= margin && route_lover - route_detective >= margin && route_lover - route_sapphic >= margin && route_lover - route_careless >= margin && route_lover - route_eccentric >= margin
|
||||
- route_id ? sapphic:
|
||||
~ return route_sapphic > 0 && route_sapphic - route_composure >= margin && route_sapphic - route_detective >= margin && route_sapphic - route_lover >= margin && route_sapphic - route_careless >= margin && route_sapphic - route_eccentric >= margin
|
||||
- route_id ? careless:
|
||||
~ return route_careless > 0 && route_careless - route_composure >= margin && route_careless - route_detective >= margin && route_careless - route_lover >= margin && route_careless - route_sapphic >= margin && route_careless - route_eccentric >= margin
|
||||
- route_id ? eccentric:
|
||||
~ return route_eccentric > 0 && route_eccentric - route_composure >= margin && route_eccentric - route_detective >= margin && route_eccentric - route_lover >= margin && route_eccentric - route_sapphic >= margin && route_eccentric - route_careless >= margin
|
||||
- else:
|
||||
~ return false
|
||||
}
|
||||
|
||||
=== function route_share_reached(route_id, numerator, denominator) ===
|
||||
~ temp total = route_total()
|
||||
~ return total > 0 && route_value(route_id) * denominator >= total * numerator
|
||||
|
||||
// ============================================================================
|
||||
// TIME-SLOT HELPERS
|
||||
// ============================================================================
|
||||
@@ -409,6 +521,8 @@ VAR route_eccentric = 0
|
||||
// - accompanied_by(character): true when character is in the companion list.
|
||||
// - companion_join(character), companion_leave(character): update companions.
|
||||
// - present(character): true when a character's location equals current_location.
|
||||
// - alone(): true when no tracked NPC is currently present with Valerie.
|
||||
// - alone_with(character): true when exactly the given tracked NPC is present.
|
||||
// - character_move_to(character, location): move a known NPC independently.
|
||||
//
|
||||
// Structural helper:
|
||||
@@ -448,6 +562,17 @@ VAR route_eccentric = 0
|
||||
~ return false
|
||||
}
|
||||
|
||||
=== function alone() ===
|
||||
~ return not present(viktor)
|
||||
|
||||
=== function alone_with(character) ===
|
||||
{
|
||||
- character == viktor:
|
||||
~ return present(viktor)
|
||||
- else:
|
||||
~ return false
|
||||
}
|
||||
|
||||
=== function character_move_to(character, location) ===
|
||||
{
|
||||
- character == viktor:
|
||||
@@ -503,9 +628,13 @@ VAR story_state = ()
|
||||
//
|
||||
// Author-facing helpers:
|
||||
// - state_reach(state_or_states): advance one or more ordered LIST states.
|
||||
// - state_reach_if_started(state_or_states): advance only chains that already
|
||||
// have any reached state; useful when one action can complete an already
|
||||
// started task but must not start it retroactively.
|
||||
// - state_move_to(state): readable alias for state_reach(state).
|
||||
// - state_reached(state), state_before(state), state_between(a, b),
|
||||
// state_is(state), state_current(state): query ordered progress.
|
||||
// state_started(state), state_unstarted(state), state_is(state),
|
||||
// state_current(state): query ordered progress.
|
||||
// - mark(fact_or_facts), has(fact_or_facts), lacks(fact_or_facts): manage exact
|
||||
// checklist facts.
|
||||
// - tutorial(tutorial_fact): returns true once and marks the tutorial as shown.
|
||||
@@ -575,6 +704,27 @@ VAR story_state = ()
|
||||
}
|
||||
|
||||
|
||||
// Return true if any state in the same LIST chain has been reached.
|
||||
// This is the generic "not null" check for a progress tracker.
|
||||
//
|
||||
// Use when content needs to know whether a linear process has begun at all,
|
||||
// without caring which exact step is current.
|
||||
//
|
||||
// Example:
|
||||
// {state_started(freshen_up_done): ...}
|
||||
=== function state_started(state) ===
|
||||
~ return LIST_COUNT(story_state ^ LIST_ALL(state)) > 0
|
||||
|
||||
|
||||
// Return true if no state in the same LIST chain has been reached.
|
||||
// This is the generic null-state check for a progress tracker.
|
||||
//
|
||||
// Example:
|
||||
// {state_unstarted(freshen_up_started): ...}
|
||||
=== function state_unstarted(state) ===
|
||||
~ return not state_started(state)
|
||||
|
||||
|
||||
// Mark a state, or a list of states, as reached.
|
||||
// High-watermark behavior:
|
||||
// reaching a state automatically reaches all earlier states in the same LIST chain.
|
||||
@@ -600,6 +750,29 @@ VAR story_state = ()
|
||||
}
|
||||
|
||||
|
||||
// Mark a state, or list of states, as reached only if its own LIST chain has
|
||||
// already begun.
|
||||
//
|
||||
// Use this for actions that can satisfy an already stated intention or progress
|
||||
// an already active line, but must not create that line retroactively.
|
||||
//
|
||||
// Example:
|
||||
// ~ state_reach_if_started(freshen_up_done)
|
||||
// ~ state_reach_if_started((freshen_up_done, unwell_managed))
|
||||
=== function state_reach_if_started(states_to_set) ===
|
||||
~ temp x = state_pop(states_to_set)
|
||||
{
|
||||
- not x:
|
||||
~ return false
|
||||
|
||||
- state_started(x):
|
||||
~ return state_reach(x) || state_reach_if_started(states_to_set)
|
||||
|
||||
- else:
|
||||
~ return false || state_reach_if_started(states_to_set)
|
||||
}
|
||||
|
||||
|
||||
// Return true if every given independent fact has been marked.
|
||||
// Facts are exact checklist items, not forward-moving encounter states.
|
||||
// Example:
|
||||
|
||||
Reference in New Issue
Block a user