crucible

module
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT

README

crucible

n. a vessel in which substances are melted down and fused at great heat. Also: the engine the rest of the family melted into.

The shared Ebitengine app/game engine behind the tool family — the GUI panels, world generation, title screens, and window plumbing that rubix, gambit, vivarium, galapagos, hegemony, pandemonium, and nemesis were each carrying copies of.

Go Reference CI Go 1.26 MIT License

Install

go get github.com/danielriddell21/crucible@latest

Packages

One package per engine concern, flat at the module root. App-specific vocabularies (messages, events, cues, tiles, textures) stay in each app; packages that carry them are generic.

Package What it is Consolidated from
geom Vectors, grid coords, rects, clamps vivarium, pandemonium, nemesis, hegemony
hud Timed status-line overlay pandemonium, nemesis (identical copies)
canvas Software RGBA text/menu surface nemesis, pandemonium
menu Title/pause/settings menu model + input polling nemesis, pandemonium
store JSON settings/records under the user config dir nemesis, pandemonium
status Cue → timed HUD line pipeline pandemonium
narrate narrata-backed rewording of status lines pandemonium
telemetry Generic observer bus with bounded recent feed pandemonium, nemesis
synth Procedural PCM sound effects, panning, cue shapes pandemonium, nemesis
record Demo GIF recorder and PNG screenshots rubix, gambit, galapagos, pandemonium
hub Multi-window leader/child coordination rubix, hegemony, nemesis
worldgen BSP dungeon generation, corridors, flood-fill, weighted choice pandemonium, nemesis
level Shared world model + generation pipeline: tiles, heights, half walls, lifts, doors, vents, themes, sky pandemonium, nemesis
raycast Raycasting camera, DDA, billboards, height-aware column walker pandemonium, nemesis
view Display-free 2D pan/zoom camera: world↔screen, follow, fit-to-bounds galapagos
camera Ebiten draw transform layered over a 2D view vivarium
rng Deterministic seeded sub-streams (PCG) galapagos, hegemony
ring Fixed-capacity rolling-history buffer galapagos, vivarium
paint Colour brightness scaling and full-frame framebuffer blend pandemonium, nemesis

Only menu and camera import Ebiten; everything else is plain Go and runs headless.

Quick start

import (
    "github.com/danielriddell21/crucible/level"
    "github.com/danielriddell21/crucible/raycast"
)

// Generate a furnished level: rooms, corridors, heights, half walls,
// doors, vents, themes, sky — retried until the exit is reachable.
l, rooms, err := level.Generate(level.GenerateConfig{Width: 64, Height: 48, Seed: seed},
    []level.Pass{
        func(l *level.Level, rng *worldgen.RNG, rooms []geom.Rect) {
            level.AssignHeights(l, rng, rooms, level.HeightsConfig{})
            level.PlaceDoors(l, rng, level.DoorConfig{})
            level.CarveVents(l, rooms, level.VentConfig{})
        },
    }, nil)

// Cast a ray for every screen column; WalkColumn handles variable
// heights and half walls, painting through your renderer.
cam := raycast.NewCamera(playerPos, playerAngle, fov)
for x := range screenW {
    res := raycast.WalkColumn(cam, screenW, screenH, x, eyeZ, l, myPainter)
    zbuf[x] = res.Depth
}

See each package's godoc for the full surface, and docs/provenance.md for exactly which files in which repos each package replaces.

The family, migrated

All seven apps — rubix, gambit, vivarium, galapagos, hegemony, pandemonium, and nemesis — now build on crucible. docs/provenance.md maps every package to the files it replaced, and records what was deliberately left app-side and why. ordinex needs no migration — crucible consumes it as a dependency (the hub sorts window ids with it) — and retrievium stays app-side, its sorted-slice search a linear scan's-worth of value away from being worth a dependency.

Why a library, not a framework

Each game keeps its own internal/gui, ebiten.Game, renderer, and simulation — crucible supplies the shared machinery behind that seam, not a scene graph. The family's CONVENTIONS.md still governs the shape of each app; crucible is the code those conventions kept describing.

Directories

Path Synopsis
Package camera provides the 2D pan-and-zoom camera the family's top-down visualizers use: zoom anchored under the cursor, panning in world units, and clamping so the view never leaves the world.
Package camera provides the 2D pan-and-zoom camera the family's top-down visualizers use: zoom anchored under the cursor, panning in world units, and clamping so the view never leaves the world.
Package canvas provides a small software drawing surface for menus and text overlays, so a front-end can compose text screens the same way a software renderer composes frames: as raw RGBA pixels.
Package canvas provides a small software drawing surface for menus and text overlays, so a front-end can compose text screens the same way a software renderer composes frames: as raw RGBA pixels.
Package geom provides the small geometric vocabulary shared by the Ebitengine tool family: float vectors for simulation space, integer coordinates and rectangles for tile grids, and clamping helpers.
Package geom provides the small geometric vocabulary shared by the Ebitengine tool family: float vectors for simulation space, integer coordinates and rectangles for tile grids, and clamping helpers.
Package hub coordinates a family of visualizer windows: one leader process spawns child windows of its own executable and relays JSON messages between them over the children's stdin and stdout, so every window shows the same state.
Package hub coordinates a family of visualizer windows: one leader process spawns child windows of its own executable and relays JSON messages between them over the children's stdin and stdout, so every window shows the same state.
Package hud provides the timed status-line overlay used by the family's game front-ends: a single line of text posted for a number of frames, on either a diagnostic or a player-facing channel.
Package hud provides the timed status-line overlay used by the family's game front-ends: a single line of text posted for a number of frames, on either a diagnostic or a player-facing channel.
Package keymap lays out an on-screen control-hint bar — the "key: action" row the family's apps show along the bottom of the window.
Package keymap lays out an on-screen control-hint bar — the "key: action" row the family's apps show along the bottom of the window.
Package level is the shared world model behind the family's first-person games: a tile grid with per-cell floor and ceiling heights, half-height walls, light, sky, and lifts, plus the placement passes that furnish a generated dungeon — heights and ledges, low walls, doors, and vent networks.
Package level is the shared world model behind the family's first-person games: a tile grid with per-cell floor and ceiling heights, half-height walls, light, sky, and lifts, plus the placement passes that furnish a generated dungeon — heights and ledges, low walls, doors, and vent networks.
Package menu provides the keyboard-driven menu model shared by the family's title, pause, and settings screens: a titled list of items with wraparound selection, adjustable settings rows, and a software-canvas renderer.
Package menu provides the keyboard-driven menu model shared by the family's title, pause, and settings screens: a titled list of items with wraparound selection, adjustable settings rows, and a software-canvas renderer.
Package narrate wraps a scripted status.Source with a narrata narration engine: player-facing hud.Notice lines are rewritten by a persona, while the scripted wording stands in whenever generation declines, fails, or times out.
Package narrate wraps a scripted status.Source with a narrata narration engine: player-facing hud.Notice lines are rewritten by a persona, while the scripted wording stands in whenever generation declines, fails, or times out.
Package paint holds the small colour and framebuffer operations the family's software renderers share: scaling a colour's brightness for distance shading, and compositing a translucent wash over a finished frame.
Package paint holds the small colour and framebuffer operations the family's software renderers share: scaling a colour's brightness for distance shading, and compositing a translucent wash over a finished frame.
Package raycast is the software raycasting core behind the family's first-person games: a planar camera, the DDA grid walk that finds the wall each screen column hits, and the billboard projection used to place sprites against the wall z-buffer.
Package raycast is the software raycasting core behind the family's first-person games: a planar camera, the DDA grid walk that finds the wall each screen column hits, and the billboard projection used to place sprites against the wall z-buffer.
Package record captures frames from a running visualizer into demo GIFs and PNG screenshots, the way the family's --record flags and screenshot keys do.
Package record captures frames from a running visualizer into demo GIFs and PNG screenshots, the way the family's --record flags and screenshot keys do.
Package ring is a fixed-capacity ring buffer for the rolling histories the family's sims keep: population counts, per-generation fitness, telemetry samples.
Package ring is a fixed-capacity ring buffer for the rolling histories the family's sims keep: population counts, per-generation fitness, telemetry samples.
Package rng seeds the family's deterministic random streams.
Package rng seeds the family's deterministic random streams.
Package status is the pipeline that turns game events into timed HUD lines: a game maps its telemetry into a cue type of its own, a Source decides whether the cue deserves a Line and with what wording, and Emit posts the line to a hud.Overlay.
Package status is the pipeline that turns game events into timed HUD lines: a game maps its telemetry into a cue type of its own, a Source decides whether the cue deserves a Line and with what wording, and Emit posts the line to a hud.Overlay.
Package store persists small per-application JSON documents — settings, records, saved state — under the user's configuration directory, following the family convention of one <app>/<file>.json per document.
Package store persists small per-application JSON documents — settings, records, saved state — under the user's configuration directory, following the family convention of one <app>/<file>.json per document.
Package synth renders the family's procedural sound effects and loops as interleaved 16-bit stereo PCM at SampleRate, ready for an Ebiten/oto audio player.
Package synth renders the family's procedural sound effects and loops as interleaved 16-bit stereo PCM at SampleRate, ready for an Ebiten/oto audio player.
Package telemetry provides the fan-out event bus the family's games hang their observers on: audio cues, HUD feeds, record keepers, and analytics all subscribe to the same stream of game events.
Package telemetry provides the fan-out event bus the family's games hang their observers on: audio cues, HUD feeds, record keepers, and analytics all subscribe to the same stream of game events.
Package view is a display-free 2D pan/zoom camera: it maps between world and screen space around a centred focus, with follow and fit-to-bounds framing, and imports no rendering backend — so headless sims and web front-ends share the same camera math the Ebiten front-ends use.
Package view is a display-free 2D pan/zoom camera: it maps between world and screen space around a centred focus, with follow and fit-to-bounds framing, and imports no rendering backend — so headless sims and web front-ends share the same camera math the Ebiten front-ends use.
Package window centralises Ebiten window setup for the family's front-ends: initial size, title, and a single shared resizing policy.
Package window centralises Ebiten window setup for the family's front-ends: initial size, title, and a single shared resizing policy.
Package worldgen generates the family's tile-grid dungeons: binary space partitioning carves rooms into leaves, L-shaped corridors join them into one connected map, short dead-end stubs add texture, and flood-fill utilities answer reachability and distance questions about the result.
Package worldgen generates the family's tile-grid dungeons: binary space partitioning carves rooms into leaves, L-shaped corridors join them into one connected map, short dead-end stubs add texture, and flood-fill utilities answer reachability and distance questions about the result.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL