Documentation
ΒΆ
Overview ΒΆ
Package gram is a modular 2D game engine for Go: a user-implemented game.Game β a named set of game.Stage values, each with its own entity-component world and its own [game.Scene]s β driven through Ebitengine's Update/Draw/Layout loop by an engine that wraps the goke ECS. Everything beyond the tick loop is a plugin.Plugin: the built-in ones give a Stage a world of moving boxes, collisions, sight, a board with terrain, pathfinding and mouse selection; a game adds its own the same way. Run is the whole public surface of this package.
Game, Stage and Scene ΒΆ
A Game supplies game.Props (window, tick rate) and its Stages by name, plus which one starts. A Stage is one self-contained context the game can be in β a menu, the gameplay, a map screen β with its own goke ECS, built fresh the moment game.Runtime.SwitchStage enters it, so a menu Stage sits idle with no gameplay entities until the player starts. Its lifecycle is Init (install plugins through a game.Initializer), Restore (resume from a save, or report there is none), Spawn (seed the initial state, only when Restore found nothing) and Update (one tick).
Within a Stage, a Scene is one thing it can show: its renderers (Layers, built once on entering the Stage) and its input handling. The Stage's game.Scenes is the static registry of its Scenes; the live game.Composition over it says which are visible, in what order, and which is active β the topmost focusable one, the only Scene whose HandleEvents runs. A Stage has no input handling of its own. game.Runtime is one undivided interface β pause, quit, switch Stage, persistence, the camera β that reaches a Stage and every Scene alike.
Plugins and behaviors ΒΆ
A plugin.Plugin is installed from Stage.Init through ctx.Use. Its Install only queues ECS wiring; the engine flushes it all in one ecs.Setup after Init returns, which is what lets Restore decide fresh-spawn or restore before the ECS commits to either. A plugin needing another plugin takes it as a constructor argument β construction order in the game's code is the dependency order; there is no registry, no lookup by name and no install-order retry.
Game logic that reacts to what a plugin finds is a behavior, registered on the plugin it concerns and run inside that plugin's own pass: plugin.Between of a payload for every pair of entities the plugin meets, one carrying tag A and the other B; plugin.Each of a payload for every entity carrying T. The payload type says whose the behavior is β a Meeting is collision's, a Sighting is vision's β and a plugin refuses one made for another, so registering in the wrong place is an error, never a silent no-op.
Kinds and spawning ΒΆ
What an entity is comes from a kind, defined in Stage.Init with package plugins/world/kind: a Spec lists the components every entity of the kind carries, each the same for all (Const) or read from that entity's own row (Load). Define hands back the kind; its Entry puts one entity on the world's roster (Seed), and the engine spawns the roster (Populate) only when nothing was restored. Kinds also tell save files which component types to expect, so a game's own tags and state survive a save without being registered anywhere else.
Tick ΒΆ
Props.TargetTPS is the engine's one fixed step. Ebitengine runs one Update per frame; a frame that falls behind runs at most five steps and drops the rest, so the game slows down instead of spiralling. Each step calls the active Scene's HandleEvents, then Stage.Update, where the game runs its plugins' RunPlan in the order it needs β world first, then whatever reads the world's space (collision, vision, ...), as the examples do.
Persistence ΒΆ
game.Persistence saves and loads the active Stage's ECS together with every tracked value's state: a plugin's Serializable, or anything a Stage handed to ctx.Track, such as its Scene Composition. Resources are matched by name β a plugin's Name, or the Go type name of anything else β never by position, so a save survives plugins being added, removed or reordered between game versions. PostLoader and Restorer are the hooks run after a load.
Package dependencies ΒΆ
The packages form a strict acyclic graph; each imports only layers below it:
Layer 0 camera β a Camera over a world: screen conversion, culling, move and zoom
control β the input vocabulary: InputEvents, KeyEvent, ClickEvent, EventHandler
Layer 1 render β drawing primitives: Renderer, Atlas, QuadBatch, sprites (β camera)
Layer 2 plugin β the extension contract: Plugin, Installer, Tick, Between and Each,
PairHost and EachHost, Serializable, PostLoader, Populator (β control, render)
Layer 3 plugins/world/kind β what an entity is: Spec, Const and Load, Define, Of, Registry (β render)
Layer 4 plugins/world β the foundation: Base (Position, Velocity, Caps), the Space,
movement, kinds, Seed and Populate, Attach and Detach, Camera (β camera, control, plugin, kind, render)
Layer 5 game β what a game implements and receives: Game, Stage, Scene, Scenes,
Composition, Initializer, Runtime, Persistence, Props, TPS (β camera, control, plugin, world, render)
plugins/board β a grid with terrain over the world (β world, β¦)
plugins/collision β the Detector over the world's Space; Collider, Physics, Meeting, Struck (β world, β¦)
plugins/selection β mouse input into a Selected tag (β world, β¦)
plugins/vision β a Sight cone into Seen, Sighting, SightOutline (β world, β¦)
Layer 6 plugins/navigation β MoveOrder paths across a board (β board, selection, world, β¦)
plugins/collision/behavior, plugins/vision/behavior β ready-made reactions (β their plugin, world, plugin)
Layer 7 internal/engine β the Engine: the Ebitengine loop, one active Stage, persistence (β game, plugin, world, camera, control, render)
Layer 8 gram β Run; the package you import (β game, internal/engine)
Expressed as a directed graph (arrow = "is imported by"), showing the spine:
camera βββΊ render βββΊ plugin βββΊ plugins/world/kind βββΊ plugins/world βββΊ game βββΊ internal/engine βββΊ gram
control ββββ β β²
βΌ β
plugins/{board, collision, selection, vision} βββΊ plugins/navigation, plugins/*/behavior
Outside the module: goke/v3 is the ECS every Stage runs on, aabbworld the space, collisions and line of sight under the world, ebiten/v2 the loop and the drawing, astar the pathfinding, and uid the entity identifiers.
Index ΒΆ
Constants ΒΆ
This section is empty.
Variables ΒΆ
This section is empty.
Functions ΒΆ
Types ΒΆ
This section is empty.
Directories
ΒΆ
| Path | Synopsis |
|---|---|
|
Package camera is the view onto a world: screen conversion, culling, the visible window and its control.
|
Package camera is the view onto a world: screen conversion, culling, the visible window and its control. |
|
Package control is the input vocabulary: what the engine captures each frame and what a handler is told.
|
Package control is the input vocabulary: what the engine captures each frame and what a handler is told. |
|
examples
|
|
|
collision-demo
command
|
|
|
minimal
command
Command minimal is the smallest gram game that does something: one Stage with a world of bouncing boxes, a collision plugin counting their contacts, and one Scene drawing them.
|
Command minimal is the smallest gram game that does something: one Stage with a world of bouncing boxes, a collision plugin counting their contacts, and one Scene drawing them. |
|
navigation-demo
command
|
|
|
scenes-demo
command
|
|
|
vision-demo
command
Command vision-demo shows ten entities keeping out of each other's way by sight, and one red hunter that lives off the ones who fail at it.
|
Command vision-demo shows ten entities keeping out of each other's way by sight, and one red hunter that lives off the ones who fail at it. |
|
Package game is what a game implements and what it is handed back: the Game the engine drives, its [Stage]s and their [Scene]s, and the Initializer, Runtime and Persistence a Stage or Scene works through.
|
Package game is what a game implements and what it is handed back: the Game the engine drives, its [Stage]s and their [Scene]s, and the Initializer, Runtime and Persistence a Stage or Scene works through. |
|
internal
|
|
|
engine
Package engine is the driver behind gram.Run: the Ebitengine loop, one active Stage and its ECS at a time, and the unexported implementations of the contracts package game declares.
|
Package engine is the driver behind gram.Run: the Ebitengine loop, one active Stage and its ECS at a time, and the unexported implementations of the contracts package game declares. |
|
Package plugin is the extension contract: what a Plugin is, what it is handed at install time, and how game logic is hosted inside a plugin's own pass as a behavior.
|
Package plugin is the extension contract: what a Plugin is, what it is handed at install time, and how game logic is hosted inside a plugin's own pass as a behavior. |
|
plugins
|
|
|
board
Package board lays a square or hex grid over the game world, with per-cell terrain (passability, movement cost, sprite) and occupancy tracking.
|
Package board lays a square or hex grid over the game world, with per-cell terrain (passability, movement cost, sprite) and occupancy tracking. |
|
collision
Package collision detects overlaps between world entities each tick and records what each struck on its Collider.
|
Package collision detects overlaps between world entities each tick and records what each struck on its Collider. |
|
collision/behavior
Package behavior holds ready-made reactions to contacts, each a plain function handed to plugin.Between or plugin.Each: CountContacts for telemetry, ShowHits with HitOverlay to keep a hit visible, LogContacts to write a line per contact.
|
Package behavior holds ready-made reactions to contacts, each a plain function handed to plugin.Between or plugin.Each: CountContacts for telemetry, ShowHits with HitOverlay to keep a hit visible, LogContacts to write a line per contact. |
|
navigation
Package navigation moves entities along a MoveOrder's path across a board, re-pathing automatically when terrain along the route changes.
|
Package navigation moves entities along a MoveOrder's path across a board, re-pathing automatically when terrain along the route changes. |
|
selection
Package selection turns mouse input into a Selected tag on world entities: left-click to select, drag for a marquee, shift to add.
|
Package selection turns mouse input into a Selected tag on world entities: left-click to select, drag for a marquee, shift to add. |
|
vision
Package vision gives entities a narrowed view of the world: a Sight cone sees what falls inside it, within range and not hidden behind something nearer.
|
Package vision gives entities a narrowed view of the world: a Sight cone sees what falls inside it, within range and not hidden behind something nearer. |
|
vision/behavior
Package behavior holds ready-made reactions to what an entity sees, each a plain function of a vision.Sighting handed to plugin.Between: Flee gives way to what is on a collision course and runs from a Threat, Chase goes after the nearest and searches when it sees none.
|
Package behavior holds ready-made reactions to what an entity sees, each a plain function of a vision.Sighting handed to plugin.Between: Flee gives way to what is on a collision course and runs from a Threat, Chase goes after the nearest and searches when it sees none. |
|
world
Package world is the foundation for a Stage with moving, drawable entities: a Position and Velocity each, a shared spatial index other plugins query, and motion integrated each tick, never further than Position.MaxStep.
|
Package world is the foundation for a Stage with moving, drawable entities: a Position and Velocity each, a shared spatial index other plugins query, and motion integrated each tick, never further than Position.MaxStep. |
|
world/kind
Package kind is how a game says what its entities are.
|
Package kind is how a game says what its entities are. |
|
Package render is the drawing side of gram: pure primitives that know nothing of Stages, Scenes or plugins.
|
Package render is the drawing side of gram: pure primitives that know nothing of Stages, Scenes or plugins. |