RunSession<L> class abstract base

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 emit through 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 asset and 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 asset and builds everything it takes to play it.
outcomeOf(L level) → RunOutcome
How the run in level is 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