Quest model: a chain of objectives GameState can answer for itself #131

Closed
opened 2026-08-28 12:20:34 +00:00 by metaheavens · 1 comment
Owner

Sub-ticket of #129.

The data behind the quests, with no UI in it.

  • An ordered chain of quests. Each names one goal, and the goals are of a few kinds rather than one kind per quest: gather a resource, build a structure, own a vessel, explore, land on a kind of planet, conquer one, research a node.
  • Progress is latched: a quest that has been satisfied stays satisfied. Collecting 5 ore and then spending it must not un-complete the quest.
  • GameState owns it, so it survives the space <-> planet-surface scene swap the way everything else does, and reset_new_game() puts it back to the first quest.
  • Signals for started/completed so the HUD and the banner are listeners rather than pollers.
  • Nothing in the chain may ask for something the player cannot yet reach - notably research points, which only come from conquering planets.
Sub-ticket of #129. The data behind the quests, with no UI in it. - An ordered chain of quests. Each names one goal, and the goals are of a few kinds rather than one kind per quest: gather a resource, build a structure, own a vessel, explore, land on a kind of planet, conquer one, research a node. - Progress is *latched*: a quest that has been satisfied stays satisfied. Collecting 5 ore and then spending it must not un-complete the quest. - `GameState` owns it, so it survives the space <-> planet-surface scene swap the way everything else does, and `reset_new_game()` puts it back to the first quest. - Signals for started/completed so the HUD and the banner are listeners rather than pollers. - Nothing in the chain may ask for something the player cannot yet reach - notably research points, which only come from conquering planets.
Author
Owner

Done in 397983b.

core/Quests.gd holds the chain as data and nothing else; GameState holds how far along it the player is and answers each goal.

Eight goal kinds, each one line in quest_progress(): a resource total, a building standing, a vessel flying, a vessel unlocked, sectors charted, planets landed on, kinds of world landed on, and planets conquered. Every one is answered from state the autoload already holds - a goal that needed a scene node to ask would be a goal that stops working the moment the player lands on a planet.

Latching came out free rather than needing a mechanism. The chain is walked one quest at a time, so the moment a goal is met the index moves on and never comes back: collecting five ore and then spending it cannot un-complete the quest that asked for five, because by the time it is spent nothing is asking. That is what lets goals be phrased against current holdings instead of against a running total that would have to be kept in step by hand.

Two constraints the model enforces rather than hopes for:

  • An unknown goal kind reads as never done, not as already done. The other way round would run the whole chain off in a single frame.
  • The chain is armed by reset_new_game() - the same gate intro_active uses, and the only door into a real game. Instantiating a scene is not by itself a reason to start briefing somebody, which matters for the 110 tests that load Main.tscn to look at something else.

Landing is now recorded (note_planet_visited, written at the same moment the descent commits), because "flown past" and "set down on" are different questions and explored_chunks only answers the first.

Done in `397983b`. `core/Quests.gd` holds the chain as data and nothing else; `GameState` holds how far along it the player is and answers each goal. Eight goal kinds, each one line in `quest_progress()`: a resource total, a building standing, a vessel flying, a vessel unlocked, sectors charted, planets landed on, kinds of world landed on, and planets conquered. Every one is answered from state the autoload already holds - a goal that needed a scene node to ask would be a goal that stops working the moment the player lands on a planet. Latching came out free rather than needing a mechanism. The chain is walked one quest at a time, so the moment a goal is met the index moves on and never comes back: collecting five ore and then spending it cannot un-complete the quest that asked for five, because by the time it is spent nothing is asking. That is what lets goals be phrased against current holdings instead of against a running total that would have to be kept in step by hand. Two constraints the model enforces rather than hopes for: - An unknown goal kind reads as *never done*, not as already done. The other way round would run the whole chain off in a single frame. - The chain is armed by `reset_new_game()` - the same gate `intro_active` uses, and the only door into a real game. Instantiating a scene is not by itself a reason to start briefing somebody, which matters for the 110 tests that load `Main.tscn` to look at something else. Landing is now recorded (`note_planet_visited`, written at the same moment the descent commits), because "flown past" and "set down on" are different questions and `explored_chunks` only answers the first.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
metaheavens/spaceship#131
No description provided.