OnStart takes a script name, and OnFinale joins it
ci/woodpecker/push/woodpecker Pipeline was successful

The opening a game plays was the one piece of content that had to be
assembled in the wiring, because OnStart wanted an Action. It takes the
name of a registered Script now, so an opening is a Script like any
other, and Validate rejects a name that is not there.

OnFinale names the closing script and queues it straight after the start
one — what a "boot into the ending" debug flag wants.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 11:25:49 +02:00
co-authored by Claude Opus 5
parent 39af65f3c9
commit e26f7345c1
3 changed files with 42 additions and 8 deletions
+16 -2
View File
@@ -42,7 +42,8 @@ type Game struct {
Input *Input
startID string
onStart Action
onStart string
onFinale string
activeTheme string
// runtime
@@ -190,7 +191,15 @@ func (g *Game) SceneHotspots(name string) []Hotspot {
g.exitHotspots[name] = hs
return hs
}
func (g *Game) OnStart(a Action) *Game { g.onStart = a; return g }
// OnStart names the script queued after the start scene's OnEnter, once,
// when the game boots.
func (g *Game) OnStart(script string) *Game { g.onStart = script; return g }
// OnFinale names the game's closing script, queued directly after the start
// script — which is what a "boot straight into the ending" debug flag wants.
// Leave it unset for an ordinary run.
func (g *Game) OnFinale(script string) *Game { g.onFinale = script; return g }
// ----- theme + UI conveniences ------------------------------------------
@@ -327,6 +336,11 @@ func (g *Game) Validate() error {
}
}
}
for _, name := range []string{g.onStart, g.onFinale} {
if name != "" && !g.ScriptManager.Has(name) {
return fmt.Errorf("%w: %q", ErrUnknownScript, name)
}
}
if g.activeTheme == "" || !g.ThemeManager.Has(g.activeTheme) {
return fmt.Errorf("inkwell: no active theme (got %q)", g.activeTheme)
}