game skeleton
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package asset
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
)
|
||||
|
||||
// alleyBackground is the alley behind Noodle's house (beat 3).
|
||||
func alleyBackground() inkwell.Asset {
|
||||
return inkwell.Asset{
|
||||
Name: names.AssetAlleyBG,
|
||||
Path: "assets/bg/alley.png",
|
||||
Kind: inkwell.AssetImage,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Package asset registers the game's assets.
|
||||
//
|
||||
// During the greybox phase no asset file exists on disk: inkwell draws a
|
||||
// placeholder when a sprite is missing, which is exactly the wireframe deck's
|
||||
// dashed-outline convention, for free. Only the registration has to exist —
|
||||
// Game.Validate requires every scene background to name a registered asset.
|
||||
package asset
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every asset to the game.
|
||||
func Register(w *world.World) {
|
||||
for _, a := range []inkwell.Asset{
|
||||
alleyBackground(),
|
||||
} {
|
||||
w.G.AssetManager.Register(a)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Package character registers the game's characters.
|
||||
//
|
||||
// Tapes are characters too, not props — the wiki is explicit about it. They
|
||||
// have no body in the scene, so they carry no W/H and never appear in
|
||||
// Scene.Actors; their voice lives in the tape channel (see world.TapeSay).
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every character to the game.
|
||||
func Register(w *world.World) {
|
||||
for _, c := range []inkwell.Character{
|
||||
paul(),
|
||||
dex(),
|
||||
mysteryTape(),
|
||||
supportTape(),
|
||||
} {
|
||||
w.G.CharacterManager.Register(c)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/theme"
|
||||
)
|
||||
|
||||
// dex is the personality imprint of a dead friend, permanently in slot 1 of
|
||||
// Paul's Armilla. Constant commentary, hint system, dialogue partner.
|
||||
func dex() inkwell.Character {
|
||||
return inkwell.Character{
|
||||
Name: names.Dex,
|
||||
SpeechColor: theme.Amber,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/theme"
|
||||
)
|
||||
|
||||
// mysteryTape is the tape found in the alley — in truth Norman's Personal
|
||||
// Tape, but the player only learns that in the finale.
|
||||
//
|
||||
// Its voice is a colder, greyer amber than Dex's. That pays off in reverse:
|
||||
// it never once spoke in the same voice as the friend.
|
||||
func mysteryTape() inkwell.Character {
|
||||
return inkwell.Character{
|
||||
Name: names.TapeMystery,
|
||||
SpeechColor: theme.RGB(0xB9A98A),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/theme"
|
||||
)
|
||||
|
||||
// paul is the player character: a junk dealer and street survivor, technically
|
||||
// competent, living on the edge of the city.
|
||||
func paul() inkwell.Character {
|
||||
return inkwell.Character{
|
||||
Name: names.Paul,
|
||||
Speed: 96,
|
||||
W: 28,
|
||||
H: 68,
|
||||
Start: inkwell.Point{X: 120, Y: 232},
|
||||
// Bone white: the world and Paul. If something is amber, a tape said
|
||||
// it — see the colour rule in README.
|
||||
SpeechColor: theme.Ink,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/theme"
|
||||
)
|
||||
|
||||
// supportTape answers everything with basic information, insufferably. Dex
|
||||
// hates it. Acquired in Chinatown (beat 5) — not reachable yet.
|
||||
func supportTape() inkwell.Character {
|
||||
return inkwell.Character{
|
||||
Name: names.TapeSupport,
|
||||
SpeechColor: theme.RGB(0xE8C86A),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Package content is the composition root for everything the game declares:
|
||||
// assets, characters, items, dialogues, scripts and scenes.
|
||||
//
|
||||
// Each registered entity lives in its own file, under a subpackage named after
|
||||
// its kind. Adding a scene means adding scene/<name>.go and one line in
|
||||
// scene/scene.go — nothing else moves.
|
||||
package content
|
||||
|
||||
import (
|
||||
"realworld/internal/content/asset"
|
||||
"realworld/internal/content/character"
|
||||
"realworld/internal/content/dialog"
|
||||
"realworld/internal/content/item"
|
||||
"realworld/internal/content/scene"
|
||||
"realworld/internal/content/script"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every entity to the game. Order matters only in that scenes
|
||||
// reference assets and characters, which Game.Validate cross-checks.
|
||||
func Register(w *world.World) {
|
||||
asset.Register(w)
|
||||
character.Register(w)
|
||||
item.Register(w)
|
||||
dialog.Register(w)
|
||||
script.Register(w)
|
||||
scene.Register(w)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package dialog
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
)
|
||||
|
||||
// dexTalk is the standing conversation with Dex. Its branches are gated on
|
||||
// story flags, so the same entry point stays useful as the game progresses.
|
||||
func dexTalk() inkwell.Dialogue {
|
||||
return inkwell.Dialogue{
|
||||
Name: names.DlgDex,
|
||||
Start: "root",
|
||||
Nodes: []inkwell.DialogueNode{{
|
||||
Name: "root",
|
||||
Lines: []inkwell.DialogueLine{{Speaker: names.Dex, Text: "Talk."}},
|
||||
Choices: []inkwell.DialogueChoice{
|
||||
{
|
||||
Text: "What am I doing here, Dex?",
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(names.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(names.FlagHasTape)),
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(names.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(names.FlagHasTape),
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(names.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"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Text: "I miss you.",
|
||||
Once: true,
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(names.Dex, "I'm four kilobytes of a dead man. Don't do this to yourself."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Text: "Nothing. Forget it.",
|
||||
Actions: []inkwell.Action{inkwell.EndDialogue()},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Package dialog registers the game's dialogue trees.
|
||||
//
|
||||
// Talking to a tape carries the same weight as talking to a human NPC — the
|
||||
// wiki states this explicitly. Tapes are dialogue partners, not menus.
|
||||
//
|
||||
// A note on DialogueChoice.Once: inkwell HIDES a spent choice. The wireframe
|
||||
// deck wanted it struck through but still visible, so the list becomes a
|
||||
// memory of what you already tried. That is still open — see README, "Known
|
||||
// gaps".
|
||||
package dialog
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every dialogue to the game.
|
||||
func Register(w *world.World) {
|
||||
for _, d := range []inkwell.Dialogue{
|
||||
dexTalk(),
|
||||
mysteryTapeSilent(),
|
||||
} {
|
||||
w.G.DialogueManager.Register(d)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package dialog
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
)
|
||||
|
||||
// mysteryTapeSilent covers the stretch before the club trigger (beat 6), while
|
||||
// the tape is still mute. Talking to it is really Dex talking about it — the
|
||||
// tape itself says nothing.
|
||||
func mysteryTapeSilent() inkwell.Dialogue {
|
||||
return inkwell.Dialogue{
|
||||
Name: names.DlgMysteryTape,
|
||||
Start: "root",
|
||||
Nodes: []inkwell.DialogueNode{{
|
||||
Name: "root",
|
||||
Lines: []inkwell.DialogueLine{{Speaker: names.Dex, Text: "Nothing. Warm, spinning, and silent."}},
|
||||
Choices: []inkwell.DialogueChoice{
|
||||
{
|
||||
Text: "Are you sure it works?",
|
||||
Actions: []inkwell.Action{
|
||||
inkwell.Say(names.Dex, "It works. It just isn't talking to you. That is not the same as silence."),
|
||||
inkwell.GotoNode("root"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Text: "Fine. It'll speak when it speaks.",
|
||||
Actions: []inkwell.Action{inkwell.EndDialogue()},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// blackMarketArmilla is flavour, not a quest trigger: the gap between
|
||||
// legitimised technology and street reality.
|
||||
func blackMarketArmilla() inkwell.Item {
|
||||
return inkwell.Item{
|
||||
Name: names.ItemBlackArmilla,
|
||||
Description: "black-market Armilla",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "Jailbroken. Pushes ads, but it was cheap."),
|
||||
world.TapeSay(names.Dex, "Two slots, and both of them lie about the temperature. Don't trade me in for it."),
|
||||
),
|
||||
OnUseWith: map[string]inkwell.Action{
|
||||
// An AUTHORED failure. Nothing is consumed, the character reacts,
|
||||
// the tape remarks. Never a generic error line.
|
||||
names.ItemNoodleLetter: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "A letter and a bracelet. Brilliant."),
|
||||
world.TapeSay(names.Dex, "Nothing. Which is what I'd charge for it."),
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Package item registers the game's inventory items.
|
||||
//
|
||||
// Personal Tapes are inventory items and quest triggers at the same time: they
|
||||
// go into slot 2 of Paul's Armilla, and loading one activates its effect.
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every item to the game.
|
||||
func Register(w *world.World) {
|
||||
for _, i := range []inkwell.Item{
|
||||
noodleLetter(),
|
||||
blackMarketArmilla(),
|
||||
mysteryTape(),
|
||||
} {
|
||||
w.G.ItemManager.Register(i)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// mysteryTape is the engine of the investigation. Password-locked; it only
|
||||
// starts speaking after the club trigger (beat 6).
|
||||
func mysteryTape() inkwell.Item {
|
||||
return inkwell.Item{
|
||||
Name: names.ItemMysteryTape,
|
||||
Description: "unmarked Personal Tape",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "Password-locked. Of course."),
|
||||
world.TapeSay(names.Dex, "Put it in the second slot if you care that much. I did warn you."),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// noodleLetter starts the story: it is what brings Paul to the city.
|
||||
func noodleLetter() inkwell.Item {
|
||||
return inkwell.Item{
|
||||
Name: names.ItemNoodleLetter,
|
||||
Description: "Noodle's letter",
|
||||
OnUseSelf: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "“Come out, Paul. Not a phone conversation.” That's all it says."),
|
||||
world.TapeSay(names.Dex, "And now you're here. And he isn't."),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// alley is the alley behind Noodle's house — beat 3, and the vertical slice
|
||||
// the whole HUD is measured against: hotspots, a gated pickup, the two-slot
|
||||
// Armilla, tape dialogue and an authored failure.
|
||||
func alley(w *world.World) inkwell.Scene {
|
||||
return inkwell.Scene{
|
||||
Name: names.SceneAlley,
|
||||
Title: "ALLEY — BEHIND NOODLE'S HOUSE",
|
||||
Background: names.AssetAlleyBG,
|
||||
Actors: []inkwell.SceneActor{
|
||||
{CharacterName: names.Paul, At: inkwell.Point{X: 120, Y: 232}},
|
||||
},
|
||||
Walkboxes: []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},
|
||||
),
|
||||
},
|
||||
OnEnter: inkwell.Seq(
|
||||
world.EnterScene(w, names.SceneAlley),
|
||||
setVarIfEmpty(names.VarArmillaStrip, "SRP: 1 tape"),
|
||||
),
|
||||
Hotspots: []inkwell.Hotspot{
|
||||
hidingPlace(),
|
||||
backDoor(),
|
||||
bin(),
|
||||
fireEscape(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// hidingPlace holds the mystery tape. It only opens once Paul has the tip from
|
||||
// the police station (beat 2) — without it he does not know what to look for.
|
||||
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(names.FlagHasTape),
|
||||
inkwell.Say(names.Paul, "Empty. Whatever was in there is on me now."),
|
||||
inkwell.Say(names.Paul, "Loose brick. There's a gap behind it."),
|
||||
),
|
||||
OnUse: inkwell.If(inkwell.Flag(names.FlagPoliceTip),
|
||||
inkwell.If(inkwell.Flag(names.FlagHasTape),
|
||||
inkwell.Say(names.Paul, "There's nothing else in there."),
|
||||
inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "“Behind the brick.” All right then."),
|
||||
inkwell.Give(names.ItemMysteryTape),
|
||||
inkwell.SetFlag(names.FlagHasTape),
|
||||
inkwell.Say(names.Paul, "A Personal Tape. No label, no seal."),
|
||||
world.TapeSay(names.Dex, "Password-locked. And somebody very much did not want it found."),
|
||||
),
|
||||
),
|
||||
inkwell.Say(names.Paul, "One loose brick. I'm not taking the alley apart over it."),
|
||||
),
|
||||
OnTake: inkwell.Say(names.Paul, "I'm not carrying a wall."),
|
||||
}
|
||||
}
|
||||
|
||||
// backDoor is the New Game+ hook: the code can be entered on the first visit
|
||||
// too, if the player already knows it.
|
||||
func backDoor() inkwell.Hotspot {
|
||||
return inkwell.Hotspot{
|
||||
Name: "back_door",
|
||||
Label: "locked back door",
|
||||
Area: inkwell.Rect(72, 106, 80, 124),
|
||||
OnLook: inkwell.Say(names.Paul, "Keypad. Four digits, worn keys."),
|
||||
OnUse: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "Locked. And I'm not guessing four digits."),
|
||||
world.TapeSay(names.Dex, "The wear is heaviest on the two and the seven. That isn't a code. It's fewer options."),
|
||||
),
|
||||
OnTalk: inkwell.Say(names.Paul, "To the door? I'm not there yet."),
|
||||
OnUseWith: map[string]inkwell.Action{
|
||||
// An AUTHORED failure — not the engine's hardcoded flash.
|
||||
names.ItemBlackArmilla: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "A black-market bracelet doesn't open a keypad."),
|
||||
world.TapeSay(names.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(names.Paul, "Somebody's been through it. Thoroughly."),
|
||||
OnUse: inkwell.Seq(
|
||||
inkwell.Say(names.Paul, "Already turned out. I'm not going to be the second one."),
|
||||
world.TapeSay(names.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(names.Paul, "Runs all the way to the roof. Bottom rung is two metres over my head."),
|
||||
OnUse: inkwell.Say(names.Paul, "Can't reach it. I'd need something to stand on."),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Package scene registers the game's scenes.
|
||||
package scene
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every scene to the game.
|
||||
func Register(w *world.World) {
|
||||
for _, s := range []inkwell.Scene{
|
||||
alley(w),
|
||||
} {
|
||||
w.G.SceneManager.Register(s)
|
||||
}
|
||||
}
|
||||
|
||||
// setVarIfEmpty only writes when the variable is still unset, so re-entering a
|
||||
// scene does not clobber what the game has set in the meantime.
|
||||
func setVarIfEmpty(name string, v any) inkwell.Action {
|
||||
return world.Fn(func(ctx *inkwell.Ctx) {
|
||||
if ctx.Game.State.Var(name) == nil {
|
||||
ctx.Game.State.SetVar(name, v)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/theme"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// awakeningFinale is the end of game two. The point of it, mechanically, is
|
||||
// the theme switch: this is where the Nokia-punk texture breaks in.
|
||||
//
|
||||
// Run it early and often during development (`go run . -finale`) — it is the
|
||||
// single most important visual beat in the game, so you want to be looking at
|
||||
// it long before the surrounding scene exists.
|
||||
func awakeningFinale(w *world.World) inkwell.Script {
|
||||
return inkwell.Script{
|
||||
Name: names.ScriptFinale,
|
||||
Actions: inkwell.Seq(
|
||||
world.SetMode(w, world.ModeCutscene),
|
||||
inkwell.Wait(0.6),
|
||||
inkwell.Say(names.Paul, "I'm putting it in. That's all this is."),
|
||||
inkwell.Wait(0.4),
|
||||
world.UseTheme(theme.NokiaPunk),
|
||||
inkwell.Say("norman", "No — this isn't what you were supposed to do!"),
|
||||
inkwell.Wait(0.6),
|
||||
world.TapeSay(names.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"),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Package script registers the game's named, reusable action sequences —
|
||||
// cutscenes and recurring logic, built from the inkwell action set.
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// Register adds every script to the game.
|
||||
func Register(w *world.World) {
|
||||
for _, s := range []inkwell.Script{
|
||||
tapeInsert(w),
|
||||
awakeningFinale(w),
|
||||
} {
|
||||
w.G.ScriptManager.Register(s)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
inkwell "git.teletypegames.org/engines/inkwell"
|
||||
|
||||
"realworld/internal/names"
|
||||
"realworld/internal/world"
|
||||
)
|
||||
|
||||
// tapeInsert runs whenever a tape goes into slot 2: it activates the tape and
|
||||
// makes Dex comment. The wiki calls the comment mandatory — Dex remarks on
|
||||
// every newly loaded tape, without exception.
|
||||
func tapeInsert(w *world.World) inkwell.Script {
|
||||
return inkwell.Script{
|
||||
Name: names.ScriptTapeInsert,
|
||||
Actions: inkwell.Seq(
|
||||
world.Fn(func(ctx *inkwell.Ctx) {
|
||||
item := w.TakePending()
|
||||
if item == "" {
|
||||
return
|
||||
}
|
||||
w.SetSlot2(item)
|
||||
ctx.Game.Inventory.Remove(item)
|
||||
ctx.Game.State.SetVar(names.VarArmillaStrip, "SLOT2: READING")
|
||||
}),
|
||||
inkwell.Say(names.Paul, "Right. Let's see who you are."),
|
||||
world.TapeSay(names.Dex, "Clicked in. Spinning. And now: nothing."),
|
||||
world.TapeSay(names.Dex, "A stranger's tape in your own Armilla, Paul. I hope you know what you're doing."),
|
||||
),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user