diff --git a/CLAUDE.md b/CLAUDE.md index 2b2ba71..29c07d9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,12 +48,12 @@ This holds for nested literals too, including small ones such as All game code lives in one flat package, `inc`. There are no subdirectories: a file's name carries the structure, in the form `[category].[name].go`. -- The category is always **singular**: `item`, `screen`, `background`, +- The category is always **singular**: `item`, `scene`, `background`, `character`, `dialog`, `script`, `world`, `ui`, `theme`, `names`, `boot`, `content`. - `[category].manager.go` is the file that ties a category together — its manager, its entity type, whatever the category shares. -- Every other file in a category holds exactly one entity: one screen, one +- Every other file in a category holds exactly one entity: one scene, one background, one item. The file registers it itself, in an `init()`. ``` @@ -70,14 +70,14 @@ inc/world.action.go custom actions and the action pump inc/ui.manager.go HUD layout and widget registration inc/ui.*.go custom widgets, coloured text inc/content.manager.go composition root; calls every register… -inc/background.*.go one image asset per screen +inc/background.*.go one image asset per scene inc/character.*.go the cast, tapes included inc/item.*.go inventory inc/dialog.*.go dialogue trees inc/script.*.go named action sequences -inc/screen.manager.go the Screen type, the deck, the scene builder -inc/screen.exit.go the connections between screens -inc/screen.*.go one file per screen +inc/scene.manager.go the Scene alias, the defaults every scene gets +inc/scene.selector.go the map screen: its pins are derived from the graph +inc/scene.*.go one file per scene ``` `manager` is the one category with no entities of its own: it holds the registry @@ -101,7 +101,7 @@ var CharacterManager = NewManager(func(entity Character) string { return entity. That is the whole of a category's manager file — an alias and one line. There are seven managers: `BackgroundManager`, `CharacterManager`, `DialogManager`, -`ItemManager`, `ScriptManager`, `ScreenManager`, `ThemeManager`. +`ItemManager`, `ScriptManager`, `SceneManager`, `ThemeManager`. `manager.interface.go` holds the contract they all keep, and asserts each one against it. A new manager goes on that list. @@ -118,8 +118,9 @@ type ManagerInterface[T any] interface { twice is an update, never a duplicate. `GetAll` returns the slice itself, in registration order. -`Screen` is the one entity type that is not an alias: a screen carries exits and -an `OnSelector` flag that inkwell's `Scene` knows nothing about. +Every entity type is an alias, `Scene` included. It was once a struct of our +own, because inkwell's `Scene` could not carry exits; that gap was closed in the +engine, so there is nothing left for a second type to hold. ### Entities register themselves @@ -144,7 +145,7 @@ variables are initialised before any `init()` runs, so the managers exist by the time the first file registers into one. `init()` order is file-name order, so **registration order is alphabetical**. -Nothing may depend on it — including the order the arrow keys walk the screens, +Nothing may depend on it — including the order the arrow keys walk the scenes, which is simply the order the files sit in. ### Handing a category to the engine @@ -159,13 +160,13 @@ func registerContent() { registerAll(ItemManager, World.G.ItemManager.Register) registerAll(DialogManager, World.G.DialogueManager.Register) registerAll(ScriptManager, World.G.ScriptManager.Register) - registerScreen() + registerScene() } ``` -`registerScreen` is the one that needs its own function, because a screen has to -be turned into an `inkwell.Scene` first, and because the selector's pins are -derived from whichever screens marked themselves `OnSelector`. +`registerScene` is the one that needs its own function: it fills in the defaults +a scene may leave out (Paul's starting position, the floor walkbox), and it +derives the selector's pins by reading the exit graph backwards. ## The world @@ -185,7 +186,7 @@ One package means one namespace, so an entity's constructor carries its category as a prefix: ```go -screenFloor screenBuild registerScreen fillSelectorPins +sceneFloor sceneDefaults registerScene fillSelectorPins ``` Entities themselves need no name at all — they are anonymous literals inside @@ -198,12 +199,12 @@ constants in `names.manager.go`, the colour tokens, and the action constructors Everything else is machinery and stays unexported: the HUD widgets (`tapeSlots`, `letterbox`, `hudFrame`, …), the `register…` functions, the -runners, `screenBuild`, `exit`. +runners, `sceneDefaults`, `fillSelectorPins`. -The engine's word for a screen is `Scene`. Ours is **screen**, because the -wiki, the concept-art deck and the beat tables all count screens. "Scene" -survives only where the code talks to the engine (`EnterScene`, -`SceneManager`). +The word is **scene**, the engine's own. The wiki and the concept-art deck count +*screens*, and this code used to as well, but everything a screen had that a +scene did not now lives in inkwell. "Screen" survives only where it means the +display: `ScreenW`, `ScreenH`. ## Layering @@ -219,10 +220,10 @@ names ← theme ← world ← ui `world` knows nothing about the HUD or the content. Both build on it, never the other way round. -## Adding a screen +## Adding a scene -1. Constants in `inc/names.manager.go`: `Screen`, `Bg` -2. `inc/screen..go` — an `init()` registering a `Screen` +1. Constants in `inc/names.manager.go`: `Scene`, `Bg` +2. `inc/scene..go` — an `init()` registering a `Scene` 3. `inc/background..go` — an `init()` registering a `Background` 4. A 640×380 PNG in `assets/bg/` @@ -234,7 +235,7 @@ Nothing else moves. There is no list to update. make build native binary into bin/ make wasm js/wasm build into dist/ make watch rebuild on change -go run . -screen start on a given screen +go run . -scene start on a given scene go run . -finale start with the finale ``` diff --git a/README.md b/README.md index f7d510c..1142cb6 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ go run . ```bash go run . # the alley (beat 3) go run . -finale # the finale — try the Nokia-punk theme switch -go run . -screen selector # the location selector: the map the city hangs off -go run . -screen hospital # any screen in the deck, e.g. to look at the art +go run . -scene selector # the location selector: the map the city hangs off +go run . -scene hospital # any scene in the deck, e.g. to look at the art ``` -Screen names are the constants in `names.manager.go` (`selector`, `paul_shop`, +Scene names are the constants in `names.manager.go` (`selector`, `paul_shop`, `noodle_house`, `alley`, `norman_apartment`, `police_station`, `hackerspace`, `ice_cream_shop`, `trinket_shop`, `small_restaurant`, `secret_club`, `bbs_terminal`, `street`, `hospital`, `server_farm`, `secret_lab`, @@ -62,12 +62,12 @@ Release metadata lives in `metadata.json`. |---|---| | left click | run the selected verb | | right click | verb coin (Look / Use / Talk / Take) | -| `←` `→` | previous / next screen, in file order, wrapping | +| `←` `→` | previous / next scene, in file order, wrapping | | `F1` | toggle hotspot outlines | | `SPACE` | during a cutscene: let the tape speak, if it offered | -The screens are connected to each other (see **The map** below); the arrow keys -are a reviewing tool on top of that, walking every screen in turn. The walk is +The scenes are connected to each other (see **The map** below); the arrow keys +are a reviewing tool on top of that, walking every scene in turn. The walk is inert during a cutscene, a menu, or a stopped world, so it can never cut across an authored beat. @@ -181,15 +181,15 @@ Content is one registered entity per file, and the category prefix groups them the way directories used to: ``` -background.*.go one file per screen: background.paul_shop.go, … +background.*.go one file per scene: background.paul_shop.go, … character.*.go character.paul.go character.dex.go character.mystery_tape.go item.*.go item.noodle_letter.go item.black_market_armilla.go … dialog.*.go dialog.dex_talk.go dialog.mystery_tape_silent.go script.*.go script.tape_insert.go script.awakening_finale.go -screen.*.go one file per screen: screen.alley.go, … + screen.exit.go +scene.*.go one file per scene: scene.alley.go, … + scene.selector.go ``` -Adding a screen means adding `screen..go` and `background..go`. +Adding a scene means adding `scene..go` and `background..go`. Nothing else moves. Every category owns a manager, and they are all the same generic type, @@ -229,13 +229,13 @@ func init() { So adding an entity is adding a file, and there is no second list to keep in step. The price is that registration order is file-name order: the arrow keys -walk the screens alphabetically rather than in the concept-art deck's order. +walk the scenes alphabetically rather than in the concept-art deck's order. That was a deliberate trade — the deck order was a list that had to be kept in step with the files by hand, and the deck is a thing to look at, not a thing to play through. The game's own catalogue is readable without going through the engine: -`ScreenManager.GetByName("alley")` answers before a single scene has been handed +`SceneManager.GetByName("alley")` answers before a single scene has been handed over. `registerContent` is where the hand-off happens, one `registerAll` call per category. @@ -244,51 +244,63 @@ a `*world` parameter and no widget holds a back-reference, which is what lets a script file be a literal — the tape-insert script closes over `World` rather than over a parameter someone would have had to thread to it. -**On the word "screen".** inkwell's entity is called a `Scene`, and that is the -type every `screen.*.go` file returns — but the wiki, the concept-art deck and -the beat tables all count *screens*, so the category, the files and the flag say -screen. "Scene" survives only where the code is talking to the engine -(`EnterScene`, `SceneManager`). +**On the word "scene".** The wiki, the concept-art deck and the beat tables all +count *screens*, and this code used to as well: it carried its own `Screen` +struct, because inkwell's `Scene` could not hold the things a screen needs — +its exits above all. Those went into the engine instead (inkwell `Exit`, +`Game.SceneRect`, `CurrentScene`/`PreviousScene`, `Back()`), and with the gap +closed there was nothing left for a second type to carry. The code says scene, +because that is what the thing is. "Screen" survives only where it means the +display: `ScreenW`, `ScreenH`. Art lives in `assets/bg/` and is embedded into the binary (`main.go`), because js/wasm has no OS filesystem and `make binaries` packages the executable alone. ## The map -Where a screen leads is recorded **in that screen**, in its own file, and it +Where a scene leads is recorded **in that scene**, in its own file, and it comes from the wiki's location graph (`projects/realworld/story#helyszín-gráf-vázlat`). That graph has two kinds of edge and so does the code: - **Physical adjacency** — the alley is behind Noodle's house, the eating place is next door to the trinket shop, the club is through its back room, the roof - is up Norman's stairs. Declared with `to:` in the screen's `exits`. + is up Norman's stairs. Declared with `To:` in the scene's `Exits`. - **The selector** — the wiki centres its map on a *Helyszínválasztó*, "nem - valódi helyszín, hanem a menü-képernyő": a screen every main location connects - to both ways. A screen marks itself `onSelector: true`; `screen/selector.go` - builds the other half of each of those edges, so the list of locations on the - map is never written down twice. + valódi helyszín, hanem a menü-képernyő": a scene every main location connects + to both ways. A main location lists `exitToSelector` among its exits, and + `scene.selector.go` derives the other half of each edge by reading the graph + backwards — every scene with an exit to the selector gets a pin on it. The + list of locations on the map is never written down twice. -The wiki's conditional arrows survive too: `needs:` holds the flag an exit waits +The wiki's conditional arrows survive too: `Needs:` holds the flag an exit waits for, which is how *Bolt →|beengedés| Klub* is expressed — the way into the club is visible and named from the first visit, and stays shut until the shopkeeper has been shown the underwater sun. Until the doors are measured on the paintings, an exit is a strip along one edge -of the picture (`sideLeft`, `sideRight`, `sideBack`, `sideNear`) — the -convention every 1990s point & click used, and one field to re-aim later. A -screen reached from several rooms has no fixed way out: the BBS terminal is the -same terminal from the club, the flat or the roof, so its exit is `back`. +of the picture (`inkwell.ExitLeft`, `ExitRight`, `ExitBack`, `ExitNear`), sized +from `Game.SceneRect` so it lands inside the painting rather than under the HUD +— the convention every 1990s point & click used, and one field to re-aim later. +A scene reached from several rooms has no fixed way out: the BBS terminal is the +same terminal from the club, the flat or the roof, so its exit leaves `To` empty +and the engine binds it to `Back()`. The graph stays machine-readable: exit hotspots are named `exit:`, so -the connections can be read straight back out of the registered screens. +the connections can be read straight back out of the registered scenes — and +`Validate` rejects an exit that names a scene nobody registered. ## Engine workarounds -Five inkwell limits turned up during implementation that the engine README does -not mention. All five are worked around on the domain side; each is a candidate +Four inkwell limits turned up during implementation that the engine README does +not mention. All four are worked around on the domain side; each is a candidate for a small engine change. +Two others have been fixed in the engine since: exits are now +[`inkwell.Exit`](https://git.teletypegames.org/engines/inkwell) on the scene +itself, and `Game.CurrentScene()` / `PreviousScene()` mean the domain no longer +has to shadow where the player is. + 1. **`drawText` discards colour.** In `asset.text.go` the colour argument is `_ = c` and rendering goes through `ebitenutil.DebugPrintAt`, which only draws white. Every text colour in `Theme` is therefore inert. *Workaround:* @@ -308,16 +320,12 @@ for a small engine change. `handleSceneInput` and can consume the click, so unauthored pairs fail in character instead, escalating on repeats. -4. **No exported `CurrentScene()`**, but the pump needs `Ctx.Scene`. - *Workaround:* `EnterScene` is the first step of every scene's - `OnEnter`; the domain tracks it. - -5. **Widgets have no `Visible` field and the `Manager` cannot unregister**, so +4. **Widgets have no `Visible` field and the `Manager` cannot unregister**, so the built-in HUD cannot be hidden during a cutscene. *Workaround:* the `gate` wrapper in `ui/ui.go` forwards `Tick`/`Draw`/`BlocksClickAt` only while the HUD is visible. -6. **`Run` hardcodes a 4× window** (`core.dsl.go`), which at 640×400 would be +5. **`Run` hardcodes a 4× window** (`core.dsl.go`), which at 640×400 would be 2560×1600 — bigger than most laptop screens. *Workaround:* the `windowSizer` widget resizes once on the first tick, since Run sets the size before entering the loop. @@ -332,15 +340,15 @@ Also: the inkwell README gives the module path as stretched, but the strip is opaque and 118px of the 380 sit on top of the picture. Either the deck gets recut so nothing that matters lives in its bottom third, or the HUD gets a translucent panel treatment. -- **The screens are empty.** 22 backgrounds are in and they are wired to each +- **The scenes are empty.** 22 backgrounds are in and they are wired to each other, but only the alley has hotspots, NPCs and dialogue; everywhere else there is nothing to do but leave again. - **The selector has no art.** The wiki's Helyszínválasztó is the centre of the map and the deck does not include it, so it renders as a placeholder with one labelled pin per location on a plain grid. -- **Two screens are missing from the deck.** The alley (the one authored beat) +- **Two scenes are missing from the deck.** The alley (the one authored beat) and deck 05, Norman's workplace — which is in the wiki's catalogue but has no - screen file yet, so the workplace thread of the story has nowhere to happen. + scene file yet, so the workplace thread of the story has nowhere to happen. - **Spent dialogue choices are hidden, not struck through.** `DialogueChoice.Once` hides them; the deck wanted them struck through but visible, so the list becomes a memory of what you already tried. Needs a thin override over diff --git a/go.mod b/go.mod index fdd1fa4..1a049a7 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.teletypegames.org/games/realworld go 1.26.3 require ( - git.teletypegames.org/engines/inkwell v0.1.0 + git.teletypegames.org/engines/inkwell v0.1.1-0.20260829220920-f9745e426624 github.com/hajimehoshi/ebiten/v2 v2.9.9 ) diff --git a/go.sum b/go.sum index 0012ab9..ee7b3b6 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ git.teletypegames.org/engines/inkwell v0.1.0 h1:NJgT924aR3e0uLVRiTEhzLrXJY+Vnj+FArkKqMJJlVI= git.teletypegames.org/engines/inkwell v0.1.0/go.mod h1:/v6QtismTE8+e7kobbVR5B/CpTSrd4j2DYwJ8DvINhs= +git.teletypegames.org/engines/inkwell v0.1.1-0.20260829220920-f9745e426624 h1:lzKbik6RzcqIEub13X8a1J3V/MCQOPNo2XF8oOKm+Ts= +git.teletypegames.org/engines/inkwell v0.1.1-0.20260829220920-f9745e426624/go.mod h1:/v6QtismTE8+e7kobbVR5B/CpTSrd4j2DYwJ8DvINhs= github.com/ebitengine/gomobile v0.0.0-20250923094054-ea854a63cce1 h1:+kz5iTT3L7uU+VhlMfTb8hHcxLO3TlaELlX8wa4XjA0= github.com/ebitengine/gomobile v0.0.0-20250923094054-ea854a63cce1/go.mod h1:lKJoeixeJwnFmYsBny4vvCJGVFc3aYDalhuDsfZzWHI= github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE= diff --git a/inc/boot.manager.go b/inc/boot.manager.go index 8329d80..6b623e2 100644 --- a/inc/boot.manager.go +++ b/inc/boot.manager.go @@ -5,18 +5,25 @@ import ( ) type Opts struct { - Screen string + Scene string Finale bool } func New(o Opts) *inkwell.Game { - start := o.Screen + start := o.Scene if start == "" { - start = ScreenAlley + start = SceneAlley } g := inkwell.NewGame("Real World", ScreenW, ScreenH) g.MaxLogLines = 64 + g.SceneRect = inkwell.Rect(0, TopBarH, ScreenW, HUDTop-TopBarH) + g.ExitLook = func(e inkwell.Exit) inkwell.Action { + return inkwell.Say(Paul, "That way: "+e.Label+".") + } + g.ExitTake = func(inkwell.Exit) inkwell.Action { + return inkwell.Say(Paul, "It's a way out, not a thing.") + } World.attach(g) registerTheme() @@ -32,7 +39,6 @@ func New(o Opts) *inkwell.Game { func bootOpening(start string, finale bool) []inkwell.Action { acts := []inkwell.Action{ - EnterScene(start), inkwell.SetFlag(FlagPoliceTip), inkwell.Say(Paul, "Back alley. Just like the clerk said."), TapeSay(Dex, "A government office tipped you off to remove something from a scene. That doesn't strike you as odd?"), diff --git a/inc/content.manager.go b/inc/content.manager.go index a560985..11ecd5e 100644 --- a/inc/content.manager.go +++ b/inc/content.manager.go @@ -6,5 +6,5 @@ func registerContent() { registerAll(ItemManager, World.G.ItemManager.Register) registerAll(DialogManager, World.G.DialogueManager.Register) registerAll(ScriptManager, World.G.ScriptManager.Register) - registerScreen() + registerScene() } diff --git a/inc/manager.interface.go b/inc/manager.interface.go index 6edaabd..fc771ee 100644 --- a/inc/manager.interface.go +++ b/inc/manager.interface.go @@ -12,6 +12,6 @@ var ( _ ManagerInterface[Dialog] = DialogManager _ ManagerInterface[Item] = ItemManager _ ManagerInterface[Script] = ScriptManager - _ ManagerInterface[Screen] = ScreenManager + _ ManagerInterface[Scene] = SceneManager _ ManagerInterface[Theme] = ThemeManager ) diff --git a/inc/names.manager.go b/inc/names.manager.go index 37f723e..31d1bfc 100644 --- a/inc/names.manager.go +++ b/inc/names.manager.go @@ -36,30 +36,30 @@ const ( ) const ( - ScreenSelector = "selector" - ScreenPaulShop = "paul_shop" - ScreenNoodleHouse = "noodle_house" - ScreenNormanApartment = "norman_apartment" - ScreenPoliceStation = "police_station" - ScreenAlley = "alley" - ScreenHackerspace = "hackerspace" - ScreenIceCreamShop = "ice_cream_shop" - ScreenTrinketShop = "trinket_shop" - ScreenSmallRestaurant = "small_restaurant" - ScreenSecretClub = "secret_club" - ScreenBBSTerminal = "bbs_terminal" - ScreenStreet = "street" - ScreenHospital = "hospital" - ScreenServerFarm = "server_farm" - ScreenSecretLab = "secret_lab" - ScreenRooftopHideout = "rooftop_hideout" - ScreenPublicBBS = "public_bbs" - ScreenBVKBranch = "bvk_branch" - ScreenCuratorShop = "curator_shop" - ScreenScrapMarket = "scrap_market" - ScreenSamizdatPress = "samizdat_press" - ScreenShowroom = "showroom" - ScreenColumbarium = "columbarium" + SceneSelector = "selector" + ScenePaulShop = "paul_shop" + SceneNoodleHouse = "noodle_house" + SceneNormanApartment = "norman_apartment" + ScenePoliceStation = "police_station" + SceneAlley = "alley" + SceneHackerspace = "hackerspace" + SceneIceCreamShop = "ice_cream_shop" + SceneTrinketShop = "trinket_shop" + SceneSmallRestaurant = "small_restaurant" + SceneSecretClub = "secret_club" + SceneBBSTerminal = "bbs_terminal" + SceneStreet = "street" + SceneHospital = "hospital" + SceneServerFarm = "server_farm" + SceneSecretLab = "secret_lab" + SceneRooftopHideout = "rooftop_hideout" + ScenePublicBBS = "public_bbs" + SceneBVKBranch = "bvk_branch" + SceneCuratorShop = "curator_shop" + SceneScrapMarket = "scrap_market" + SceneSamizdatPress = "samizdat_press" + SceneShowroom = "showroom" + SceneColumbarium = "columbarium" ) const ( diff --git a/inc/screen.alley.go b/inc/scene.alley.go similarity index 94% rename from inc/screen.alley.go rename to inc/scene.alley.go index 56db3d1..ab893a5 100644 --- a/inc/screen.alley.go +++ b/inc/scene.alley.go @@ -5,15 +5,15 @@ import ( ) func init() { - ScreenManager.Register(Screen{ - Name: ScreenAlley, + SceneManager.Register(Scene{ + Name: SceneAlley, Title: "ALLEY — BEHIND NOODLE'S HOUSE", Background: BgAlley, - Exits: []exit{ + Exits: []inkwell.Exit{ { - to: ScreenNoodleHouse, - label: "back out to the street", - side: sideLeft, + To: SceneNoodleHouse, + Label: "back out to the street", + Side: inkwell.ExitLeft, }, }, Actors: []inkwell.SceneActor{ diff --git a/inc/scene.bbs_terminal.go b/inc/scene.bbs_terminal.go new file mode 100644 index 0000000..2ee213d --- /dev/null +++ b/inc/scene.bbs_terminal.go @@ -0,0 +1,19 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneBBSTerminal, + Title: "TERMINAL — BBS ACCESS POINT", + Background: BgBBSTerminal, + Exits: []inkwell.Exit{ + { + Label: "step back from the terminal", + Side: inkwell.ExitNear, + }, + }, + }) +} diff --git a/inc/scene.bvk_branch.go b/inc/scene.bvk_branch.go new file mode 100644 index 0000000..5dbb9d4 --- /dev/null +++ b/inc/scene.bvk_branch.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneBVKBranch, + Title: "BVK — SAN FRANCISCO BRANCH", + Background: BgBVKBranch, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.columbarium.go b/inc/scene.columbarium.go new file mode 100644 index 0000000..a68a997 --- /dev/null +++ b/inc/scene.columbarium.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneColumbarium, + Title: "COLUMBARIUM — DEX'S MEMORIAL", + Background: BgColumbarium, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.curator_shop.go b/inc/scene.curator_shop.go new file mode 100644 index 0000000..3893124 --- /dev/null +++ b/inc/scene.curator_shop.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneCuratorShop, + Title: "CURATOR SERVICE — THE MASTER'S WORKSHOP", + Background: BgCuratorShop, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.hackerspace.go b/inc/scene.hackerspace.go new file mode 100644 index 0000000..cdd0fbf --- /dev/null +++ b/inc/scene.hackerspace.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneHackerspace, + Title: "HACKERSPACE", + Background: BgHackerspace, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.hospital.go b/inc/scene.hospital.go new file mode 100644 index 0000000..7598060 --- /dev/null +++ b/inc/scene.hospital.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneHospital, + Title: "HOSPITAL — PSYCHIATRIC WING", + Background: BgHospital, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.ice_cream_shop.go b/inc/scene.ice_cream_shop.go new file mode 100644 index 0000000..df96462 --- /dev/null +++ b/inc/scene.ice_cream_shop.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneIceCreamShop, + Title: "ICE CREAM SHOP — WHERE THE BAR WAS", + Background: BgIceCreamShop, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.manager.go b/inc/scene.manager.go new file mode 100644 index 0000000..829f4b3 --- /dev/null +++ b/inc/scene.manager.go @@ -0,0 +1,61 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +type Scene = inkwell.Scene + +var SceneManager = NewManager(func(entity Scene) string { return entity.Name }) + +func registerScene() { + fillSelectorPins() + registerAll(SceneManager, func(entity Scene) { + World.G.SceneManager.Register(sceneDefaults(entity)) + }) +} + +var sceneFloor = []inkwell.Polygon{ + inkwell.Poly( + inkwell.Point{ + X: 16, + Y: 196, + }, inkwell.Point{ + X: 624, + Y: 196, + }, + inkwell.Point{ + X: 624, + Y: 258, + }, inkwell.Point{ + X: 16, + Y: 258, + }, + ), +} + +func sceneDefaults(s Scene) Scene { + if s.Actors == nil { + s.Actors = []inkwell.SceneActor{ + { + CharacterName: Paul, + At: inkwell.Point{ + X: 320, + Y: 232, + }, + }, + } + } + if s.Walkboxes == nil { + s.Walkboxes = sceneFloor + } + return s +} + +func setVarIfEmpty(name string, v any) inkwell.Action { + return Fn(func(ctx *inkwell.Ctx) { + if ctx.Game.State.Var(name) == nil { + ctx.Game.State.SetVar(name, v) + } + }) +} diff --git a/inc/scene.noodle_house.go b/inc/scene.noodle_house.go new file mode 100644 index 0000000..e88f4e0 --- /dev/null +++ b/inc/scene.noodle_house.go @@ -0,0 +1,21 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneNoodleHouse, + Title: "NOODLE'S HOUSE — SEALED", + Background: BgNoodleHouse, + Exits: []inkwell.Exit{ + exitToSelector, + { + To: SceneAlley, + Label: "the alley behind the house", + Side: inkwell.ExitRight, + }, + }, + }) +} diff --git a/inc/scene.norman_apartment.go b/inc/scene.norman_apartment.go new file mode 100644 index 0000000..cd9df4c --- /dev/null +++ b/inc/scene.norman_apartment.go @@ -0,0 +1,26 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneNormanApartment, + Title: "NORMAN'S APARTMENT", + Background: BgNormanApartment, + Exits: []inkwell.Exit{ + exitToSelector, + { + To: SceneRooftopHideout, + Label: "the stairs up to the roof", + Side: inkwell.ExitBack, + }, + { + To: SceneBBSTerminal, + Label: "Norman's terminal", + Side: inkwell.ExitRight, + }, + }, + }) +} diff --git a/inc/scene.paul_shop.go b/inc/scene.paul_shop.go new file mode 100644 index 0000000..fe69966 --- /dev/null +++ b/inc/scene.paul_shop.go @@ -0,0 +1,20 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: ScenePaulShop, + Title: "PAUL'S SHOP — JUNK AND GARAGE", + Background: BgPaulShop, + Exits: []inkwell.Exit{ + { + To: SceneNoodleHouse, + Label: "the bus to San Francisco", + Side: inkwell.ExitNear, + }, + }, + }) +} diff --git a/inc/scene.police_station.go b/inc/scene.police_station.go new file mode 100644 index 0000000..4398c5f --- /dev/null +++ b/inc/scene.police_station.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: ScenePoliceStation, + Title: "SFPD — STATION AND HOLDING", + Background: BgPoliceStation, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.public_bbs.go b/inc/scene.public_bbs.go new file mode 100644 index 0000000..fdb7d44 --- /dev/null +++ b/inc/scene.public_bbs.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: ScenePublicBBS, + Title: "PUBLIC BBS TERMINAL", + Background: BgPublicBBS, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.rooftop_hideout.go b/inc/scene.rooftop_hideout.go new file mode 100644 index 0000000..9bfb167 --- /dev/null +++ b/inc/scene.rooftop_hideout.go @@ -0,0 +1,25 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneRooftopHideout, + Title: "NORMAN'S ROOFTOP HIDEOUT", + Background: BgRooftopHideout, + Exits: []inkwell.Exit{ + { + To: SceneNormanApartment, + Label: "back down into the flat", + Side: inkwell.ExitNear, + }, + { + To: SceneBBSTerminal, + Label: "the old terminal", + Side: inkwell.ExitRight, + }, + }, + }) +} diff --git a/inc/scene.samizdat_press.go b/inc/scene.samizdat_press.go new file mode 100644 index 0000000..b9cf637 --- /dev/null +++ b/inc/scene.samizdat_press.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneSamizdatPress, + Title: "SAMIZDAT PRINTING HOUSE", + Background: BgSamizdatPress, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.scrap_market.go b/inc/scene.scrap_market.go new file mode 100644 index 0000000..7475331 --- /dev/null +++ b/inc/scene.scrap_market.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneScrapMarket, + Title: "SCRAP MARKET", + Background: BgScrapMarket, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.secret_club.go b/inc/scene.secret_club.go new file mode 100644 index 0000000..23a303c --- /dev/null +++ b/inc/scene.secret_club.go @@ -0,0 +1,25 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneSecretClub, + Title: "SECRET CLUB — THE UNDERWATER SUN", + Background: BgSecretClub, + Exits: []inkwell.Exit{ + { + To: SceneBBSTerminal, + Label: "the terminal in the corner", + Side: inkwell.ExitBack, + }, + { + To: SceneTrinketShop, + Label: "back out through the shop", + Side: inkwell.ExitNear, + }, + }, + }) +} diff --git a/inc/scene.secret_lab.go b/inc/scene.secret_lab.go new file mode 100644 index 0000000..96ca536 --- /dev/null +++ b/inc/scene.secret_lab.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneSecretLab, + Title: "SECRET RESEARCH LABORATORY", + Background: BgSecretLab, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/screen.selector.go b/inc/scene.selector.go similarity index 53% rename from inc/screen.selector.go rename to inc/scene.selector.go index bcfce9d..150540d 100644 --- a/inc/screen.selector.go +++ b/inc/scene.selector.go @@ -6,9 +6,15 @@ import ( inkwell "git.teletypegames.org/engines/inkwell" ) +var exitToSelector = inkwell.Exit{ + To: SceneSelector, + Label: "the rest of the city", + Side: inkwell.ExitNear, +} + func init() { - ScreenManager.Register(Screen{ - Name: ScreenSelector, + SceneManager.Register(Scene{ + Name: SceneSelector, Title: "SAN FRANCISCO", Background: BgSelector, Actors: []inkwell.SceneActor{}, @@ -17,23 +23,32 @@ func init() { } func fillSelectorPins() { - selector, ok := ScreenManager.GetByName(ScreenSelector) + selector, ok := SceneManager.GetByName(SceneSelector) if !ok { return } - var exits []exit - for _, entity := range ScreenManager.GetAll() { - if !entity.OnSelector { + var exits []inkwell.Exit + for _, entity := range SceneManager.GetAll() { + if !leadsToSelector(entity) { continue } - exits = append(exits, exit{ - to: entity.Name, - label: pinLabel(entity.Title), - area: pin(len(exits)), + exits = append(exits, inkwell.Exit{ + To: entity.Name, + Label: pinLabel(entity.Title), + Area: pin(len(exits)), }) } selector.Exits = exits - ScreenManager.Register(selector) + SceneManager.Register(selector) +} + +func leadsToSelector(s Scene) bool { + for _, e := range s.Exits { + if e.To == SceneSelector { + return true + } + } + return false } const ( diff --git a/inc/scene.server_farm.go b/inc/scene.server_farm.go new file mode 100644 index 0000000..09f43f9 --- /dev/null +++ b/inc/scene.server_farm.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneServerFarm, + Title: "SERVER FARM", + Background: BgServerFarm, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.showroom.go b/inc/scene.showroom.go new file mode 100644 index 0000000..d27cb31 --- /dev/null +++ b/inc/scene.showroom.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneShowroom, + Title: "NEUMATRONIC SHOWROOM", + Background: BgShowroom, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.small_restaurant.go b/inc/scene.small_restaurant.go new file mode 100644 index 0000000..58e80f4 --- /dev/null +++ b/inc/scene.small_restaurant.go @@ -0,0 +1,20 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneSmallRestaurant, + Title: "SMALL RESTAURANT — NEXT DOOR", + Background: BgSmallRestaurant, + Exits: []inkwell.Exit{ + { + To: SceneTrinketShop, + Label: "back to the trinket shop", + Side: inkwell.ExitLeft, + }, + }, + }) +} diff --git a/inc/scene.street.go b/inc/scene.street.go new file mode 100644 index 0000000..c918ba0 --- /dev/null +++ b/inc/scene.street.go @@ -0,0 +1,16 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneStreet, + Title: "STREET", + Background: BgStreet, + Exits: []inkwell.Exit{ + exitToSelector, + }, + }) +} diff --git a/inc/scene.trinket_shop.go b/inc/scene.trinket_shop.go new file mode 100644 index 0000000..b2c4853 --- /dev/null +++ b/inc/scene.trinket_shop.go @@ -0,0 +1,28 @@ +package inc + +import ( + inkwell "git.teletypegames.org/engines/inkwell" +) + +func init() { + SceneManager.Register(Scene{ + Name: SceneTrinketShop, + Title: "CHINATOWN — TRINKET SHOP", + Background: BgTrinketShop, + Exits: []inkwell.Exit{ + exitToSelector, + { + To: SceneSmallRestaurant, + Label: "the eating place next door", + Side: inkwell.ExitRight, + }, + { + To: SceneSecretClub, + Label: "the way in at the back", + Side: inkwell.ExitBack, + Needs: FlagClubEntry, + Blocked: inkwell.Say(Paul, "Just a shop, as far as the man behind the counter is concerned."), + }, + }, + }) +} diff --git a/inc/screen.bbs_terminal.go b/inc/screen.bbs_terminal.go deleted file mode 100644 index fd8073f..0000000 --- a/inc/screen.bbs_terminal.go +++ /dev/null @@ -1,15 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenBBSTerminal, - Title: "TERMINAL — BBS ACCESS POINT", - Background: BgBBSTerminal, - Exits: []exit{ - { - label: "step back from the terminal", - side: sideNear, - }, - }, - }) -} diff --git a/inc/screen.bvk_branch.go b/inc/screen.bvk_branch.go deleted file mode 100644 index bb80f2f..0000000 --- a/inc/screen.bvk_branch.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenBVKBranch, - Title: "BVK — SAN FRANCISCO BRANCH", - Background: BgBVKBranch, - OnSelector: true, - }) -} diff --git a/inc/screen.columbarium.go b/inc/screen.columbarium.go deleted file mode 100644 index 62155ea..0000000 --- a/inc/screen.columbarium.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenColumbarium, - Title: "COLUMBARIUM — DEX'S MEMORIAL", - Background: BgColumbarium, - OnSelector: true, - }) -} diff --git a/inc/screen.curator_shop.go b/inc/screen.curator_shop.go deleted file mode 100644 index e227dc9..0000000 --- a/inc/screen.curator_shop.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenCuratorShop, - Title: "CURATOR SERVICE — THE MASTER'S WORKSHOP", - Background: BgCuratorShop, - OnSelector: true, - }) -} diff --git a/inc/screen.exit.go b/inc/screen.exit.go deleted file mode 100644 index 059b39b..0000000 --- a/inc/screen.exit.go +++ /dev/null @@ -1,76 +0,0 @@ -package inc - -import ( - inkwell "git.teletypegames.org/engines/inkwell" -) - -type side int - -const ( - sideLeft side = iota - sideRight - sideBack - sideNear -) - -func (s side) area() inkwell.Shape { - switch s { - case sideLeft: - return inkwell.Rect(0, 40, 56, 212) - case sideRight: - return inkwell.Rect(584, 40, 56, 212) - case sideBack: - return inkwell.Rect(232, 28, 176, 84) - default: - return inkwell.Rect(232, 214, 176, 48) - } -} - -type exit struct { - to string - label string - side side - - area inkwell.Shape - - needs string - blocked string -} - -func toSelector() exit { - return exit{ - to: ScreenSelector, - label: "the rest of the city", - side: sideNear, - } -} - -func exitName(to string) string { - if to == "" { - return "exit:back" - } - return "exit:" + to -} - -func (e exit) hotspot() inkwell.Hotspot { - var travel inkwell.Action = inkwell.GoTo(e.to) - if e.to == "" { - travel = Back() - } - if e.needs != "" { - travel = inkwell.If(inkwell.Flag(e.needs), travel, inkwell.Say(Paul, e.blocked)) - } - area := e.area - if area == nil { - area = e.side.area() - } - return inkwell.Hotspot{ - Name: exitName(e.to), - Label: e.label, - Area: area, - Cursor: inkwell.CursorExit, - OnLook: inkwell.Say(Paul, "That way: "+e.label+"."), - OnUse: travel, - OnTake: inkwell.Say(Paul, "It's a way out, not a thing."), - } -} diff --git a/inc/screen.hackerspace.go b/inc/screen.hackerspace.go deleted file mode 100644 index d8d4f00..0000000 --- a/inc/screen.hackerspace.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenHackerspace, - Title: "HACKERSPACE", - Background: BgHackerspace, - OnSelector: true, - }) -} diff --git a/inc/screen.hospital.go b/inc/screen.hospital.go deleted file mode 100644 index cbdeea1..0000000 --- a/inc/screen.hospital.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenHospital, - Title: "HOSPITAL — PSYCHIATRIC WING", - Background: BgHospital, - OnSelector: true, - }) -} diff --git a/inc/screen.ice_cream_shop.go b/inc/screen.ice_cream_shop.go deleted file mode 100644 index 2c9d4dc..0000000 --- a/inc/screen.ice_cream_shop.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenIceCreamShop, - Title: "ICE CREAM SHOP — WHERE THE BAR WAS", - Background: BgIceCreamShop, - OnSelector: true, - }) -} diff --git a/inc/screen.manager.go b/inc/screen.manager.go deleted file mode 100644 index 869ef8b..0000000 --- a/inc/screen.manager.go +++ /dev/null @@ -1,99 +0,0 @@ -package inc - -import ( - inkwell "git.teletypegames.org/engines/inkwell" -) - -type Screen struct { - Name string - Title string - Background string - - Exits []exit - - OnSelector bool - - Hotspots []inkwell.Hotspot - Actors []inkwell.SceneActor - Walkboxes []inkwell.Polygon - OnEnter inkwell.Action -} - -var ScreenManager = NewManager(func(entity Screen) string { return entity.Name }) - -func registerScreen() { - fillSelectorPins() - registerAll(ScreenManager, func(entity Screen) { - World.G.SceneManager.Register(screenBuild(entity)) - }) -} - -var screenFloor = []inkwell.Polygon{ - inkwell.Poly( - inkwell.Point{ - X: 16, - Y: 196, - }, inkwell.Point{ - X: 624, - Y: 196, - }, - inkwell.Point{ - X: 624, - Y: 258, - }, inkwell.Point{ - X: 16, - Y: 258, - }, - ), -} - -func screenBuild(s Screen) inkwell.Scene { - exits := s.Exits - if s.OnSelector { - exits = append(exits, toSelector()) - } - hotspots := make([]inkwell.Hotspot, 0, len(exits)+len(s.Hotspots)) - hotspots = append(hotspots, s.Hotspots...) - for _, e := range exits { - hotspots = append(hotspots, e.hotspot()) - } - - actors := s.Actors - if actors == nil { - actors = []inkwell.SceneActor{ - { - CharacterName: Paul, - At: inkwell.Point{ - X: 320, - Y: 232, - }, - }, - } - } - walkboxes := s.Walkboxes - if walkboxes == nil { - walkboxes = screenFloor - } - onEnter := inkwell.Action(EnterScene(s.Name)) - if s.OnEnter != nil { - onEnter = inkwell.Seq(onEnter, s.OnEnter) - } - - return inkwell.Scene{ - Name: s.Name, - Title: s.Title, - Background: s.Background, - Actors: actors, - Walkboxes: walkboxes, - Hotspots: hotspots, - OnEnter: onEnter, - } -} - -func setVarIfEmpty(name string, v any) inkwell.Action { - return Fn(func(ctx *inkwell.Ctx) { - if ctx.Game.State.Var(name) == nil { - ctx.Game.State.SetVar(name, v) - } - }) -} diff --git a/inc/screen.noodle_house.go b/inc/screen.noodle_house.go deleted file mode 100644 index 84910d1..0000000 --- a/inc/screen.noodle_house.go +++ /dev/null @@ -1,17 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenNoodleHouse, - Title: "NOODLE'S HOUSE — SEALED", - Background: BgNoodleHouse, - OnSelector: true, - Exits: []exit{ - { - to: ScreenAlley, - label: "the alley behind the house", - side: sideRight, - }, - }, - }) -} diff --git a/inc/screen.norman_apartment.go b/inc/screen.norman_apartment.go deleted file mode 100644 index d52c1c9..0000000 --- a/inc/screen.norman_apartment.go +++ /dev/null @@ -1,22 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenNormanApartment, - Title: "NORMAN'S APARTMENT", - Background: BgNormanApartment, - OnSelector: true, - Exits: []exit{ - { - to: ScreenRooftopHideout, - label: "the stairs up to the roof", - side: sideBack, - }, - { - to: ScreenBBSTerminal, - label: "Norman's terminal", - side: sideRight, - }, - }, - }) -} diff --git a/inc/screen.paul_shop.go b/inc/screen.paul_shop.go deleted file mode 100644 index ec06f44..0000000 --- a/inc/screen.paul_shop.go +++ /dev/null @@ -1,16 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenPaulShop, - Title: "PAUL'S SHOP — JUNK AND GARAGE", - Background: BgPaulShop, - Exits: []exit{ - { - to: ScreenNoodleHouse, - label: "the bus to San Francisco", - side: sideNear, - }, - }, - }) -} diff --git a/inc/screen.police_station.go b/inc/screen.police_station.go deleted file mode 100644 index 06dbdd7..0000000 --- a/inc/screen.police_station.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenPoliceStation, - Title: "SFPD — STATION AND HOLDING", - Background: BgPoliceStation, - OnSelector: true, - }) -} diff --git a/inc/screen.public_bbs.go b/inc/screen.public_bbs.go deleted file mode 100644 index e91c673..0000000 --- a/inc/screen.public_bbs.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenPublicBBS, - Title: "PUBLIC BBS TERMINAL", - Background: BgPublicBBS, - OnSelector: true, - }) -} diff --git a/inc/screen.rooftop_hideout.go b/inc/screen.rooftop_hideout.go deleted file mode 100644 index 6cccb37..0000000 --- a/inc/screen.rooftop_hideout.go +++ /dev/null @@ -1,21 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenRooftopHideout, - Title: "NORMAN'S ROOFTOP HIDEOUT", - Background: BgRooftopHideout, - Exits: []exit{ - { - to: ScreenNormanApartment, - label: "back down into the flat", - side: sideNear, - }, - { - to: ScreenBBSTerminal, - label: "the old terminal", - side: sideRight, - }, - }, - }) -} diff --git a/inc/screen.samizdat_press.go b/inc/screen.samizdat_press.go deleted file mode 100644 index 6f9a715..0000000 --- a/inc/screen.samizdat_press.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenSamizdatPress, - Title: "SAMIZDAT PRINTING HOUSE", - Background: BgSamizdatPress, - OnSelector: true, - }) -} diff --git a/inc/screen.scrap_market.go b/inc/screen.scrap_market.go deleted file mode 100644 index 60f82d3..0000000 --- a/inc/screen.scrap_market.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenScrapMarket, - Title: "SCRAP MARKET", - Background: BgScrapMarket, - OnSelector: true, - }) -} diff --git a/inc/screen.secret_club.go b/inc/screen.secret_club.go deleted file mode 100644 index e4ec784..0000000 --- a/inc/screen.secret_club.go +++ /dev/null @@ -1,21 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenSecretClub, - Title: "SECRET CLUB — THE UNDERWATER SUN", - Background: BgSecretClub, - Exits: []exit{ - { - to: ScreenBBSTerminal, - label: "the terminal in the corner", - side: sideBack, - }, - { - to: ScreenTrinketShop, - label: "back out through the shop", - side: sideNear, - }, - }, - }) -} diff --git a/inc/screen.secret_lab.go b/inc/screen.secret_lab.go deleted file mode 100644 index 98679a3..0000000 --- a/inc/screen.secret_lab.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenSecretLab, - Title: "SECRET RESEARCH LABORATORY", - Background: BgSecretLab, - OnSelector: true, - }) -} diff --git a/inc/screen.server_farm.go b/inc/screen.server_farm.go deleted file mode 100644 index d1cac94..0000000 --- a/inc/screen.server_farm.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenServerFarm, - Title: "SERVER FARM", - Background: BgServerFarm, - OnSelector: true, - }) -} diff --git a/inc/screen.showroom.go b/inc/screen.showroom.go deleted file mode 100644 index a9f0ded..0000000 --- a/inc/screen.showroom.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenShowroom, - Title: "NEUMATRONIC SHOWROOM", - Background: BgShowroom, - OnSelector: true, - }) -} diff --git a/inc/screen.small_restaurant.go b/inc/screen.small_restaurant.go deleted file mode 100644 index 8b4d0b7..0000000 --- a/inc/screen.small_restaurant.go +++ /dev/null @@ -1,16 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenSmallRestaurant, - Title: "SMALL RESTAURANT — NEXT DOOR", - Background: BgSmallRestaurant, - Exits: []exit{ - { - to: ScreenTrinketShop, - label: "back to the trinket shop", - side: sideLeft, - }, - }, - }) -} diff --git a/inc/screen.street.go b/inc/screen.street.go deleted file mode 100644 index 58f4b02..0000000 --- a/inc/screen.street.go +++ /dev/null @@ -1,10 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenStreet, - Title: "STREET", - Background: BgStreet, - OnSelector: true, - }) -} diff --git a/inc/screen.trinket_shop.go b/inc/screen.trinket_shop.go deleted file mode 100644 index f05126a..0000000 --- a/inc/screen.trinket_shop.go +++ /dev/null @@ -1,24 +0,0 @@ -package inc - -func init() { - ScreenManager.Register(Screen{ - Name: ScreenTrinketShop, - Title: "CHINATOWN — TRINKET SHOP", - Background: BgTrinketShop, - OnSelector: true, - Exits: []exit{ - { - to: ScreenSmallRestaurant, - label: "the eating place next door", - side: sideRight, - }, - { - to: ScreenSecretClub, - label: "the way in at the back", - side: sideBack, - needs: FlagClubEntry, - blocked: "Just a shop, as far as the man behind the counter is concerned.", - }, - }, - }) -} diff --git a/inc/ui.manager.go b/inc/ui.manager.go index 4a166d7..baa8d9d 100644 --- a/inc/ui.manager.go +++ b/inc/ui.manager.go @@ -36,8 +36,8 @@ func registerUI() { g.UIManager.Register(&actionPump{ Name: "pump", }) - g.UIManager.Register(&screenNav{ - Name: "screen_nav", + g.UIManager.Register(&sceneNav{ + Name: "scene_nav", }) g.UIManager.Register(&windowSizer{ Name: "window", diff --git a/inc/ui.screen_nav.go b/inc/ui.scene_nav.go similarity index 67% rename from inc/ui.screen_nav.go rename to inc/ui.scene_nav.go index df19f9e..9217872 100644 --- a/inc/ui.screen_nav.go +++ b/inc/ui.scene_nav.go @@ -6,14 +6,14 @@ import ( "github.com/hajimehoshi/ebiten/v2/inpututil" ) -type screenNav struct { +type sceneNav struct { Name string } -func (n *screenNav) GetName() string { return n.Name } -func (n *screenNav) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {} +func (n *sceneNav) GetName() string { return n.Name } +func (n *sceneNav) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {} -func (n *screenNav) Tick(ctx *inkwell.UICtx) { +func (n *sceneNav) Tick(ctx *inkwell.UICtx) { if !World.HUDVisible() || World.Paused() { return } @@ -32,13 +32,13 @@ func (n *screenNav) Tick(ctx *inkwell.UICtx) { } } -func (n *screenNav) neighbour(g *inkwell.Game, step int) string { +func (n *sceneNav) neighbour(g *inkwell.Game, step int) string { deck := g.SceneManager.Names() if len(deck) < 2 { return "" } for i, name := range deck { - if name == World.Scene() { + if name == World.G.CurrentScene() { return deck[((i+step)%len(deck)+len(deck))%len(deck)] } } diff --git a/inc/world.action.go b/inc/world.action.go index 422c9e7..4dfc528 100644 --- a/inc/world.action.go +++ b/inc/world.action.go @@ -32,7 +32,7 @@ func (w *world) PumpTick(dt float64) { Game: w.G, DT: dt, } - if s, ok := w.G.SceneManager.Get(w.scene); ok { + if s, ok := w.G.SceneManager.Get(w.G.CurrentScene()); ok { ctx.Scene = &s } if w.running.Tick(ctx) != inkwell.StatusRunning { @@ -41,7 +41,7 @@ func (w *world) PumpTick(dt float64) { } func (w *world) sceneTitle() string { - s, ok := w.G.SceneManager.Get(w.scene) + s, ok := w.G.SceneManager.Get(w.G.CurrentScene()) if !ok { return "" } @@ -88,24 +88,6 @@ func SetMode(m Mode) inkwell.Action { return Fn(func(*inkwell.Ctx) { World.SetMode(m) }) } -func EnterScene(name string) inkwell.Action { - return Fn(func(*inkwell.Ctx) { - if name != World.scene { - World.prev = World.scene - } - World.scene = name - }) -} - -func Back() inkwell.Action { - return Fn(func(ctx *inkwell.Ctx) { - if World.prev == "" { - return - } - inkwell.GoTo(World.prev).Start().Tick(ctx) - }) -} - func TapeSay(speaker, text string) inkwell.Action { return &tapeSayAction{ speaker: speaker, diff --git a/inc/world.manager.go b/inc/world.manager.go index 151c52d..8a95486 100644 --- a/inc/world.manager.go +++ b/inc/world.manager.go @@ -17,8 +17,6 @@ type world struct { mode Mode - scene string - prev string paused bool pending string queue []inkwell.Action @@ -34,8 +32,6 @@ var World = &world{} func (w *world) attach(g *inkwell.Game) { w.G = g w.mode = ModePlay - w.scene = "" - w.prev = "" w.paused = false w.pending = "" w.queue = nil @@ -51,10 +47,6 @@ func (w *world) SetMode(m Mode) { w.mode = m } func (w *world) HUDVisible() bool { return w.mode == ModePlay } -func (w *world) Scene() string { return w.scene } - -func (w *world) Previous() string { return w.prev } - func (w *world) Paused() bool { return w.paused } func (w *world) SetTopBar(t *inkwell.TopBar) { w.top = t } diff --git a/main.go b/main.go index c8d02fd..6f7f572 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,7 @@ func init() { inkwell.AssetFS = assets } func main() { var o inc.Opts - flag.StringVar(&o.Screen, "screen", "", "starting screen (empty: the alley)") + flag.StringVar(&o.Scene, "scene", "", "starting scene (empty: the alley)") flag.BoolVar(&o.Finale, "finale", false, "start with the finale, to try the Nokia-punk theme switch") flag.Parse()