Documentation
¶
Overview ¶
Package inkwell is a point-and-click adventure game library built on top of Ebitengine. Games are composed declaratively by registering plain struct literals into per-entity *Manager registries hanging off the *Game root.
See PLAN.md in the repo root for the full design notes.
Index ¶
- Variables
- func RegisterDefaultUI(g *Game)
- func RegisterPresetThemes(g *Game)
- func RegisterRadialVerbUI(g *Game)
- func RegisterRichUI(g *Game, playerName, npcName string)
- func Run(g *Game) error
- type Action
- func ClearFlag(name string) Action
- func Custom(fn func(*Ctx) Status) Action
- func EndDialogue() Action
- func Give(item string) Action
- func GoTo(scene string) Action
- func GotoNode(node string) Action
- func If(cond Condition, then Action, els ...Action) Action
- func Par(actions ...Action) Action
- func PlayMusic(name string) Action
- func PlaySound(name string) Action
- func RequireItem(item string) Action
- func RunDialogue(name string) Action
- func RunScript(name string) Action
- func Say(speaker, text string) Action
- func Seq(actions ...Action) Action
- func SetFlag(name string) Action
- func SetVar(name string, v any) Action
- func ShowEnd(text string) Action
- func StopMusic() Action
- func TakeAway(item string) Action
- func Wait(seconds float64) Action
- func Walk(character string, to Point) Action
- type Align
- type AnimationClip
- type Asset
- type AssetKind
- type AssetManager
- type AudioPlayer
- type Camera
- type CharStat
- type Character
- type CharacterManager
- type CharacterPanel
- type ChatLog
- type Condition
- type Ctx
- type Cursor
- type CursorKind
- type DialogBox
- type Dialogue
- type DialogueChoice
- type DialogueLine
- type DialogueManager
- type DialogueNode
- type EndCard
- type Game
- func (g *Game) CharacterInScene(name string) bool
- func (g *Game) ClearSpeech()
- func (g *Game) DrawText(dst *ebiten.Image, s string, x, y int, c color.Color)
- func (g *Game) FlashLine(text string)
- func (g *Game) HotspotAt(p Point) *Hotspot
- func (g *Game) HoverHint() string
- func (g *Game) HoverLabel() string
- func (g *Game) Load(slot int) error
- func (g *Game) LogAction(text string)
- func (g *Game) LogResponse(speaker, text string)
- func (g *Game) LogSystem(text string)
- func (g *Game) Messages() []LogMessage
- func (g *Game) OnStart(a Action) *Game
- func (g *Game) Run() error
- func (g *Game) Save(slot int) error
- func (g *Game) SelectedVerb() string
- func (g *Game) SetHoverLabel(s string)
- func (g *Game) SetSelectedVerb(s string)
- func (g *Game) SetSpeech(speaker, text string)
- func (g *Game) StartAt(name string) *Game
- func (g *Game) Theme() Theme
- func (g *Game) UseTheme(name string)
- func (g *Game) Validate() error
- type Hotspot
- type HotspotDebug
- type Input
- type Inventory
- type InventoryBar
- type Item
- type ItemManager
- type LogKind
- type LogMessage
- type Manager
- func (m *Manager[T]) Each(fn func(T))
- func (m *Manager[T]) Get(name string) (T, bool)
- func (m *Manager[T]) Has(name string) bool
- func (m *Manager[T]) Len() int
- func (m *Manager[T]) MustGet(name string) T
- func (m *Manager[T]) Names() []string
- func (m *Manager[T]) Register(v T)
- func (m *Manager[T]) Remove(name string)
- func (m *Manager[T]) SortedNames() []string
- type MouseButton
- type Named
- type Panel
- type Point
- type Polygon
- type RadialVerbs
- type Rectangle
- type Runner
- type Scene
- type SceneActor
- type SceneManager
- type Script
- type ScriptManager
- type Shape
- type Size
- type SpeechBubble
- type State
- func (s *State) ClearFlag(name string)
- func (s *State) Flag(name string) bool
- func (s *State) NoteTalked(node string)
- func (s *State) NoteVisit(name string)
- func (s *State) SetFlag(name string)
- func (s *State) SetVar(name string, v any)
- func (s *State) Talked(node string) int
- func (s *State) Var(name string) any
- func (s *State) Visited(name string) int
- type Status
- type StatusLine
- type Theme
- type ThemeManager
- type Timer
- type TopBar
- type Trigger
- type UICtx
- type UIManager
- type Verb
- type VerbBar
- type VerbManager
- type Widget
Constants ¶
This section is empty.
Variables ¶
var ( ErrUnknownAsset = errors.New("inkwell: unknown asset") ErrUnknownScene = errors.New("inkwell: unknown scene") ErrUnknownItem = errors.New("inkwell: unknown item") ErrUnknownCharacter = errors.New("inkwell: unknown character") ErrUnknownDialogue = errors.New("inkwell: unknown dialogue") ErrUnknownDialogueNode = errors.New("inkwell: unknown dialogue node") ErrUnknownScript = errors.New("inkwell: unknown script") ErrUnknownVerb = errors.New("inkwell: unknown verb") ErrDuplicateName = errors.New("inkwell: duplicate name") ErrNoStartScene = errors.New("inkwell: StartAt not set or unknown scene") ErrSceneMissingBackground = errors.New("inkwell: scene has no background") )
var AssetFS fs.FS
AssetFS, when non-nil, is the filesystem asset files (images, audio) are read from instead of the OS filesystem. Set it to an embed.FS before Run to ship assets inside the binary — required for js/wasm builds, where there is no OS filesystem and every asset would fall back to a placeholder:
//go:embed assets
var assetsFS embed.FS
func init() { inkwell.AssetFS = assetsFS }
Asset.Path values are used as-is, so they must be slash-separated and relative (e.g. "assets/bg/bedroom.png") — the same form that works with os.Open from the project root.
var DebugLog = false
Functions ¶
func RegisterDefaultUI ¶
func RegisterDefaultUI(g *Game)
RegisterDefaultUI installs the SCUMM-style HUD widgets into g.UIManager in the conventional Z-order (HotspotDebug at the back, Cursor on top). Domains that want a different layout call this and then either tweak the registered widgets in place or replace them entirely.
Layout assumes the default 320×200 internal resolution.
func RegisterPresetThemes ¶
func RegisterPresetThemes(g *Game)
RegisterPresetThemes installs the four built-in themes. NewGame calls this automatically and selects "classic-scumm".
func RegisterRadialVerbUI ¶
func RegisterRadialVerbUI(g *Game)
RegisterRadialVerbUI installs an alternative HUD that swaps the permanent verb-bar for a verb-coin (right-click radial menu). Inventory, dialog, speech and cursor stay the same.
func RegisterRichUI ¶
RegisterRichUI installs a "story-rich" HUD that matches the layout of the screenshot used as the reference: top bar with title/score/time, floating character panels for the player and a single NPC, a chat-log strip at the bottom-left, a tiny inventory at the bottom-right and a permanent verb-wheel on the right edge.
The HUD assumes the default 320×200 internal resolution and that PlayerName / NPCName correspond to registered characters. Pass "" for NPCName to skip the NPC panel.
Types ¶
type Action ¶
type Action interface {
Start() Runner
}
Action is an immutable spec of work; Start makes a fresh Runner with state. Storing an Action in a struct field (e.g. Hotspot.OnUse) is safe because the engine always calls Start before ticking, so two invocations can never share mutable state.
func Custom ¶
Custom wraps a user function as an Action. Returns Done on first tick unless the function itself returns StatusRunning.
func EndDialogue ¶
func EndDialogue() Action
func RequireItem ¶
func RunDialogue ¶
type Align ¶
type Align int
Align controls horizontal text alignment for widgets that draw a single line.
type AnimationClip ¶
AnimationClip describes one named sprite-sheet animation. Frames are source rectangles into the character's Sprite asset; the renderer projects them onto the character's screen-space W×H footprint.
FrameTime is the time (seconds) each frame is shown; Loop=true rewinds to the first frame after the last, Loop=false freezes on the final frame. A clip with zero frames or zero FrameTime is treated as static and the renderer falls back to the whole-sprite draw path.
type AssetManager ¶
type AudioPlayer ¶
type AudioPlayer struct {
// contains filtered or unexported fields
}
AudioPlayer plays music and one-shot sound effects through Ebiten's audio subsystem. Music is streamed and looped infinitely; sound effects are decoded once, cached as raw PCM, and replayed via NewPlayerFromBytes for low-latency triggering.
AudioPlayer is fail-soft by design: missing asset files, decode errors and a missing audio device all degrade to no-ops with a debug log message — the game keeps running. The action constructors (PlayMusic/PlaySound/StopMusic) call through here unchanged.
func NewAudioPlayer ¶
func NewAudioPlayer() *AudioPlayer
func (*AudioPlayer) PlayMusic ¶
func (a *AudioPlayer) PlayMusic(name string)
func (*AudioPlayer) PlaySound ¶
func (a *AudioPlayer) PlaySound(name string)
func (*AudioPlayer) StopMusic ¶
func (a *AudioPlayer) StopMusic()
type Camera ¶
type Camera struct {
Offset Point
}
Camera is a stub identity transform — no scrolling in this milestone.
type CharStat ¶
CharStat is one (Label, VarKey) row rendered inside a CharacterPanel. VarKey is read from g.State.Var; the value is fmt.Sprint'd verbatim.
type Character ¶
type CharacterManager ¶
type CharacterPanel ¶
type CharacterPanel struct {
Name string
Bounds Rectangle
Character string // Character.Name to display
Title string // "PLAYER", "NPC", role badge
Stats []CharStat
}
CharacterPanel is a small floating panel that shows portrait + stats for one registered character. The panel auto-hides when the character isn't listed as an actor in the current scene, so the same panel registration works across scenes.
func (*CharacterPanel) BlocksClickAt ¶
func (c *CharacterPanel) BlocksClickAt(p Point) bool
BlocksClickAt — the panel sits on top of the scene; clicks inside it shouldn't trigger hotspots underneath.
func (*CharacterPanel) GetName ¶
func (c *CharacterPanel) GetName() string
func (*CharacterPanel) Tick ¶
func (c *CharacterPanel) Tick(ctx *UICtx)
type ChatLog ¶
type ChatLog struct {
Name string
Bounds Rectangle
LineHeight int
Padding int
// ShowBorder draws a thin border around the box.
ShowBorder bool
}
ChatLog renders the in-game message log (player commands + in-world replies) as a scrolling box. The newest message is at the bottom; older messages scroll up out of view as the buffer fills.
func (*ChatLog) BlocksClickAt ¶
BlocksClickAt — the log is non-interactive, but it sits over the bottom of the scene; treat it as opaque so RadialVerbs doesn't pop up over it.
type Condition ¶
func SelectedItem ¶
type Cursor ¶
type Cursor struct {
Name string
}
Cursor renders the mouse cursor. When the player has an inventory item selected, the item's sprite is drawn at the cursor instead of the default crosshair. Registered last so it draws on top.
type CursorKind ¶
type CursorKind int
const ( CursorDefault CursorKind = iota CursorLook CursorUse CursorTalk CursorTake CursorExit )
type DialogBox ¶
DialogBox renders the active conversation: one line at a time (advanced on click) followed by the player's choices. The widget is dormant unless ctx.Game.dialogueActive() — and while active it consumes input so nothing underneath reacts.
func (*DialogBox) BlocksClickAt ¶
BlocksClickAt — when a dialog is open, every click is ours.
type Dialogue ¶
type Dialogue struct {
Name string
Start string
Nodes []DialogueNode
}
type DialogueChoice ¶
type DialogueLine ¶
type DialogueManager ¶
type DialogueNode ¶
type DialogueNode struct {
Name string
Lines []DialogueLine
Choices []DialogueChoice
}
type EndCard ¶
type EndCard struct {
Name string
}
EndCard is a fullscreen overlay shown when the ShowEnd action fires. While active it consumes every input so nothing underneath reacts.
type Game ¶
type Game struct {
Title string
Width, Height int
ItemManager *ItemManager
SceneManager *SceneManager
CharacterManager *CharacterManager
DialogueManager *DialogueManager
ScriptManager *ScriptManager
AssetManager *AssetManager
VerbManager *VerbManager
UIManager *UIManager
ThemeManager *ThemeManager
State *State
Inventory *Inventory
Audio *AudioPlayer
Camera *Camera
Input *Input
MaxLogLines int // 0 = unlimited (memory grows); set per-game.
// SaveDir overrides the on-disk directory used by Save/Load.
// Empty falls back to "saves" relative to the working directory.
SaveDir string
// contains filtered or unexported fields
}
Game is the root aggregate. It carries every Manager plus the runtime state. A domain package builds one via NewGame, registers entities, optionally calls RegisterDefaultUI / UseTheme, then hands it to Run.
func NewGame ¶
NewGame initializes a game with empty entity managers, the SCUMM-style verb set, all preset themes, and "classic-scumm" selected. Widgets are NOT auto-registered — call RegisterDefaultUI(g) explicitly.
func (*Game) CharacterInScene ¶
CharacterInScene reports whether a registered character is listed as an actor in the current scene. Used by the CharacterPanel widget so it auto-hides when the character isn't in view.
func (*Game) ClearSpeech ¶
func (g *Game) ClearSpeech()
func (*Game) DrawText ¶
DrawText is a thin wrapper that lets widgets accept a Theme-supplied color today and switch to text/v2 later without changing call sites.
func (*Game) HotspotAt ¶
HotspotAt returns the topmost hotspot in the current scene whose Area contains p, or nil if none. Exposed so widgets (e.g., a verb coin that only opens over hotspots) can do their own hit-tests in their Tick — the engine's own resolution runs only after every widget had a chance, so widgets can't rely on it.
func (*Game) HoverLabel ¶
func (*Game) Load ¶
Load replaces the runtime state with the contents of saves/slot<N>.json. Managers (items, scenes, characters, …) are left intact — Build() owns those. References in the save (scene name, theme, character names) are validated against the current managers before any state is touched.
func (*Game) LogAction ¶
LogAction appends a player-command line (rendered with the prompt color by ChatLog widgets).
func (*Game) LogResponse ¶
LogResponse appends a reply line (rendered with the response color).
func (*Game) Messages ¶
func (g *Game) Messages() []LogMessage
Messages returns the current log buffer (read-only).
func (*Game) Save ¶
Save serialises the current session into saves/slot<N>.json (or SaveDir/slot<N>.json if set). The in-flight script and dialog are dropped — saves capture state at idle/ready boundaries.
func (*Game) SelectedVerb ¶
func (*Game) SetHoverLabel ¶
func (*Game) SetSelectedVerb ¶
type Hotspot ¶
type Hotspot struct {
Name string
Area Shape
Label string
Cursor CursorKind
OnLook Action
OnUse Action
OnTalk Action
OnTake Action
OnGive Action
// OnUseWith: when the player has an item selected and clicks this hotspot,
// the engine looks up the item's Name here first.
OnUseWith map[string]Action
// OnVerb: custom verbs registered via g.VerbManager.
OnVerb map[string]Action
}
type HotspotDebug ¶
type HotspotDebug struct {
Name string
Enabled bool
// ToggleKey, if non-zero, overrides the default F1 toggle.
ToggleKey ebiten.Key
}
HotspotDebug overlays a colored outline on every hotspot of the current scene. F1 toggles it at runtime; the default is off.
func (*HotspotDebug) GetName ¶
func (h *HotspotDebug) GetName() string
func (*HotspotDebug) Tick ¶
func (h *HotspotDebug) Tick(ctx *UICtx)
type Input ¶
type Input struct {
// contains filtered or unexported fields
}
Input is read once per Update() and exposes a tiny "consume on use" API so that one click can be authoritative — e.g. clicking on a hotspot while a Say is active should only skip the Say, not also fire the hotspot underneath.
func (*Input) ConsumeLeft ¶
func (i *Input) ConsumeLeft()
func (*Input) ConsumeRight ¶
func (i *Input) ConsumeRight()
func (*Input) LeftClicked ¶
func (*Input) RightClicked ¶
type Inventory ¶
type Inventory struct {
// contains filtered or unexported fields
}
func NewInventory ¶
func NewInventory() *Inventory
type InventoryBar ¶
type InventoryBar struct {
Name string
Origin Point
Slots int
Cols int
SlotSize int
Gap int
PanelBG bool
}
InventoryBar shows the player's items as clickable slots. Left-click on a slot under the "look" verb prints the item's description; under any other verb, it toggles selection (the cursor "picks up" the item).
func (*InventoryBar) BlocksClickAt ¶
func (b *InventoryBar) BlocksClickAt(p Point) bool
BlocksClickAt — clickBlocker contract for the RadialVerbs widget.
func (*InventoryBar) GetName ¶
func (b *InventoryBar) GetName() string
func (*InventoryBar) Tick ¶
func (b *InventoryBar) Tick(ctx *UICtx)
type Item ¶
type ItemManager ¶
type LogKind ¶
type LogKind int
LogKind classifies a chat-log entry — UI widgets style them differently.
type LogMessage ¶
LogMessage is a single line in the chat-log buffer.
type Manager ¶
type Manager[T Named] struct { // contains filtered or unexported fields }
Manager is the single registry shape used by every entity type. Each entity kind gets a named alias (ItemManager = Manager[Item], etc.). Insertion order is preserved — Names() returns it. SortedNames() returns alphabetical.
func NewManager ¶
func (*Manager[T]) Names ¶
Names returns the registered names in insertion order. Use SortedNames when iteration order needs to be stable across runs.
func (*Manager[T]) Register ¶
func (m *Manager[T]) Register(v T)
Register adds v to the registry. Panics on empty or duplicate name — these are construction-time bugs, not runtime conditions.
func (*Manager[T]) Remove ¶
Remove drops a registered entry. Used by hot-reload / dynamic UI changes. Silently no-ops on unknown names.
func (*Manager[T]) SortedNames ¶
type MouseButton ¶
type MouseButton int
MouseButton identifies which mouse button a widget binds to (e.g. the RadialVerbs widget uses MouseButtonRight by default).
const ( MouseButtonLeft MouseButton = iota MouseButtonRight )
type Named ¶
type Named interface {
GetName() string
}
Named is implemented by every entity that can be registered into a Manager.
type Panel ¶
type Panel struct {
Name string
Bounds Rectangle
// BG, if nil, falls back to the active Theme.PanelBG.
BG color.Color
// Border thickness in pixels (0 = no border).
Border int
// BorderColor, if nil, falls back to Theme.DialogBorder.
BorderColor color.Color
}
Panel is a generic background widget — a colored rectangle. Useful as a backdrop for grouping other widgets or as a chat/notebook frame.
type RadialVerbs ¶
type RadialVerbs struct {
Name string
Trigger MouseButton
Radius float64
// AlwaysVisible turns the widget into a permanent verb-wheel fixed at
// Center. The trigger button is ignored in this mode; left-click picks
// the verb slice under the cursor.
AlwaysVisible bool
Center Point
// HotspotOnly (trigger mode only) makes the wheel open only when the
// trigger lands on a registered hotspot in the current scene. Right-
// clicks on empty space fall through to handleSceneInput (so the
// SCUMM "reset verb to look" behaviour still works there).
HotspotOnly bool
// Labels overrides the rendered verb label per verb Name. Useful when
// the regular Verb.Label is too long to fit inside the wheel — e.g.
// {"use": "Tedd", "take": "Vedd"}. Falls back to Verb.Label.
Labels map[string]string
// contains filtered or unexported fields
}
RadialVerbs is the verb-coin alternative to VerbBar: secondary-click on the scene opens a radial menu of every registered verb, click on a slice (or close to its center) picks that verb.
To use it instead of a VerbBar, register RadialVerbs and skip VerbBar. Both can coexist if you really want.
func (*RadialVerbs) BlocksClickAt ¶
func (r *RadialVerbs) BlocksClickAt(p Point) bool
BlocksClickAt — when the wheel is open (or always visible), clicks on it should not pass through to the scene underneath.
func (*RadialVerbs) GetName ¶
func (r *RadialVerbs) GetName() string
func (*RadialVerbs) Tick ¶
func (r *RadialVerbs) Tick(ctx *UICtx)
type Runner ¶
Runner is one in-flight execution of an Action. Tick advances it one frame and returns whether it's still running, done, or failed.
type Scene ¶
type SceneActor ¶
SceneActor places a registered Character at a starting position inside a scene.
type SceneManager ¶
type ScriptManager ¶
type SpeechBubble ¶
SpeechBubble renders the line set by the Say action above the speaking character (or at FallbackY if the speaker has no on-screen position).
func (*SpeechBubble) GetName ¶
func (s *SpeechBubble) GetName() string
func (*SpeechBubble) Tick ¶
func (s *SpeechBubble) Tick(ctx *UICtx)
type State ¶
type State struct {
// contains filtered or unexported fields
}
func (*State) NoteTalked ¶
type StatusLine ¶
type StatusLine struct {
Name string
Y int
Align Align
// ScreenWidth, if 0, uses Game.Width.
ScreenWidth int
}
StatusLine renders a single line: either the active flash message (set by FlashLine) or the hover-hint (verb + target under the cursor).
func (*StatusLine) GetName ¶
func (s *StatusLine) GetName() string
func (*StatusLine) Tick ¶
func (s *StatusLine) Tick(ctx *UICtx)
type Theme ¶
type Theme struct {
Name string
PanelBG color.Color
StatusText color.Color
FlashText color.Color
VerbButtonBG color.Color
VerbButtonSelectedBG color.Color
VerbButtonText color.Color
InventorySlotBG color.Color
InventorySlotSelectedBG color.Color
SpeechBubbleBG color.Color
SpeechDefaultText color.Color
DialogBG color.Color
DialogBorder color.Color
DialogChoiceBG color.Color
DialogChoiceHover color.Color
DialogSpeaker color.Color
DialogText color.Color
EndCardBG color.Color
EndCardText color.Color
CursorColor color.Color
HotspotOutline color.Color
// SceneBackdrop is painted before the scene background. Useful for
// letterboxing or filling areas not covered by a smaller backdrop.
SceneBackdrop color.Color
// Rich-UI widgets (TopBar, CharacterPanel, ChatLog).
TopBarBG color.Color
TopBarText color.Color
TopBarAccent color.Color // score / highlighted number color
ChatLogBG color.Color
ChatLogPrompt color.Color // "> look at door" lines
ChatLogResponse color.Color // in-world reply lines
ChatLogSystem color.Color // system / meta lines
CharacterPanelBG color.Color
CharacterPanelBorder color.Color
CharacterPanelTitle color.Color // "PLAYER" / "NPC" badge color
}
Theme is a registry-stored entity carrying every color the built-in widgets read. Multiple themes can be registered; the active one is addressed by name on the Game.
type ThemeManager ¶
type Timer ¶
type Timer struct {
Elapsed float64
}
Timer accumulates seconds. Tick advances it; Reset zeroes it.
type TopBar ¶
type TopBar struct {
Name string
Height int
// LeftText overrides the auto-discovered scene Title/Name.
LeftText string
// ScoreVar is a State Var key whose value is fmt-printed as the
// center score; empty = no score shown.
ScoreVar string
ScoreMax int // when >0, rendered as "Score: X/MAX"
// TimeVar is a State Var key whose value is printed at the right
// edge (e.g. "Day 2 - 14:32"); empty = nothing on the right.
TimeVar string
}
TopBar is a thin strip across the top of the screen with three sections: scene title on the left, a score number in the center, and a day/time string on the right. Empty fields are skipped.
func (*TopBar) BlocksClickAt ¶
BlocksClickAt — the TopBar swallows clicks so the radial menu doesn't pop up under it.
type Trigger ¶
Trigger fires Do when its When condition first becomes true after the trigger arms (on scene enter). Rising-edge semantics: the Do action is queued only on a false→true transition, so a condition that becomes true and stays true fires exactly once per arming. Once=true makes the trigger fire at most once per arming regardless of further toggles.
type UICtx ¶
UICtx is the per-tick context handed to widgets. Game is the root aggregate; DT is seconds since the previous frame.
type Verb ¶
Verb is a registered "action word" (Look, Use, Talk, Take, …). The VerbBar / RadialVerbs widgets read the VerbManager to know which verbs to render; Hotspot.handler(name) looks up the bound action by Verb.Name.
type VerbBar ¶
type VerbBar struct {
Name string
Origin Point
Cols int
Button Size
Gap Point
// PanelBG, if non-nil, paints a backdrop behind the buttons. nil = use Theme.PanelBG.
PanelBG bool
}
VerbBar is the SCUMM-style permanent verb panel. It reads the VerbManager every frame so newly-registered verbs show up automatically.
func (*VerbBar) BlocksClickAt ¶
BlocksClickAt is part of the clickBlocker contract — keeps the RadialVerbs widget from popping up over the verb bar.
type VerbManager ¶
type Widget ¶
Widget is the minimal surface a HUD element must implement to participate in the per-frame loop. The library ships several built-in widgets (VerbBar, InventoryBar, DialogBox, etc.) and the domain can register arbitrary new ones — chat panels, minimaps, hotbars — as long as they satisfy this interface.
Lifecycle:
- Tick runs once per frame in REVERSE registration order so the top-most widget gets a chance to consume input first via ctx.Game.Input.ConsumeLeft / ConsumeRight.
- Draw runs once per frame in REGISTRATION order, so widgets registered later are painted on top.
Source Files
¶
- action.condition.go
- action.def.go
- action.manager.go
- action.script.go
- actor.animation.go
- actor.def.go
- actor.manager.go
- asset.audio.go
- asset.def.go
- asset.fs.go
- asset.manager.go
- asset.text.go
- core.doc.go
- core.dsl.go
- core.engine.go
- core.errors.go
- core.game.go
- core.manager.go
- dialog.def.go
- dialog.manager.go
- input.def.go
- item.def.go
- item.inventory.go
- item.manager.go
- scene.camera.go
- scene.def.go
- scene.hotspot.go
- scene.manager.go
- scene.path.go
- scene.transition.go
- scene.trigger.go
- state.def.go
- state.save.go
- ui.character_panel.go
- ui.chat_log.go
- ui.cursor.go
- ui.defaults.go
- ui.dialog_box.go
- ui.end_card.go
- ui.hotspot_debug.go
- ui.inventory.go
- ui.manager.go
- ui.panel.go
- ui.speech.go
- ui.status.go
- ui.theme.go
- ui.theme_presets.go
- ui.top_bar.go
- ui.verb.go
- ui.verb_bar.go
- ui.verb_radial.go
- ui.widget.go
- util.geometry.go
- util.log.go
- util.timer.go