Obsidian is a 2D game engine for CC: Tweaked. It pairs an Entity Component System with a retained renderer, so game logic stays decoupled from data while drawing is reduced to the cells that actually changed.
- ECS architecture: entities, components and systems, backed by a spatial grid for rect queries, triggers, raycasting and line-of-sight checks.
- Retained renderer: z-ordered layers with per-channel transparency, nested translation and clipping contexts, and dirty-region tracking so only changed rows reach the terminal.
- Colour beyond 16 slots: register logical RGB colours; a sticky palette mapper assigns them to hardware slots per frame and approximates the excess.
- Subpixels: a 2x3 virtual canvas compiled into CC mosaic characters.
- FLIMG images: a binary format that keeps RGB and subpixels intact instead of baking them into terminal cells.
- Scenes and tilemaps: multi-layer maps with collision, slopes and one-way platforms, plus static, dynamic and foreground render passes.
- Gameplay systems: physics, particles, tweens, timers, pathfinding, AI behaviour trees, audio, save/load and a document store.
- Multiplayer: a rednet wrapper with heartbeats, and a high-level server with rooms, middleware and an optional console.
- Developer friendly: LuaLS annotations throughout, generated API docs, and source, minified and compressed release bundles.
Fetch the installer and run it:
wget https://pyroxenium.github.io/Obsidian/install.luaRun without arguments it opens a graphical installer; pass a variant to skip straight to the download:
install minified| Variant | Result | Notes |
|---|---|---|
source |
obsidian/ folder |
Editable original sources |
bundled |
obsidian.lua |
Readable single file |
minified |
obsidian.lua |
Smaller, instant startup (default) |
compressed |
obsidian.lua |
Smallest download, decompresses on load |
Whichever you choose, the engine is loaded by name:
local Engine = require("obsidian")Both layouts answer that call: a folder containing init.lua, or a single
obsidian.lua next to your program.
local Engine = require("obsidian")
local scene = Engine.scene.new()
scene.name = "Hello"
local player = scene:spawn()
scene:attach(player, "pos", Engine.math.vec2(10, 5))
scene.onDraw = function()
Engine.buffer:drawText(2, 2, "Hello Obsidian", "0", "f")
end
Engine.setScene(scene)
Engine.start()See guides/engine_quickstart.md for a longer walkthrough and guides/ecs_guide.md for the ECS model.
src/— the engine. Installed asobsidian.init.lua— entry point and module loader.engine.lua— subsystem wiring, main loop, scene transitions.core/— one file per subsystem (buffer,scene,ecs,ui/, …).flimg.lua— the FLIMG image codec, shared with Basalt.
guides/— prose documentation.examples/— runnable sample programs.tools/— development tooling, not shipped with the engine.bundle/— generated single-file releases.install.lua— the web installer.manifest.txt— source file list the installer reads; regenerated by CI.
| Extension | Contents | Loaded with |
|---|---|---|
.obs |
Multi-frame sprite: character, foreground and background layers | Engine.loader.loadSprite |
.oui |
UI layout definitions | Engine.loader.loadUI / scene:loadUI |
.pe |
Particle emitter configuration | Engine.loader.loadEmitter |
.flimg |
Binary image with RGB colours and subpixels | Engine.loader.loadImage |
.obs, .oui and .pe are serialised Lua tables; see
filetypes.md for their structure and validation rules, and
src/FLIMG.md for the FLIMG binary layout.
Each frame runs a fixed sequence:
- Clear
- Static pass (tilemap and static elements, cached between frames)
- Query pass (ECS)
- Sort pass (z-index)
- Entity pass
- UI pass
- Present (compose layers, blit changed rows)
Static content is redrawn only when the camera moves or the scene is marked dirty; otherwise the rows entities touched last frame are restored from cache.
Run from the repository root. All of these work under plain Lua as well as inside CraftOS-PC.
lua tools/docgen.lua --checklua tools/bundle-host.lua --compressdocgen.lua— generates the API reference from the source annotations. Without arguments it writes todocs/;--checkvalidates only.bundle.lua/bundle-host.lua— build a single-file release. Default is minified;--no-minifykeeps readable source,--compressadds compression.smoketest.lua— loads the engine and verifies every subsystem came up. Run it from a computer that has Obsidian installed asobsidian.minify.lua— the Lua minifier used by the bundler.
This project is licensed under the MIT License.
