OnStart takes a script name, and OnFinale joins it
ci/woodpecker/push/woodpecker Pipeline was successful
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:
@@ -296,12 +296,29 @@ register into them instead unless that is what you want.
|
||||
|
||||
```go
|
||||
func (g *Game) StartAt(name string) *Game // entry scene
|
||||
func (g *Game) OnStart(a Action) *Game // action run after the scene's OnEnter
|
||||
func (g *Game) OnStart(script string) *Game // script run after the scene's OnEnter
|
||||
func (g *Game) OnFinale(script string) *Game // closing script, queued after OnStart
|
||||
func (g *Game) Validate() error // cross-check name references
|
||||
func (g *Game) Run() error // same as inkwell.Run(g)
|
||||
```
|
||||
|
||||
`StartAt` and `OnStart` return `*Game` so they chain at the end of `Build`.
|
||||
`OnStart` and `OnFinale` name registered scripts rather than taking an action,
|
||||
so the opening a game plays is content like any other — a `Script` in the
|
||||
`ScriptManager`, reachable by name and editable without touching the wiring.
|
||||
`Validate` rejects a name that is not registered.
|
||||
|
||||
`OnFinale` is queued directly after the start script, which is what a "boot
|
||||
straight into the ending" debug flag wants:
|
||||
|
||||
```go
|
||||
g.StartAt(start)
|
||||
g.OnStart(ScriptOpening)
|
||||
if finale {
|
||||
g.OnFinale(ScriptFinale)
|
||||
}
|
||||
```
|
||||
|
||||
All three return `*Game` so they chain at the end of `Build`.
|
||||
|
||||
### 4.3 Theme accessors
|
||||
|
||||
@@ -1540,8 +1557,8 @@ func Run(g *Game) error // toplevel — same as g.Run()
|
||||
3. If `UIManager` is empty, call `RegisterDefaultUI(g)`.
|
||||
4. Place the start scene directly (no transition), bump
|
||||
`State.NoteVisit`, position registered actors, kick off music.
|
||||
5. Compose `Seq(scene.OnEnter, game.OnStart)` and queue it as the initial
|
||||
action — the first script tick runs both in order.
|
||||
5. Compose `Seq(scene.OnEnter, OnStart script, OnFinale script)` and queue
|
||||
it as the initial action — the first script tick runs them in order.
|
||||
6. `ebiten.SetWindowSize(Width*4, Height*4)`,
|
||||
`ebiten.SetWindowTitle(g.Title)`, then `ebiten.RunGame(&engine{g})`.
|
||||
|
||||
|
||||
+5
-2
@@ -34,8 +34,11 @@ func Run(g *Game) error {
|
||||
if s.OnEnter != nil {
|
||||
seq = append(seq, s.OnEnter)
|
||||
}
|
||||
if g.onStart != nil {
|
||||
seq = append(seq, g.onStart)
|
||||
if g.onStart != "" {
|
||||
seq = append(seq, RunScript(g.onStart))
|
||||
}
|
||||
if g.onFinale != "" {
|
||||
seq = append(seq, RunScript(g.onFinale))
|
||||
}
|
||||
if len(seq) > 0 {
|
||||
g.queueAction(Seq(seq...), "init")
|
||||
|
||||
+16
-2
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user