The run: which level is up, what happened to it, and where to go next.
What this replaces
Three games, three answers, none of them shared:
| dungeon | a 278-line cubit with nine tests |
| platformer | nine private methods and five fields inside a 1441-line widget |
| racing | nothing at all |
The same sequence in each: load a document, say why if it will not read, start again, move on when the level says there is somewhere to move on to, write the run down, put it back, and tell the screen how it ended.
Why the awkward parts are here
Everything in this class that is longer than a line is a rule that has been got wrong at least once:
- advance does nothing twice. A finished level stays finished for every frame until the next one is up, and without the guard each of those frames starts another load — a dozen of them on a slow disk.
- begin falls back. A save naming a level that no longer exists is a player whose game will not start, and renaming a level file should not brick every save that mentions it.
- save refuses a finished run. A save written at the exit is a save the next launch resumes, putting the player back at the end of a level they already beat.
- restart rebuilds rather than resumes. A run that begins with the health you died at is not a restart.
Not a cubit
An ordinary class, so this package makes no choice about state management
for the games above it. Two of the three wrap it in a cubit; onChanged
fires on every transition and each transition builds a fresh RunStatus, so
a Cubit.emit of it is a distinct state and rebuilds.
L is whatever a game gets back from loading a level. This class never
looks inside it — the five methods below are how it asks.
Constructors
-
RunSession({required String firstLevel, required SaveFile saves, void onChanged(RunStatus<
L> status)?})
Properties
- firstLevel → String
-
Where a new game starts.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- isOver → bool
-
Whether the run has ended, either way.
no setter
- level → L?
-
The level that is up, or null.
no setter
-
onChanged
↔ void Function(RunStatus<
L> status)? -
Called after every transition. A cubit passes its own
emitthrough here.getter/setter pair - runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- saves → SaveFile
-
final
-
status
→ RunStatus<
L> -
no setter
Methods
-
advance(
) → Future< void> - Moves on if the level said there is somewhere to move on to.
-
beforeNext(
String next) → Future< void> - A beat before the next level is read. Immediate by default.
-
begin(
) → Future< bool> - Starts a game: the saved run if there is one, otherwise firstLevel.
-
carryFrom(
L level, String next) → void -
What the player takes with them into
next. Empty by default. -
close(
L level) → void - Lets go of a level that is being left. Nothing by default.
-
load(
String asset, {Snapshot? resume}) → Future< void> -
Reads
assetand puts it on screen. -
nextOf(
L level) → String? - Which document comes after this one, or null for the end of the game.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
observe(
) → void - Reads how the run is going and republishes it if it changed.
-
onLost(
L level) → void - What a game does about a run that ended badly. Nothing by default.
-
open(
String asset) → Future< L> -
Reads
assetand builds everything it takes to play it. -
outcomeOf(
L level) → RunOutcome -
How the run in
levelis going, in the words every game shares. -
restart(
) → Future< void> - Puts the current level back the way it started.
-
restoreInto(
L level, Snapshot snapshot) → void - Puts a saved run back into a freshly loaded level.
-
save(
) → void - Writes where the run has got to, if there is one worth writing.
-
snapshotOf(
L level) → Snapshot - The run so far, for the save file.
-
startFresh(
) → void - What a fresh run starts with. Empty by default.
-
startOver(
) → Future< void> - Throws the run away and starts the game again from firstLevel.
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited