@@ -45,71 +45,72 @@ This holds for nested literals too, including small ones such as
|
||||
|
||||
## Layout
|
||||
|
||||
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`.
|
||||
One category, one package, one directory. A file keeps the category in its own
|
||||
name anyway — `[category].[name].go` inside `inc/[category]/` — because the
|
||||
prefix is what makes a file findable in a list of editor tabs, a grep, or a
|
||||
diff, where the directory has already fallen off.
|
||||
|
||||
- The category is always **singular**: `item`, `scene`, `background`,
|
||||
`character`, `tape`, `dialog`, `script`, `world`, `widget`, `theme`, `names`.
|
||||
- `[category].manager.go` is the file that ties a category together — its
|
||||
entity type and whatever else the category shares.
|
||||
- Every other file in a category holds exactly one entity: one scene, one
|
||||
`character`, `tape`, `dialog`, `script`, `world`, `widget`, `theme`.
|
||||
- `[category].manager.go` is the file that ties a package together — its entity
|
||||
type, its `Manager`, and whatever else the category shares.
|
||||
- Every other file in a package holds exactly one entity: one scene, one
|
||||
background, one item. The file registers it itself, in an `init()`.
|
||||
- `boot.go` is the exception that has no category: it declares every manager
|
||||
and builds the game.
|
||||
- Two files have no category. `inc/constants.go` is the vocabulary every
|
||||
package imports, and `inc/boot/boot.go` builds the game.
|
||||
|
||||
```
|
||||
main.go flags + inkwell.Run
|
||||
inc/boot.go the managers; New(Opts) builds the game
|
||||
inc/names.manager.go entity names and world-state keys
|
||||
inc/theme.manager.go the Theme alias and the colour helpers
|
||||
inc/theme.realworld.go realworld-93
|
||||
inc/theme.nokia_punk.go nokia-punk
|
||||
inc/world.manager.go unsaved runtime state
|
||||
inc/world.action.go custom actions
|
||||
inc/widget.manager.go the Widget alias, HUD layout, the shared conditions
|
||||
inc/widget.*.go one widget per file, registering itself
|
||||
inc/background.*.go one image asset per scene
|
||||
inc/character.*.go the cast, tapes included
|
||||
inc/tape.manager.go the Tape entity and the lookups over it
|
||||
inc/tape.*.go one tape per file
|
||||
inc/item.*.go inventory
|
||||
inc/dialog.*.go dialogue trees
|
||||
inc/script.*.go named action sequences
|
||||
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
|
||||
main.go flags + inkwell.Run
|
||||
inc/constants.go entity names and world-state keys
|
||||
inc/boot/boot.go New(Opts) builds the game
|
||||
inc/theme/theme.manager.go the Theme alias, its Manager, RGB/RGBA
|
||||
inc/theme/theme.realworld.go realworld-93
|
||||
inc/theme/theme.nokia_punk.go nokia-punk
|
||||
inc/world/world.manager.go unsaved runtime state
|
||||
inc/world/world.action.go custom actions
|
||||
inc/tape/tape.manager.go the Tape entity and the lookups over it
|
||||
inc/tape/tape.*.go one tape per file
|
||||
inc/widget/widget.manager.go the Widget alias, HUD layout, the conditions
|
||||
inc/widget/widget.*.go one widget per file, registering itself
|
||||
inc/background/background.*.go one image asset per scene
|
||||
inc/character/character.*.go the cast, tapes included
|
||||
inc/item/item.*.go inventory
|
||||
inc/dialog/dialog.*.go dialogue trees
|
||||
inc/script/script.*.go named action sequences
|
||||
inc/scene/scene.manager.go the Scene alias, its Manager, the floor
|
||||
inc/scene/scene.selector.go the map screen: pins derived from the graph
|
||||
inc/scene/scene.*.go one file per scene
|
||||
```
|
||||
|
||||
`inc` is constants and nothing else, so every package can import it and it can
|
||||
import none of them. That is also why `New` sits in `inc/boot` rather than in
|
||||
`inc`: a package cannot be imported by what it imports, and the assembly is the
|
||||
one thing that has to name every package at once.
|
||||
|
||||
## Managers
|
||||
|
||||
Every category that owns a collection of entities has a manager, and they are
|
||||
all the engine's own `inkwell.Manager[T]` — the same registry type the `*Game`
|
||||
hangs its content off. The game defines no registry of its own.
|
||||
|
||||
All nine are declared together, in `boot.go`, so the list of what the game
|
||||
holds is one block rather than a line hidden in each category file:
|
||||
Each one is declared in its own package's manager file, beside the alias it
|
||||
holds, and it needs no prefix because the package already is one:
|
||||
|
||||
```go
|
||||
var (
|
||||
BackgroundManager = inkwell.NewManager[Background]()
|
||||
CharacterManager = inkwell.NewManager[Character]()
|
||||
DialogManager = inkwell.NewManager[Dialog]()
|
||||
ItemManager = inkwell.NewManager[Item]()
|
||||
SceneManager = inkwell.NewManager[Scene]()
|
||||
ScriptManager = inkwell.NewManager[Script]()
|
||||
TapeManager = inkwell.NewManager[Tape]()
|
||||
ThemeManager = inkwell.NewManager[Theme]()
|
||||
WidgetManager = inkwell.NewManager[Widget]()
|
||||
)
|
||||
```
|
||||
// inc/character/character.manager.go
|
||||
package character
|
||||
|
||||
The entity types stay in their own category files, one alias each, and that is
|
||||
all a manager file holds now:
|
||||
|
||||
```go
|
||||
type Character = inkwell.Character
|
||||
|
||||
var Manager = inkwell.NewManager[Character]()
|
||||
```
|
||||
|
||||
Read from `inc/boot` the nine of them still line up as a list —
|
||||
`background.Manager`, `character.Manager`, `dialog.Manager`, `item.Manager`,
|
||||
`scene.Manager`, `script.Manager`, `tape.Manager`, `theme.Manager`,
|
||||
`widget.Manager` — only now the list is a consequence of the imports rather
|
||||
than a block someone has to keep in step.
|
||||
|
||||
Aliases of engine structs already carry `GetName()` and satisfy
|
||||
`inkwell.Named`, which is the whole of what a manager asks of them.
|
||||
|
||||
@@ -126,8 +127,8 @@ the engine, so there is nothing left for a second type to hold.
|
||||
`Tape` is the exception, and it is a real one: a tape is a cassette that speaks,
|
||||
a thing inkwell has no notion of. It names the character whose voice it is, the
|
||||
item that carries it and the dialogue it plays, and `tape.manager.go` holds the
|
||||
four lookups over the registry — `IsTape`, `TapeOf`, `IsTapeItem`,
|
||||
`TapeDialogue`. What a tape *sounds* like is not in it: the display name and the
|
||||
four lookups over the registry — `tape.Is`, `tape.Of`, `tape.IsItem`,
|
||||
`tape.Dialogue`. What a tape *sounds* like is not in it: the display name and the
|
||||
log-only voice are `Character.Label` and `Character.Voice`, because those are
|
||||
facts about a speaker, not about a cassette.
|
||||
|
||||
@@ -138,11 +139,11 @@ somewhere else to keep in step — the file hands itself to its manager in an
|
||||
`init()`:
|
||||
|
||||
```go
|
||||
package inc
|
||||
package background
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgServerFarm,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgServerFarm,
|
||||
Path: "assets/bg/server_farm.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -151,13 +152,18 @@ func init() {
|
||||
|
||||
Adding an entity is adding a file. Deleting one is deleting a file. Package-level
|
||||
variables are initialised before any `init()` runs, whatever file each sits in,
|
||||
so the managers in `boot.go` exist by the time the first entity file registers
|
||||
into one.
|
||||
so a package's `Manager` exists by the time its first entity 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 scenes,
|
||||
which is simply the order the files sit in.
|
||||
|
||||
An `init()` only runs if something imports the package. `inc/boot` names eight
|
||||
of the nine for their `Manager`, which is import enough; `tape` is the one
|
||||
nobody names, so it is there as a blank import. That list is **per package, not
|
||||
per entity** — a new scene file still touches nothing but itself.
|
||||
|
||||
### Widgets name their layer instead of their order
|
||||
|
||||
A widget is a file like any other entity — `widget.<name>.go`, one widget,
|
||||
@@ -166,7 +172,7 @@ which the game registers as literals the same way it registers a background:
|
||||
|
||||
```go
|
||||
func init() {
|
||||
WidgetManager.Register(&inkwell.Cursor{
|
||||
Manager.Register(&inkwell.Cursor{
|
||||
Name: "cursor",
|
||||
})
|
||||
}
|
||||
@@ -193,7 +199,7 @@ hidden for a cutscene, and that is a condition over game state, not a wrapper
|
||||
and not an `if` at the top of every `Draw`:
|
||||
|
||||
```go
|
||||
WidgetManager.Register(&inkwell.StatusLine{
|
||||
Manager.Register(&inkwell.StatusLine{
|
||||
Name: "status",
|
||||
When: whenPlaying,
|
||||
Y: statusY,
|
||||
@@ -201,7 +207,7 @@ WidgetManager.Register(&inkwell.StatusLine{
|
||||
```
|
||||
|
||||
`whenPlaying`, `whenCutscene` and `whenUnpaused` are in `widget.manager.go`, and
|
||||
they read `VarMode` and `VarNote` out of the engine's own `State`. A widget of
|
||||
they read `inc.VarMode` and `inc.VarNote` out of the engine's own `State`. A widget of
|
||||
ours says the same thing with a method — `VisibleWhen() inkwell.Condition` —
|
||||
because it has no literal to put a field in. A widget that is switched off
|
||||
neither ticks nor draws nor blocks a click, so nothing else has to ask.
|
||||
@@ -213,14 +219,14 @@ hands ours over in their place — the types are identical, so the engine and th
|
||||
game end up sharing one registry per category rather than two in step:
|
||||
|
||||
```go
|
||||
g.AssetManager = BackgroundManager
|
||||
g.CharacterManager = CharacterManager
|
||||
g.DialogueManager = DialogManager
|
||||
g.ItemManager = ItemManager
|
||||
g.SceneManager = SceneManager
|
||||
g.ScriptManager = ScriptManager
|
||||
g.WidgetManager = WidgetManager
|
||||
ThemeManager.Each(g.ThemeManager.Register)
|
||||
g.AssetManager = background.Manager
|
||||
g.CharacterManager = character.Manager
|
||||
g.DialogueManager = dialog.Manager
|
||||
g.ItemManager = item.Manager
|
||||
g.SceneManager = scene.Manager
|
||||
g.ScriptManager = script.Manager
|
||||
g.WidgetManager = widget.Manager
|
||||
theme.Manager.Each(g.ThemeManager.Register)
|
||||
```
|
||||
|
||||
Themes are the odd one out and stay a copy: `NewGame` puts four preset themes
|
||||
@@ -241,14 +247,14 @@ saying "the usual", and the selector opts out by declaring both empty.
|
||||
### What runs at boot
|
||||
|
||||
`New` names two scripts and nothing else — the opening a player sees is content
|
||||
like every other script, in `script.opening.go`, not a slice built in the
|
||||
like every other script, in `script/script.opening.go`, not a slice built in the
|
||||
wiring:
|
||||
|
||||
```go
|
||||
g.StartAt(start)
|
||||
g.OnStart(ScriptOpening)
|
||||
g.OnStart(inc.ScriptOpening)
|
||||
if o.Finale {
|
||||
g.OnFinale(ScriptFinale)
|
||||
g.OnFinale(inc.ScriptFinale)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -261,60 +267,64 @@ something this package used to carry itself:
|
||||
|
||||
```go
|
||||
g.WindowScale = 2
|
||||
g.Player = Paul
|
||||
g.Walkboxes = sceneFloor
|
||||
g.UseWithFail = useWithFail
|
||||
g.Player = inc.Paul
|
||||
g.Walkboxes = scene.Floor
|
||||
g.UseWithFail = script.UseWithFail
|
||||
```
|
||||
|
||||
`UseWithFail` is the response to a use-with pair nobody authored — the engine
|
||||
asks for it the same way it asks for `ExitLook` and `ExitTake`, and the lines
|
||||
live with the rest of the writing, in `script.usewith_fail.go`.
|
||||
live with the rest of the writing, in `script/script.usewith_fail.go`.
|
||||
|
||||
## The world
|
||||
|
||||
There is exactly one game, so there is exactly one world: `World`, a
|
||||
package-level singleton in `world.manager.go`. Nothing takes a `*world`
|
||||
parameter and no widget holds a back-reference — `World.Do(…)`, `World.Mode()`,
|
||||
`World.Slot2()` are reachable from anywhere in the package. `New` calls
|
||||
`World.attach(g)`, which binds the engine and resets the runtime state, so
|
||||
building the game twice is clean.
|
||||
There is exactly one game, so there is exactly one world — and since there is
|
||||
exactly one, the **package is the singleton**. There is no `World` value to pass
|
||||
around and no back-reference for a widget to hold: `world.Do(…)`,
|
||||
`world.Slot2()`, `world.SetPending(…)` are reachable from anywhere that imports
|
||||
`world`. `New` calls `world.Attach(g)`, which binds the engine and resets the
|
||||
run state, so building the game twice is clean.
|
||||
|
||||
`World` holds as little as it can get away with. The mode and the top bar's
|
||||
note are `State` vars (`VarMode`, `VarNote`), because state the engine can see
|
||||
is state a `Condition` can read — that is what makes a widget's `When` possible
|
||||
and what puts "— paused" in the top bar without anyone pushing it there.
|
||||
`World.Do` hands its action to `g.Do`, the engine's queue, so the game runs one
|
||||
action at a time without a pump of its own. What is left in the struct is the
|
||||
two things the engine has no notion of: the tape waiting to speak, and the
|
||||
cassette on its way into slot 2.
|
||||
`world` holds as little as it can get away with. The mode and the top bar's note
|
||||
are `State` vars (`inc.VarMode`, `inc.VarNote`), because state the engine can
|
||||
see is state a `Condition` can read — that is what makes a widget's `When`
|
||||
possible and what puts "— paused" in the top bar without anyone pushing it
|
||||
there. `world.Do` hands its action to `g.Do`, the engine's queue, so the game
|
||||
runs one action at a time without a pump of its own. What is left in package
|
||||
variables is the two things the engine has no notion of: the tape waiting to
|
||||
speak, and the cassette on its way into slot 2. Only `world.Attach` resets them.
|
||||
|
||||
This is what lets an entity file be a literal: the tape-insert script closes
|
||||
over `World`, not over a parameter it would have had to be handed.
|
||||
over the `world` package, not over a parameter it would have had to be handed.
|
||||
|
||||
## Naming
|
||||
|
||||
One package means one namespace, so an entity's constructor carries its
|
||||
category as a prefix:
|
||||
The package is the namespace now, so an identifier never repeats what the
|
||||
package already says. It is `scene.Floor`, not `scene.SceneFloor`;
|
||||
`tape.Dialogue`, not `tape.TapeDialogue`; `widget.Manager`, not
|
||||
`widget.WidgetManager`; `world.Do`, not `world.WorldDo`. Read the call site, not
|
||||
the declaration, when choosing a name:
|
||||
|
||||
```go
|
||||
sceneFloor fillSelectorPins tapeSlots useWithFail
|
||||
scene.FillSelectorPins() tape.Is(speaker) world.Do(a) widget.ScreenW
|
||||
```
|
||||
|
||||
Entities themselves need no name at all — they are anonymous literals inside
|
||||
their file's `init()`, and the file name says which one it is.
|
||||
|
||||
Exported names are the authoring vocabulary — what a content file spells out:
|
||||
`New` and `Opts`, `World`, the managers and the entity types they hold, the
|
||||
constants in `names.manager.go`, the colour tokens, the tape lookups
|
||||
(`IsTape`, `TapeOf`, `IsTapeItem`, `TapeDialogue`) and the action constructors
|
||||
(`Paused`, `SetMode`, `UseTheme`, `TapeOffer`, `Fn`). A tape's line is
|
||||
`inkwell.Say` like anyone else's — the tape voice is on the character, not on a
|
||||
second spelling of Say.
|
||||
`boot.New` and `boot.Opts`, the constants in `inc/constants.go`, each package's
|
||||
`Manager` and entity type, the colour tokens, the tape lookups (`tape.Is`,
|
||||
`tape.Of`, `tape.IsItem`, `tape.Dialogue`), the world (`world.Do`,
|
||||
`world.Slot2`, …) and the action constructors (`world.Paused`, `world.SetMode`,
|
||||
`world.UseTheme`, `world.TapeOffer`, `world.Fn`). A tape's line is `inkwell.Say`
|
||||
like anyone else's — the tape voice is on the character, not on a second
|
||||
spelling of Say.
|
||||
|
||||
Everything else is machinery and stays unexported: the HUD widgets
|
||||
(`tapeSlots`, `letterbox`, `hudFrame`, …), the conditions (`whenPlaying`,
|
||||
`whenCutscene`, `whenUnpaused`), the runners, `useWithFail`,
|
||||
`fillSelectorPins`.
|
||||
Everything else stays unexported, and now the compiler holds the line: the HUD
|
||||
widgets (`tapeSlots`, `letterbox`, `hudFrame`, …), the conditions
|
||||
(`whenPlaying`, `whenCutscene`, `whenUnpaused`), the runners, `setMode`,
|
||||
`setNote`, `setVarIfEmpty`.
|
||||
|
||||
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
|
||||
@@ -323,23 +333,25 @@ display: `ScreenW`, `ScreenH`.
|
||||
|
||||
## Layering
|
||||
|
||||
Nothing is enforced by the compiler any more, so the layering is a rule kept by
|
||||
hand:
|
||||
The layering is the import graph, so the compiler keeps it:
|
||||
|
||||
```
|
||||
names ← theme ← world ← widget
|
||||
↑ ↑
|
||||
content ───┴── boot ← main
|
||||
inc ← theme ← world ← tape ← widget ← boot ← main
|
||||
↑ ↑ ↑
|
||||
└── content ───────────────────-┘
|
||||
```
|
||||
|
||||
`world` knows nothing about the HUD or the content. Both build on it, never the
|
||||
other way round.
|
||||
`inc` imports nothing and everything imports it. `world` knows nothing about the
|
||||
HUD or the content; both build on it, never the other way round — and an arrow
|
||||
pointing back is now an import cycle, not a review comment. The one edge worth
|
||||
knowing is `widget → tape`: the tape slots ask which cassette a tape is in, so
|
||||
the tape concept sits below the HUD rather than beside it.
|
||||
|
||||
## Adding a scene
|
||||
|
||||
1. Constants in `inc/names.manager.go`: `Scene<Name>`, `Bg<Name>`
|
||||
2. `inc/scene.<name>.go` — an `init()` registering a `Scene`
|
||||
3. `inc/background.<name>.go` — an `init()` registering a `Background`
|
||||
1. Constants in `inc/constants.go`: `Scene<Name>`, `Bg<Name>`
|
||||
2. `inc/scene/scene.<name>.go` — an `init()` registering a `Scene`
|
||||
3. `inc/background/background.<name>.go` — an `init()` registering a `Background`
|
||||
4. A 640×380 PNG in `assets/bg/`
|
||||
|
||||
Nothing else moves. There is no list to update.
|
||||
|
||||
@@ -110,7 +110,7 @@ Every pixel it gives back is a pixel of art.
|
||||
```
|
||||
|
||||
Every vertical measurement derives from `LineH` (glyph cell + leading) and from
|
||||
`ScreenH`, both in `widget.manager.go`, not from the wireframe deck's ratios, so
|
||||
`ScreenH`, both in `widget/widget.manager.go`, not from the wireframe deck's ratios, so
|
||||
the layout cannot drift out of step with the font — or with the art — again;
|
||||
`TestLayoutFitsTheFont` guards it. The tape channel comes out at 4 rows of 38
|
||||
columns, which is about one and a half of Dex's remarks on screen at once.
|
||||
@@ -150,74 +150,76 @@ licence.
|
||||
|
||||
## Structure
|
||||
|
||||
The game is one flat package, `inc`. There are no subdirectories: a file's
|
||||
name says where it belongs, in the form `[category].[name].go`. The category is
|
||||
always singular, and `[category].manager.go` is the file that ties that category
|
||||
together — its entity type and whatever else the category shares. `boot.go` is
|
||||
the one file with no category: it declares every manager and builds the game.
|
||||
One category, one package, one directory. A file still says which entity it
|
||||
holds in its own name — `[category].[name].go`, the prefix repeated inside the
|
||||
directory that already carries it, because a file called `alley.go` tells you
|
||||
nothing in a list of open editor tabs.
|
||||
|
||||
```
|
||||
main.go flags + inkwell.Run
|
||||
inc/boot.go the managers, and New(Opts)
|
||||
inc/names.manager.go entity names and world-state keys
|
||||
inc/theme.*.go realworld-93 + nokia-punk
|
||||
inc/world.*.go unsaved runtime state and custom actions
|
||||
inc/widget.manager.go HUD layout and the shared visibility conditions
|
||||
inc/widget.*.go one widget per file
|
||||
inc/<kind>.<name>.go one file per registered entity, by kind
|
||||
main.go flags + inkwell.Run
|
||||
inc/constants.go every name and state key; imports nothing
|
||||
inc/boot/ New(Opts): the hand-off to the engine
|
||||
inc/theme/ the Theme alias, RGB, realworld-93, nokia-punk
|
||||
inc/world/ the run state and the custom actions
|
||||
inc/tape/ the Tape entity and the lookups over it
|
||||
inc/widget/ HUD layout, the visibility conditions, 14 widgets
|
||||
inc/scene/ inc/background/ one file per location, twice
|
||||
inc/item/ inc/character/ inc/dialog/ inc/script/
|
||||
```
|
||||
|
||||
Nothing is enforced by the compiler any more, so the layering is a rule the
|
||||
code keeps by hand: the world holds no opinion about the HUD or the content, and
|
||||
both build on it, never the other way round.
|
||||
`inc` itself holds nothing but constants, which is why every package can import
|
||||
it and it can import none of them. The consequence is that the assembly moved
|
||||
down rather than up: `New` lives in `inc/boot`, because a package cannot be
|
||||
imported by what it imports.
|
||||
|
||||
The layering is no longer a rule kept by hand — it is the import graph, and the
|
||||
compiler rejects the arrow that points the wrong way:
|
||||
|
||||
```
|
||||
names ← theme ← world ← widget
|
||||
↑ ↑
|
||||
content ───┴── boot ← main
|
||||
inc ← theme ← world ← tape ← widget ← boot ← main
|
||||
↑ ↑ ↑
|
||||
└── content ───────────────────-┘
|
||||
```
|
||||
|
||||
Content is one registered entity per file, and the category prefix groups them
|
||||
the way directories used to:
|
||||
|
||||
```
|
||||
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
|
||||
scene.*.go one file per scene: scene.alley.go, … + scene.selector.go
|
||||
```
|
||||
|
||||
Adding a scene means adding `scene.<name>.go` and `background.<name>.go`.
|
||||
Nothing else moves.
|
||||
Adding a scene means adding `inc/scene/scene.<name>.go` and
|
||||
`inc/background/background.<name>.go`. Nothing else moves.
|
||||
|
||||
Every category owns a manager, and they are all the engine's own
|
||||
`inkwell.Manager[T]` — the same registry the `*Game` hangs its content off, kept
|
||||
in registration order and addressed by name. There is no second registry type
|
||||
here: the entity types are aliases of engine structs, so they already satisfy
|
||||
`inkwell.Named` and need no help reading their own name. The eight of them are
|
||||
declared as one block in `boot.go`, and a category's manager file is left
|
||||
holding the alias:
|
||||
`inkwell.Named` and need no help reading their own name. Each one lives in its
|
||||
own package's manager file, next to the alias it holds, and it needs no prefix
|
||||
because the package already is one:
|
||||
|
||||
```go
|
||||
// inc/character/character.manager.go
|
||||
type Character = inkwell.Character
|
||||
|
||||
var Manager = inkwell.NewManager[Character]()
|
||||
```
|
||||
|
||||
An entity file is a literal that hands itself over in an `init()`:
|
||||
|
||||
```go
|
||||
package background
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgServerFarm,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgServerFarm,
|
||||
Path: "assets/bg/server_farm.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Widgets go the same way, the engine's own included: `widget.cursor.go` registers
|
||||
an `inkwell.Cursor` exactly as `background.street.go` registers an image. What
|
||||
The `init()` only runs if something imports the package, so a package whose
|
||||
entities nobody names by symbol needs a blank import in `inc/boot`. Exactly one
|
||||
does — `tape`, everything else is imported for its `Manager` — and the list is
|
||||
per package, not per entity, so adding a file is still adding a file.
|
||||
|
||||
Widgets go the same way, the engine's own included: `widget/widget.cursor.go` registers
|
||||
an `inkwell.Cursor` exactly as `background/background.street.go` registers an image. What
|
||||
they cannot take from alphabetical order is their place in the stack, so each
|
||||
widget names a **layer** — `LayerScene`, `LayerPanel`, `LayerHUD`, `LayerSpeech`,
|
||||
`LayerDialog`, `LayerMenu`, `LayerCurtain`, `LayerCursor` — and inkwell draws
|
||||
@@ -248,7 +250,7 @@ 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:
|
||||
`SceneManager.Get("alley")` answers long before there is a `*Game` to ask. And
|
||||
`scene.Manager.Get("alley")` answers long before there is a `*Game` to ask. And
|
||||
when the game is built, nothing is copied into it — `New` assigns our managers
|
||||
onto the `*Game` in place of the empty ones `NewGame` made, so engine and game
|
||||
share one registry per category instead of keeping two of them in step. Themes
|
||||
@@ -261,12 +263,16 @@ his `Start`, and `g.Walkboxes` is the floor a scene without one walks on. Both
|
||||
are fields on the `*Game`, so a scene file that says nothing about either means
|
||||
"the usual", and the selector opts out by declaring both empty. What is still
|
||||
written back before the hand-off is the derived half of the map:
|
||||
`fillSelectorPins` reads the exit graph backwards and `Set`s the selector.
|
||||
`scene.FillSelectorPins` reads the exit graph backwards and `Set`s the selector.
|
||||
|
||||
There is one world, and it is a package-level singleton: `World`. Nothing takes
|
||||
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.
|
||||
There is one world, and now the package *is* the singleton: `world.Do(…)`,
|
||||
`world.Slot2()`, `world.SetPending(…)`. Nothing takes 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 the `world` package rather than over a
|
||||
parameter someone would have had to thread to it. What little it still keeps is
|
||||
in package-level variables that only `world.Attach` may reset; the mode and the
|
||||
top bar's note are not among them, because those are `State` vars the engine
|
||||
itself can see.
|
||||
|
||||
**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`
|
||||
@@ -293,7 +299,7 @@ edge and so does the code:
|
||||
- **The selector** — the wiki centres its map on a *Helyszínválasztó*, "nem
|
||||
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
|
||||
`scene/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.
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgAlley,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgAlley,
|
||||
Path: "assets/bg/alley.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgBBSTerminal,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgBBSTerminal,
|
||||
Path: "assets/bg/bbs_terminal.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgBVKBranch,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgBVKBranch,
|
||||
Path: "assets/bg/bvk_branch.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgColumbarium,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgColumbarium,
|
||||
Path: "assets/bg/columbarium.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgCuratorShop,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgCuratorShop,
|
||||
Path: "assets/bg/curator_shop.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgHackerspace,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgHackerspace,
|
||||
Path: "assets/bg/hackerspace.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgHospital,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgHospital,
|
||||
Path: "assets/bg/hospital.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgIceCreamShop,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgIceCreamShop,
|
||||
Path: "assets/bg/ice_cream_shop.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,7 +1,9 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
type Background = inkwell.Asset
|
||||
|
||||
var Manager = inkwell.NewManager[Background]()
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgNoodleHouse,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgNoodleHouse,
|
||||
Path: "assets/bg/noodle_house.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgNormanApartment,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgNormanApartment,
|
||||
Path: "assets/bg/norman_apartment.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgPaulShop,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgPaulShop,
|
||||
Path: "assets/bg/paul_shop.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgPoliceStation,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgPoliceStation,
|
||||
Path: "assets/bg/police_station.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgPublicBBS,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgPublicBBS,
|
||||
Path: "assets/bg/public_bbs.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgRooftopHideout,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgRooftopHideout,
|
||||
Path: "assets/bg/rooftop_hideout.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgSamizdatPress,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgSamizdatPress,
|
||||
Path: "assets/bg/samizdat_press.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgScrapMarket,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgScrapMarket,
|
||||
Path: "assets/bg/scrap_market.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgSecretClub,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgSecretClub,
|
||||
Path: "assets/bg/secret_club.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgSecretLab,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgSecretLab,
|
||||
Path: "assets/bg/secret_lab.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgSelector,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgSelector,
|
||||
Path: "assets/bg/selector.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgServerFarm,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgServerFarm,
|
||||
Path: "assets/bg/server_farm.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgShowroom,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgShowroom,
|
||||
Path: "assets/bg/showroom.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgSmallRestaurant,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgSmallRestaurant,
|
||||
Path: "assets/bg/small_restaurant.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgStreet,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgStreet,
|
||||
Path: "assets/bg/street.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package inc
|
||||
package background
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
BackgroundManager.Register(Background{
|
||||
Name: BgTrinketShop,
|
||||
Manager.Register(Background{
|
||||
Name: inc.BgTrinketShop,
|
||||
Path: "assets/bg/trinket_shop.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
})
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
var (
|
||||
BackgroundManager = inkwell.NewManager[Background]()
|
||||
CharacterManager = inkwell.NewManager[Character]()
|
||||
DialogManager = inkwell.NewManager[Dialog]()
|
||||
ItemManager = inkwell.NewManager[Item]()
|
||||
SceneManager = inkwell.NewManager[Scene]()
|
||||
ScriptManager = inkwell.NewManager[Script]()
|
||||
TapeManager = inkwell.NewManager[Tape]()
|
||||
ThemeManager = inkwell.NewManager[Theme]()
|
||||
WidgetManager = inkwell.NewManager[Widget]()
|
||||
)
|
||||
|
||||
type Opts struct {
|
||||
Scene string
|
||||
Finale bool
|
||||
}
|
||||
|
||||
func New(o Opts) *inkwell.Game {
|
||||
start := o.Scene
|
||||
if start == "" {
|
||||
start = SceneAlley
|
||||
}
|
||||
|
||||
fillSelectorPins()
|
||||
|
||||
g := inkwell.NewGame("Real World", ScreenW, ScreenH)
|
||||
g.MaxLogLines = 64
|
||||
g.WindowScale = 2
|
||||
g.SceneRect = inkwell.Rect(0, TopBarH, ScreenW, HUDTop-TopBarH)
|
||||
g.Player = Paul
|
||||
g.Walkboxes = sceneFloor
|
||||
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.")
|
||||
}
|
||||
g.UseWithFail = useWithFail
|
||||
|
||||
g.AssetManager = BackgroundManager
|
||||
g.CharacterManager = CharacterManager
|
||||
g.DialogueManager = DialogManager
|
||||
g.ItemManager = ItemManager
|
||||
g.SceneManager = SceneManager
|
||||
g.ScriptManager = ScriptManager
|
||||
g.WidgetManager = WidgetManager
|
||||
ThemeManager.Each(g.ThemeManager.Register)
|
||||
|
||||
World.attach(g)
|
||||
g.UseTheme(RealWorld)
|
||||
|
||||
g.StartAt(start)
|
||||
g.OnStart(ScriptOpening)
|
||||
if o.Finale {
|
||||
g.OnFinale(ScriptFinale)
|
||||
}
|
||||
return g
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package boot
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/background"
|
||||
"git.teletypegames.org/games/realworld/inc/character"
|
||||
"git.teletypegames.org/games/realworld/inc/dialog"
|
||||
"git.teletypegames.org/games/realworld/inc/item"
|
||||
"git.teletypegames.org/games/realworld/inc/scene"
|
||||
"git.teletypegames.org/games/realworld/inc/script"
|
||||
_ "git.teletypegames.org/games/realworld/inc/tape"
|
||||
"git.teletypegames.org/games/realworld/inc/theme"
|
||||
"git.teletypegames.org/games/realworld/inc/widget"
|
||||
"git.teletypegames.org/games/realworld/inc/world"
|
||||
)
|
||||
|
||||
type Opts struct {
|
||||
Scene string
|
||||
Finale bool
|
||||
}
|
||||
|
||||
func New(o Opts) *inkwell.Game {
|
||||
start := o.Scene
|
||||
if start == "" {
|
||||
start = inc.SceneAlley
|
||||
}
|
||||
|
||||
scene.FillSelectorPins()
|
||||
|
||||
g := inkwell.NewGame("Real World", widget.ScreenW, widget.ScreenH)
|
||||
g.MaxLogLines = 64
|
||||
g.WindowScale = 2
|
||||
g.SceneRect = inkwell.Rect(0, widget.TopBarH, widget.ScreenW, widget.HUDTop-widget.TopBarH)
|
||||
g.Player = inc.Paul
|
||||
g.Walkboxes = scene.Floor
|
||||
g.ExitLook = func(e inkwell.Exit) inkwell.Action {
|
||||
return inkwell.Say(inc.Paul, "That way: "+e.Label+".")
|
||||
}
|
||||
g.ExitTake = func(inkwell.Exit) inkwell.Action {
|
||||
return inkwell.Say(inc.Paul, "It's a way out, not a thing.")
|
||||
}
|
||||
g.UseWithFail = script.UseWithFail
|
||||
|
||||
g.AssetManager = background.Manager
|
||||
g.CharacterManager = character.Manager
|
||||
g.DialogueManager = dialog.Manager
|
||||
g.ItemManager = item.Manager
|
||||
g.SceneManager = scene.Manager
|
||||
g.ScriptManager = script.Manager
|
||||
g.WidgetManager = widget.Manager
|
||||
theme.Manager.Each(g.ThemeManager.Register)
|
||||
|
||||
world.Attach(g)
|
||||
g.UseTheme(inc.RealWorld)
|
||||
|
||||
g.StartAt(start)
|
||||
g.OnStart(inc.ScriptOpening)
|
||||
if o.Finale {
|
||||
g.OnFinale(inc.ScriptFinale)
|
||||
}
|
||||
return g
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
CharacterManager.Register(Character{
|
||||
Name: Dex,
|
||||
Label: "DEX",
|
||||
Voice: inkwell.VoiceLog,
|
||||
SpeechColor: Amber,
|
||||
})
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
CharacterManager.Register(Character{
|
||||
Name: TapeMystery,
|
||||
Label: "UNKNOWN TAPE",
|
||||
Voice: inkwell.VoiceLog,
|
||||
SpeechColor: RGB(0xB9A98A),
|
||||
})
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
CharacterManager.Register(Character{
|
||||
Name: Paul,
|
||||
Speed: 96,
|
||||
W: 28,
|
||||
H: 68,
|
||||
Start: inkwell.Point{
|
||||
X: 320,
|
||||
Y: 232,
|
||||
},
|
||||
SpeechColor: Ink,
|
||||
})
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
CharacterManager.Register(Character{
|
||||
Name: TapeSupport,
|
||||
Label: "TECH SUPPORT",
|
||||
Voice: inkwell.VoiceLog,
|
||||
SpeechColor: RGB(0xE8C86A),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/theme"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Character{
|
||||
Name: inc.Dex,
|
||||
Label: "DEX",
|
||||
Voice: inkwell.VoiceLog,
|
||||
SpeechColor: theme.Amber,
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package inc
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
type Character = inkwell.Character
|
||||
|
||||
var Manager = inkwell.NewManager[Character]()
|
||||
@@ -0,0 +1,16 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/theme"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Character{
|
||||
Name: inc.TapeMystery,
|
||||
Label: "UNKNOWN TAPE",
|
||||
Voice: inkwell.VoiceLog,
|
||||
SpeechColor: theme.RGB(0xB9A98A),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/theme"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Character{
|
||||
Name: inc.Paul,
|
||||
Speed: 96,
|
||||
W: 28,
|
||||
H: 68,
|
||||
Start: inkwell.Point{
|
||||
X: 320,
|
||||
Y: 232,
|
||||
},
|
||||
SpeechColor: theme.Ink,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/theme"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Character{
|
||||
Name: inc.TapeSupport,
|
||||
Label: "TECH SUPPORT",
|
||||
Voice: inkwell.VoiceLog,
|
||||
SpeechColor: theme.RGB(0xE8C86A),
|
||||
})
|
||||
}
|
||||
@@ -14,6 +14,11 @@ const (
|
||||
ItemBlackArmilla = "black_market_armilla"
|
||||
)
|
||||
|
||||
const (
|
||||
RealWorld = "realworld-93"
|
||||
NokiaPunk = "nokia-punk"
|
||||
)
|
||||
|
||||
const (
|
||||
DlgDex = "dex_talk"
|
||||
DlgMysteryTape = "mystery_tape_silent"
|
||||
@@ -1,40 +1,41 @@
|
||||
package inc
|
||||
package dialog
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
DialogManager.Register(Dialog{
|
||||
Name: DlgDex,
|
||||
Manager.Register(Dialog{
|
||||
Name: inc.DlgDex,
|
||||
Start: "root",
|
||||
Nodes: []inkwell.DialogueNode{{
|
||||
Name: "root",
|
||||
Lines: []inkwell.DialogueLine{{
|
||||
Speaker: Dex,
|
||||
Speaker: inc.Dex,
|
||||
Text: "Talk.",
|
||||
}},
|
||||
Choices: []inkwell.DialogueChoice{
|
||||
{
|
||||
Text: "What am I doing here, Dex?",
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(Dex, "You got a letter from a man you hadn't seen in twenty years. And you came. That says more about you than it does about him."),
|
||||
inkwell.Say(inc.Dex, "You got a letter from a man you hadn't seen in twenty years. And you came. That says more about you than it does about him."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Text: "What do you know about Noodle?",
|
||||
Show: inkwell.Not(inkwell.Flag(FlagHasTape)),
|
||||
Show: inkwell.Not(inkwell.Flag(inc.FlagHasTape)),
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(Dex, "He traded cracked Armillas. That isn't charity, Paul, that's a business. The kind they take you in for."),
|
||||
inkwell.Say(inc.Dex, "He traded cracked Armillas. That isn't charity, Paul, that's a business. The kind they take you in for."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Text: "What do you make of this tape?",
|
||||
Show: inkwell.Flag(FlagHasTape),
|
||||
Show: inkwell.Flag(inc.FlagHasTape),
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(Dex, "I make of it that you found a password-locked tape in a gap between two bins, on a tip from a government office. Count how many times that has ended well."),
|
||||
inkwell.Say(inc.Dex, "I make of it that you found a password-locked tape in a gap between two bins, on a tip from a government office. Count how many times that has ended well."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
@@ -42,7 +43,7 @@ func init() {
|
||||
Text: "I miss you.",
|
||||
Once: true,
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(Dex, "I'm four kilobytes of a dead man. Don't do this to yourself."),
|
||||
inkwell.Say(inc.Dex, "I'm four kilobytes of a dead man. Don't do this to yourself."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
@@ -1,7 +1,9 @@
|
||||
package inc
|
||||
package dialog
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
type Dialog = inkwell.Dialogue
|
||||
|
||||
var Manager = inkwell.NewManager[Dialog]()
|
||||
@@ -1,24 +1,25 @@
|
||||
package inc
|
||||
package dialog
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
DialogManager.Register(Dialog{
|
||||
Name: DlgMysteryTape,
|
||||
Manager.Register(Dialog{
|
||||
Name: inc.DlgMysteryTape,
|
||||
Start: "root",
|
||||
Nodes: []inkwell.DialogueNode{{
|
||||
Name: "root",
|
||||
Lines: []inkwell.DialogueLine{{
|
||||
Speaker: Dex,
|
||||
Speaker: inc.Dex,
|
||||
Text: "Nothing. Warm, spinning, and silent.",
|
||||
}},
|
||||
Choices: []inkwell.DialogueChoice{
|
||||
{
|
||||
Text: "Are you sure it works?",
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(Dex, "It works. It just isn't talking to you. That is not the same as silence."),
|
||||
inkwell.Say(inc.Dex, "It works. It just isn't talking to you. That is not the same as silence."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
@@ -1,22 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ItemManager.Register(Item{
|
||||
Name: ItemBlackArmilla,
|
||||
Description: "black-market Armilla",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(Paul, "Jailbroken. Pushes ads, but it was cheap."),
|
||||
inkwell.Say(Dex, "Two slots, and both of them lie about the temperature. Don't trade me in for it."),
|
||||
),
|
||||
OnUseWith: map[string]inkwell.Action{
|
||||
ItemNoodleLetter: inkwell.Seq(
|
||||
inkwell.Say(Paul, "A letter and a bracelet. Brilliant."),
|
||||
inkwell.Say(Dex, "Nothing. Which is what I'd charge for it."),
|
||||
),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ItemManager.Register(Item{
|
||||
Name: ItemMysteryTape,
|
||||
Description: "unmarked Personal Tape",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(Paul, "Password-locked. Of course."),
|
||||
inkwell.Say(Dex, "Put it in the second slot if you care that much. I did warn you."),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ItemManager.Register(Item{
|
||||
Name: ItemNoodleLetter,
|
||||
Description: "Noodle's letter",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(Paul, "“Come out, Paul. Not a phone conversation.” That's all it says."),
|
||||
inkwell.Say(Dex, "And now you're here. And he isn't."),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Item{
|
||||
Name: inc.ItemBlackArmilla,
|
||||
Description: "black-market Armilla",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "Jailbroken. Pushes ads, but it was cheap."),
|
||||
inkwell.Say(inc.Dex, "Two slots, and both of them lie about the temperature. Don't trade me in for it."),
|
||||
),
|
||||
OnUseWith: map[string]inkwell.Action{
|
||||
inc.ItemNoodleLetter: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "A letter and a bracelet. Brilliant."),
|
||||
inkwell.Say(inc.Dex, "Nothing. Which is what I'd charge for it."),
|
||||
),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package inc
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
type Item = inkwell.Item
|
||||
|
||||
var Manager = inkwell.NewManager[Item]()
|
||||
@@ -0,0 +1,17 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Item{
|
||||
Name: inc.ItemMysteryTape,
|
||||
Description: "unmarked Personal Tape",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "Password-locked. Of course."),
|
||||
inkwell.Say(inc.Dex, "Put it in the second slot if you care that much. I did warn you."),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Item{
|
||||
Name: inc.ItemNoodleLetter,
|
||||
Description: "Noodle's letter",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "“Come out, Paul. Not a phone conversation.” That's all it says."),
|
||||
inkwell.Say(inc.Dex, "And now you're here. And he isn't."),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneAlley,
|
||||
Title: "ALLEY — BEHIND NOODLE'S HOUSE",
|
||||
Background: BgAlley,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
To: SceneNoodleHouse,
|
||||
Label: "back out to the street",
|
||||
Side: inkwell.ExitLeft,
|
||||
},
|
||||
},
|
||||
Actors: []inkwell.SceneActor{
|
||||
{
|
||||
CharacterName: Paul,
|
||||
At: inkwell.Point{
|
||||
X: 120,
|
||||
Y: 232,
|
||||
},
|
||||
},
|
||||
},
|
||||
OnEnter: setVarIfEmpty(VarArmillaStrip, "SRP: 1 tape"),
|
||||
Hotspots: []inkwell.Hotspot{hidingPlace(), backDoor(), bin(), fireEscape()},
|
||||
})
|
||||
}
|
||||
|
||||
func hidingPlace() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "hiding_place",
|
||||
Label: "gap at the foot of the wall",
|
||||
Area: inkwell.Rect(416, 150, 68, 52),
|
||||
OnLook: inkwell.If(inkwell.Flag(FlagHasTape),
|
||||
inkwell.Say(Paul, "Empty. Whatever was in there is on me now."),
|
||||
inkwell.Say(Paul, "Loose brick. There's a gap behind it."),
|
||||
),
|
||||
OnUse: inkwell.If(inkwell.Flag(FlagPoliceTip),
|
||||
inkwell.If(inkwell.Flag(FlagHasTape),
|
||||
inkwell.Say(Paul, "There's nothing else in there."),
|
||||
inkwell.Seq(
|
||||
inkwell.Say(Paul, "“Behind the brick.” All right then."),
|
||||
inkwell.Give(ItemMysteryTape),
|
||||
inkwell.SetFlag(FlagHasTape),
|
||||
inkwell.Say(Paul, "A Personal Tape. No label, no seal."),
|
||||
inkwell.Say(Dex, "Password-locked. And somebody very much did not want it found."),
|
||||
),
|
||||
),
|
||||
inkwell.Say(Paul, "One loose brick. I'm not taking the alley apart over it."),
|
||||
),
|
||||
OnTake: inkwell.Say(Paul, "I'm not carrying a wall."),
|
||||
}
|
||||
}
|
||||
|
||||
func backDoor() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "back_door",
|
||||
Label: "locked back door",
|
||||
Area: inkwell.Rect(72, 106, 80, 124),
|
||||
OnLook: inkwell.Say(Paul, "Keypad. Four digits, worn keys."),
|
||||
OnUse: inkwell.Seq(
|
||||
inkwell.Say(Paul, "Locked. And I'm not guessing four digits."),
|
||||
inkwell.Say(Dex, "The wear is heaviest on the two and the seven. That isn't a code. It's fewer options."),
|
||||
),
|
||||
OnTalk: inkwell.Say(Paul, "To the door? I'm not there yet."),
|
||||
OnUseWith: map[string]inkwell.Action{
|
||||
ItemBlackArmilla: inkwell.Seq(
|
||||
inkwell.Say(Paul, "A black-market bracelet doesn't open a keypad."),
|
||||
inkwell.Say(Dex, "But you do get an advert out of it."),
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func bin() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "bin",
|
||||
Label: "toppled bin",
|
||||
Area: inkwell.Rect(240, 170, 88, 60),
|
||||
OnLook: inkwell.Say(Paul, "Somebody's been through it. Thoroughly."),
|
||||
OnUse: inkwell.Seq(
|
||||
inkwell.Say(Paul, "Already turned out. I'm not going to be the second one."),
|
||||
inkwell.Say(Dex, "The police don't go through bins. So who did?"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func fireEscape() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "fire_escape",
|
||||
Label: "fire escape",
|
||||
Area: inkwell.Rect(528, 44, 88, 160),
|
||||
OnLook: inkwell.Say(Paul, "Runs all the way to the roof. Bottom rung is two metres over my head."),
|
||||
OnUse: inkwell.Say(Paul, "Can't reach it. I'd need something to stand on."),
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
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."),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneAlley,
|
||||
Title: "ALLEY — BEHIND NOODLE'S HOUSE",
|
||||
Background: inc.BgAlley,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
To: inc.SceneNoodleHouse,
|
||||
Label: "back out to the street",
|
||||
Side: inkwell.ExitLeft,
|
||||
},
|
||||
},
|
||||
Actors: []inkwell.SceneActor{
|
||||
{
|
||||
CharacterName: inc.Paul,
|
||||
At: inkwell.Point{
|
||||
X: 120,
|
||||
Y: 232,
|
||||
},
|
||||
},
|
||||
},
|
||||
OnEnter: setVarIfEmpty(inc.VarArmillaStrip, "SRP: 1 tape"),
|
||||
Hotspots: []inkwell.Hotspot{hidingPlace(), backDoor(), bin(), fireEscape()},
|
||||
})
|
||||
}
|
||||
|
||||
func hidingPlace() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "hiding_place",
|
||||
Label: "gap at the foot of the wall",
|
||||
Area: inkwell.Rect(416, 150, 68, 52),
|
||||
OnLook: inkwell.If(inkwell.Flag(inc.FlagHasTape),
|
||||
inkwell.Say(inc.Paul, "Empty. Whatever was in there is on me now."),
|
||||
inkwell.Say(inc.Paul, "Loose brick. There's a gap behind it."),
|
||||
),
|
||||
OnUse: inkwell.If(inkwell.Flag(inc.FlagPoliceTip),
|
||||
inkwell.If(inkwell.Flag(inc.FlagHasTape),
|
||||
inkwell.Say(inc.Paul, "There's nothing else in there."),
|
||||
inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "“Behind the brick.” All right then."),
|
||||
inkwell.Give(inc.ItemMysteryTape),
|
||||
inkwell.SetFlag(inc.FlagHasTape),
|
||||
inkwell.Say(inc.Paul, "A Personal Tape. No label, no seal."),
|
||||
inkwell.Say(inc.Dex, "Password-locked. And somebody very much did not want it found."),
|
||||
),
|
||||
),
|
||||
inkwell.Say(inc.Paul, "One loose brick. I'm not taking the alley apart over it."),
|
||||
),
|
||||
OnTake: inkwell.Say(inc.Paul, "I'm not carrying a wall."),
|
||||
}
|
||||
}
|
||||
|
||||
func backDoor() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "back_door",
|
||||
Label: "locked back door",
|
||||
Area: inkwell.Rect(72, 106, 80, 124),
|
||||
OnLook: inkwell.Say(inc.Paul, "Keypad. Four digits, worn keys."),
|
||||
OnUse: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "Locked. And I'm not guessing four digits."),
|
||||
inkwell.Say(inc.Dex, "The wear is heaviest on the two and the seven. That isn't a code. It's fewer options."),
|
||||
),
|
||||
OnTalk: inkwell.Say(inc.Paul, "To the door? I'm not there yet."),
|
||||
OnUseWith: map[string]inkwell.Action{
|
||||
inc.ItemBlackArmilla: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "A black-market bracelet doesn't open a keypad."),
|
||||
inkwell.Say(inc.Dex, "But you do get an advert out of it."),
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func bin() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "bin",
|
||||
Label: "toppled bin",
|
||||
Area: inkwell.Rect(240, 170, 88, 60),
|
||||
OnLook: inkwell.Say(inc.Paul, "Somebody's been through it. Thoroughly."),
|
||||
OnUse: inkwell.Seq(
|
||||
inkwell.Say(inc.Paul, "Already turned out. I'm not going to be the second one."),
|
||||
inkwell.Say(inc.Dex, "The police don't go through bins. So who did?"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func fireEscape() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "fire_escape",
|
||||
Label: "fire escape",
|
||||
Area: inkwell.Rect(528, 44, 88, 160),
|
||||
OnLook: inkwell.Say(inc.Paul, "Runs all the way to the roof. Bottom rung is two metres over my head."),
|
||||
OnUse: inkwell.Say(inc.Paul, "Can't reach it. I'd need something to stand on."),
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneBBSTerminal,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneBBSTerminal,
|
||||
Title: "TERMINAL — BBS ACCESS POINT",
|
||||
Background: BgBBSTerminal,
|
||||
Background: inc.BgBBSTerminal,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
Label: "step back from the terminal",
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneBVKBranch,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneBVKBranch,
|
||||
Title: "BVK — SAN FRANCISCO BRANCH",
|
||||
Background: BgBVKBranch,
|
||||
Background: inc.BgBVKBranch,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneColumbarium,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneColumbarium,
|
||||
Title: "COLUMBARIUM — DEX'S MEMORIAL",
|
||||
Background: BgColumbarium,
|
||||
Background: inc.BgColumbarium,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneCuratorShop,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneCuratorShop,
|
||||
Title: "CURATOR SERVICE — THE MASTER'S WORKSHOP",
|
||||
Background: BgCuratorShop,
|
||||
Background: inc.BgCuratorShop,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneHackerspace,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneHackerspace,
|
||||
Title: "HACKERSPACE",
|
||||
Background: BgHackerspace,
|
||||
Background: inc.BgHackerspace,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneHospital,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneHospital,
|
||||
Title: "HOSPITAL — PSYCHIATRIC WING",
|
||||
Background: BgHospital,
|
||||
Background: inc.BgHospital,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneIceCreamShop,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneIceCreamShop,
|
||||
Title: "ICE CREAM SHOP — WHERE THE BAR WAS",
|
||||
Background: BgIceCreamShop,
|
||||
Background: inc.BgIceCreamShop,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,12 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc/world"
|
||||
)
|
||||
|
||||
type Scene = inkwell.Scene
|
||||
|
||||
var sceneFloor = []inkwell.Polygon{
|
||||
var Manager = inkwell.NewManager[Scene]()
|
||||
|
||||
var Floor = []inkwell.Polygon{
|
||||
inkwell.Poly(
|
||||
inkwell.Point{
|
||||
X: 16,
|
||||
@@ -26,7 +29,7 @@ var sceneFloor = []inkwell.Polygon{
|
||||
}
|
||||
|
||||
func setVarIfEmpty(name string, v any) inkwell.Action {
|
||||
return Fn(func(ctx *inkwell.Ctx) {
|
||||
return world.Fn(func(ctx *inkwell.Ctx) {
|
||||
if ctx.Game.State.Var(name) == nil {
|
||||
ctx.Game.State.SetVar(name, v)
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneNoodleHouse,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneNoodleHouse,
|
||||
Title: "NOODLE'S HOUSE — SEALED",
|
||||
Background: BgNoodleHouse,
|
||||
Background: inc.BgNoodleHouse,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
{
|
||||
To: SceneAlley,
|
||||
To: inc.SceneAlley,
|
||||
Label: "the alley behind the house",
|
||||
Side: inkwell.ExitRight,
|
||||
},
|
||||
@@ -1,23 +1,24 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneNormanApartment,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneNormanApartment,
|
||||
Title: "NORMAN'S APARTMENT",
|
||||
Background: BgNormanApartment,
|
||||
Background: inc.BgNormanApartment,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
{
|
||||
To: SceneRooftopHideout,
|
||||
To: inc.SceneRooftopHideout,
|
||||
Label: "the stairs up to the roof",
|
||||
Side: inkwell.ExitBack,
|
||||
},
|
||||
{
|
||||
To: SceneBBSTerminal,
|
||||
To: inc.SceneBBSTerminal,
|
||||
Label: "Norman's terminal",
|
||||
Side: inkwell.ExitRight,
|
||||
},
|
||||
@@ -1,17 +1,18 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: ScenePaulShop,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.ScenePaulShop,
|
||||
Title: "PAUL'S SHOP — JUNK AND GARAGE",
|
||||
Background: BgPaulShop,
|
||||
Background: inc.BgPaulShop,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
To: SceneNoodleHouse,
|
||||
To: inc.SceneNoodleHouse,
|
||||
Label: "the bus to San Francisco",
|
||||
Side: inkwell.ExitNear,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: ScenePoliceStation,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.ScenePoliceStation,
|
||||
Title: "SFPD — STATION AND HOLDING",
|
||||
Background: BgPoliceStation,
|
||||
Background: inc.BgPoliceStation,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: ScenePublicBBS,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.ScenePublicBBS,
|
||||
Title: "PUBLIC BBS TERMINAL",
|
||||
Background: BgPublicBBS,
|
||||
Background: inc.BgPublicBBS,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,22 +1,23 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneRooftopHideout,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneRooftopHideout,
|
||||
Title: "NORMAN'S ROOFTOP HIDEOUT",
|
||||
Background: BgRooftopHideout,
|
||||
Background: inc.BgRooftopHideout,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
To: SceneNormanApartment,
|
||||
To: inc.SceneNormanApartment,
|
||||
Label: "back down into the flat",
|
||||
Side: inkwell.ExitNear,
|
||||
},
|
||||
{
|
||||
To: SceneBBSTerminal,
|
||||
To: inc.SceneBBSTerminal,
|
||||
Label: "the old terminal",
|
||||
Side: inkwell.ExitRight,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneSamizdatPress,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneSamizdatPress,
|
||||
Title: "SAMIZDAT PRINTING HOUSE",
|
||||
Background: BgSamizdatPress,
|
||||
Background: inc.BgSamizdatPress,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneScrapMarket,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneScrapMarket,
|
||||
Title: "SCRAP MARKET",
|
||||
Background: BgScrapMarket,
|
||||
Background: inc.BgScrapMarket,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,22 +1,23 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneSecretClub,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneSecretClub,
|
||||
Title: "SECRET CLUB — THE UNDERWATER SUN",
|
||||
Background: BgSecretClub,
|
||||
Background: inc.BgSecretClub,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
To: SceneBBSTerminal,
|
||||
To: inc.SceneBBSTerminal,
|
||||
Label: "the terminal in the corner",
|
||||
Side: inkwell.ExitBack,
|
||||
},
|
||||
{
|
||||
To: SceneTrinketShop,
|
||||
To: inc.SceneTrinketShop,
|
||||
Label: "back out through the shop",
|
||||
Side: inkwell.ExitNear,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneSecretLab,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneSecretLab,
|
||||
Title: "SECRET RESEARCH LABORATORY",
|
||||
Background: BgSecretLab,
|
||||
Background: inc.BgSecretLab,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,34 +1,35 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
var exitToSelector = inkwell.Exit{
|
||||
To: SceneSelector,
|
||||
To: inc.SceneSelector,
|
||||
Label: "the rest of the city",
|
||||
Side: inkwell.ExitNear,
|
||||
}
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneSelector,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneSelector,
|
||||
Title: "SAN FRANCISCO",
|
||||
Background: BgSelector,
|
||||
Background: inc.BgSelector,
|
||||
Actors: []inkwell.SceneActor{},
|
||||
Walkboxes: []inkwell.Polygon{},
|
||||
})
|
||||
}
|
||||
|
||||
func fillSelectorPins() {
|
||||
selector, ok := SceneManager.Get(SceneSelector)
|
||||
func FillSelectorPins() {
|
||||
selector, ok := Manager.Get(inc.SceneSelector)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var exits []inkwell.Exit
|
||||
for _, entity := range SceneManager.All() {
|
||||
for _, entity := range Manager.All() {
|
||||
if !leadsToSelector(entity) {
|
||||
continue
|
||||
}
|
||||
@@ -39,12 +40,12 @@ func fillSelectorPins() {
|
||||
})
|
||||
}
|
||||
selector.Exits = exits
|
||||
SceneManager.Set(selector)
|
||||
Manager.Set(selector)
|
||||
}
|
||||
|
||||
func leadsToSelector(s Scene) bool {
|
||||
for _, e := range s.Exits {
|
||||
if e.To == SceneSelector {
|
||||
if e.To == inc.SceneSelector {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneServerFarm,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneServerFarm,
|
||||
Title: "SERVER FARM",
|
||||
Background: BgServerFarm,
|
||||
Background: inc.BgServerFarm,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneShowroom,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneShowroom,
|
||||
Title: "NEUMATRONIC SHOWROOM",
|
||||
Background: BgShowroom,
|
||||
Background: inc.BgShowroom,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -1,17 +1,18 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneSmallRestaurant,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneSmallRestaurant,
|
||||
Title: "SMALL RESTAURANT — NEXT DOOR",
|
||||
Background: BgSmallRestaurant,
|
||||
Background: inc.BgSmallRestaurant,
|
||||
Exits: []inkwell.Exit{
|
||||
{
|
||||
To: SceneTrinketShop,
|
||||
To: inc.SceneTrinketShop,
|
||||
Label: "back to the trinket shop",
|
||||
Side: inkwell.ExitLeft,
|
||||
},
|
||||
@@ -1,14 +1,15 @@
|
||||
package inc
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SceneManager.Register(Scene{
|
||||
Name: SceneStreet,
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneStreet,
|
||||
Title: "STREET",
|
||||
Background: BgStreet,
|
||||
Background: inc.BgStreet,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
},
|
||||
@@ -0,0 +1,29 @@
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Scene{
|
||||
Name: inc.SceneTrinketShop,
|
||||
Title: "CHINATOWN — TRINKET SHOP",
|
||||
Background: inc.BgTrinketShop,
|
||||
Exits: []inkwell.Exit{
|
||||
exitToSelector,
|
||||
{
|
||||
To: inc.SceneSmallRestaurant,
|
||||
Label: "the eating place next door",
|
||||
Side: inkwell.ExitRight,
|
||||
},
|
||||
{
|
||||
To: inc.SceneSecretClub,
|
||||
Label: "the way in at the back",
|
||||
Side: inkwell.ExitBack,
|
||||
Needs: inc.FlagClubEntry,
|
||||
Blocked: inkwell.Say(inc.Paul, "Just a shop, as far as the man behind the counter is concerned."),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ScriptManager.Register(Script{
|
||||
Name: ScriptFinale,
|
||||
Actions: inkwell.Seq(
|
||||
SetMode(ModeCutscene),
|
||||
inkwell.Wait(0.6),
|
||||
inkwell.Say(Paul, "I'm putting it in. That's all this is."),
|
||||
inkwell.Wait(0.4),
|
||||
UseTheme(NokiaPunk),
|
||||
inkwell.Say("norman", "No — this isn't what you were supposed to do!"),
|
||||
inkwell.Wait(0.6),
|
||||
inkwell.Say(TapeMystery, "Thank you, Paul. You did exactly what I asked, the whole way through."),
|
||||
inkwell.Wait(1.0),
|
||||
inkwell.ShowEnd("REAL WORLD — end of game two"),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ScriptManager.Register(Script{
|
||||
Name: ScriptOpening,
|
||||
Actions: inkwell.Seq(
|
||||
inkwell.SetFlag(FlagPoliceTip),
|
||||
inkwell.Say(Paul, "Back alley. Just like the clerk said."),
|
||||
inkwell.Say(Dex, "A government office tipped you off to remove something from a scene. That doesn't strike you as odd?"),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ScriptManager.Register(Script{
|
||||
Name: ScriptTapeInsert,
|
||||
Actions: inkwell.Seq(
|
||||
Fn(func(ctx *inkwell.Ctx) {
|
||||
item := World.TakePending()
|
||||
if item == "" {
|
||||
return
|
||||
}
|
||||
World.SetSlot2(item)
|
||||
ctx.Game.Inventory.Remove(item)
|
||||
ctx.Game.State.SetVar(VarArmillaStrip, "SLOT2: READING")
|
||||
}),
|
||||
inkwell.Say(Paul, "Right. Let's see who you are."),
|
||||
inkwell.Say(Dex, "Clicked in. Spinning. And now: nothing."),
|
||||
inkwell.Say(Dex, "A stranger's tape in your own Armilla, Paul. I hope you know what you're doing."),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/world"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Script{
|
||||
Name: inc.ScriptFinale,
|
||||
Actions: inkwell.Seq(
|
||||
world.SetMode(world.ModeCutscene),
|
||||
inkwell.Wait(0.6),
|
||||
inkwell.Say(inc.Paul, "I'm putting it in. That's all this is."),
|
||||
inkwell.Wait(0.4),
|
||||
world.UseTheme(inc.NokiaPunk),
|
||||
inkwell.Say("norman", "No — this isn't what you were supposed to do!"),
|
||||
inkwell.Wait(0.6),
|
||||
inkwell.Say(inc.TapeMystery, "Thank you, Paul. You did exactly what I asked, the whole way through."),
|
||||
inkwell.Wait(1.0),
|
||||
inkwell.ShowEnd("REAL WORLD — end of game two"),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package inc
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
type Script = inkwell.Script
|
||||
|
||||
var Manager = inkwell.NewManager[Script]()
|
||||
@@ -0,0 +1,17 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Script{
|
||||
Name: inc.ScriptOpening,
|
||||
Actions: inkwell.Seq(
|
||||
inkwell.SetFlag(inc.FlagPoliceTip),
|
||||
inkwell.Say(inc.Paul, "Back alley. Just like the clerk said."),
|
||||
inkwell.Say(inc.Dex, "A government office tipped you off to remove something from a scene. That doesn't strike you as odd?"),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/world"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Script{
|
||||
Name: inc.ScriptTapeInsert,
|
||||
Actions: inkwell.Seq(
|
||||
world.Fn(func(ctx *inkwell.Ctx) {
|
||||
item := world.TakePending()
|
||||
if item == "" {
|
||||
return
|
||||
}
|
||||
world.SetSlot2(item)
|
||||
ctx.Game.Inventory.Remove(item)
|
||||
ctx.Game.State.SetVar(inc.VarArmillaStrip, "SLOT2: READING")
|
||||
}),
|
||||
inkwell.Say(inc.Paul, "Right. Let's see who you are."),
|
||||
inkwell.Say(inc.Dex, "Clicked in. Spinning. And now: nothing."),
|
||||
inkwell.Say(inc.Dex, "A stranger's tape in your own Armilla, Paul. I hope you know what you're doing."),
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
package inc
|
||||
package script
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
"git.teletypegames.org/games/realworld/inc/world"
|
||||
)
|
||||
|
||||
func useWithFail(item string, h *inkwell.Hotspot) inkwell.Action {
|
||||
func UseWithFail(item string, h *inkwell.Hotspot) inkwell.Action {
|
||||
key := "fail." + item + "." + h.Name
|
||||
World.G.State.NoteTalked(key)
|
||||
n := World.G.State.Talked(key)
|
||||
world.Game().State.NoteTalked(key)
|
||||
n := world.Game().State.Talked(key)
|
||||
|
||||
return inkwell.Seq(
|
||||
inkwell.Say(Paul, pick(paulFails, n)),
|
||||
inkwell.Say(Dex, dexFail(n)),
|
||||
inkwell.Say(inc.Paul, pick(paulFails, n)),
|
||||
inkwell.Say(inc.Dex, dexFail(n)),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package inc
|
||||
|
||||
func init() {
|
||||
TapeManager.Register(Tape{
|
||||
Name: Dex,
|
||||
Dialogue: DlgDex,
|
||||
})
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package inc
|
||||
|
||||
type Tape struct {
|
||||
Name string
|
||||
Item string
|
||||
Dialogue string
|
||||
}
|
||||
|
||||
func (t Tape) GetName() string { return t.Name }
|
||||
|
||||
func IsTape(name string) bool { return TapeManager.Has(name) }
|
||||
|
||||
func TapeOf(item string) (Tape, bool) {
|
||||
for _, t := range TapeManager.All() {
|
||||
if t.Item != "" && t.Item == item {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return Tape{}, false
|
||||
}
|
||||
|
||||
func IsTapeItem(item string) bool {
|
||||
_, ok := TapeOf(item)
|
||||
return ok
|
||||
}
|
||||
|
||||
func TapeDialogue(item string) string {
|
||||
if t, ok := TapeOf(item); ok && t.Dialogue != "" {
|
||||
return t.Dialogue
|
||||
}
|
||||
return DlgDex
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package inc
|
||||
|
||||
func init() {
|
||||
TapeManager.Register(Tape{
|
||||
Name: TapeMystery,
|
||||
Item: ItemMysteryTape,
|
||||
Dialogue: DlgMysteryTape,
|
||||
})
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package inc
|
||||
|
||||
func init() {
|
||||
TapeManager.Register(Tape{
|
||||
Name: TapeSupport,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package tape
|
||||
|
||||
import (
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Tape{
|
||||
Name: inc.Dex,
|
||||
Dialogue: inc.DlgDex,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package tape
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
type Tape struct {
|
||||
Name string
|
||||
Item string
|
||||
Dialogue string
|
||||
}
|
||||
|
||||
var Manager = inkwell.NewManager[Tape]()
|
||||
|
||||
func (t Tape) GetName() string { return t.Name }
|
||||
|
||||
func Is(name string) bool { return Manager.Has(name) }
|
||||
|
||||
func Of(item string) (Tape, bool) {
|
||||
for _, t := range Manager.All() {
|
||||
if t.Item != "" && t.Item == item {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return Tape{}, false
|
||||
}
|
||||
|
||||
func IsItem(item string) bool {
|
||||
_, ok := Of(item)
|
||||
return ok
|
||||
}
|
||||
|
||||
func Dialogue(item string) string {
|
||||
if t, ok := Of(item); ok && t.Dialogue != "" {
|
||||
return t.Dialogue
|
||||
}
|
||||
return inc.DlgDex
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package tape
|
||||
|
||||
import (
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Tape{
|
||||
Name: inc.TapeMystery,
|
||||
Item: inc.ItemMysteryTape,
|
||||
Dialogue: inc.DlgMysteryTape,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tape
|
||||
|
||||
import (
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Manager.Register(Tape{
|
||||
Name: inc.TapeSupport,
|
||||
})
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package inc
|
||||
package theme
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
@@ -8,10 +8,7 @@ import (
|
||||
|
||||
type Theme = inkwell.Theme
|
||||
|
||||
const (
|
||||
RealWorld = "realworld-93"
|
||||
NokiaPunk = "nokia-punk"
|
||||
)
|
||||
var Manager = inkwell.NewManager[Theme]()
|
||||
|
||||
func RGB(hex uint32) color.Color {
|
||||
return color.RGBA{
|
||||
@@ -1,4 +1,8 @@
|
||||
package inc
|
||||
package theme
|
||||
|
||||
import (
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
var (
|
||||
Green = RGB(0x3BE86B)
|
||||
@@ -7,8 +11,8 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
ThemeManager.Register(Theme{
|
||||
Name: NokiaPunk,
|
||||
Manager.Register(Theme{
|
||||
Name: inc.NokiaPunk,
|
||||
PanelBG: npBlack,
|
||||
StatusText: Green,
|
||||
FlashText: RGB(0xD8F06A),
|
||||
@@ -1,4 +1,8 @@
|
||||
package inc
|
||||
package theme
|
||||
|
||||
import (
|
||||
"git.teletypegames.org/games/realworld/inc"
|
||||
)
|
||||
|
||||
var (
|
||||
Ink = RGB(0xDCD5C4)
|
||||
@@ -11,8 +15,8 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
ThemeManager.Register(Theme{
|
||||
Name: RealWorld,
|
||||
Manager.Register(Theme{
|
||||
Name: inc.RealWorld,
|
||||
PanelBG: black,
|
||||
StatusText: Ink,
|
||||
FlashText: Amber,
|
||||
@@ -1,15 +0,0 @@
|
||||
package inc
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
WidgetManager.Register(&inkwell.TopBar{
|
||||
Name: "topbar",
|
||||
When: whenPlaying,
|
||||
Height: TopBarH,
|
||||
TimeVar: VarArmillaStrip,
|
||||
NoteVar: VarNote,
|
||||
})
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package inc
|
||||
package widget
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
WidgetManager.Register(&inkwell.Cursor{
|
||||
Manager.Register(&inkwell.Cursor{
|
||||
Name: "cursor",
|
||||
})
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package inc
|
||||
package widget
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
WidgetManager.Register(&inkwell.DialogBox{
|
||||
Manager.Register(&inkwell.DialogBox{
|
||||
Name: "dialog",
|
||||
Bounds: inkwell.Rect(0, ScreenH-LineH*9, DividerX, LineH*9),
|
||||
LineHeight: LineH,
|
||||
@@ -1,11 +1,11 @@
|
||||
package inc
|
||||
package widget
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
WidgetManager.Register(&inkwell.EndCard{
|
||||
Manager.Register(&inkwell.EndCard{
|
||||
Name: "endcard",
|
||||
})
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package inc
|
||||
package widget
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
)
|
||||
|
||||
func init() {
|
||||
WidgetManager.Register(&inkwell.HotspotDebug{
|
||||
Manager.Register(&inkwell.HotspotDebug{
|
||||
Name: "hotspot_debug",
|
||||
})
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user