|
1 | 1 | # Obsidian Engine |
2 | 2 |
|
3 | | -Obsidian is a high-performance 2D game engine designed specifically for **CC: Tweaked**. It features a robust Entity Component System (ECS), an optimized rendering pipeline with double-buffering, and a flexible particle system. |
| 3 | +Obsidian is a 2D game engine for **CC: Tweaked**. It pairs an Entity Component |
| 4 | +System with a retained renderer, so game logic stays decoupled from data while |
| 5 | +drawing is reduced to the cells that actually changed. |
| 6 | + |
| 7 | +**[API reference and guides](https://pyroxenium.github.io/Obsidian/)** |
4 | 8 |
|
5 | 9 | ## Features |
6 | 10 |
|
7 | | -* **High-Performance Rendering:** Uses double-buffering and `term.blit` optimization to ensure smooth frame rates. |
8 | | -* **ECS Architecture:** Decoupled logic and data for scalable game development. |
9 | | -* **Asset Management:** Automatic caching and pre-processing of sprites (`.osf`), UI layouts (`.oui`), and emitters (`.ope`). |
10 | | -* **Particle System:** Fully integrated ECS-based particles with support for gravity, drag, and color/character interpolation. |
11 | | -* **Static/Dynamic Layering:** Optimized handling of static backgrounds versus dynamic entities. |
12 | | - |
13 | | -## Project Structure |
14 | | - |
15 | | -* `src/core/`: The heart of the engine. |
16 | | - * `loader.lua`: Handles asset loading and optimization. |
17 | | - * `particles.lua`: ECS systems for particle effects. |
18 | | - * `buffer.lua`: Low-level rendering logic (Double-Buffering). |
19 | | -* `assets/`: Suggested directory for your `.osf` and `.ope` files. |
20 | | - |
21 | | -## Rendering Pipeline |
22 | | -The engine follows a strict 7-phase pipeline: |
23 | | -1. Clear Phase |
24 | | -2. Static Pass |
25 | | -3. Query Pass (ECS) |
26 | | -4. Sort Pass (Z-Indexing) |
27 | | -5. Entity Pass |
28 | | -6. UI Pass |
29 | | -7. Present Phase (Sync to Hardware) |
| 11 | +* **ECS architecture:** entities, components and systems, backed by a spatial |
| 12 | + grid for rect queries, triggers, raycasting and line-of-sight checks. |
| 13 | +* **Retained renderer:** z-ordered layers with per-channel transparency, nested |
| 14 | + translation and clipping contexts, and dirty-region tracking so only changed |
| 15 | + rows reach the terminal. |
| 16 | +* **Colour beyond 16 slots:** register logical RGB colours; a sticky palette |
| 17 | + mapper assigns them to hardware slots per frame and approximates the excess. |
| 18 | +* **Subpixels:** a 2x3 virtual canvas compiled into CC mosaic characters. |
| 19 | +* **FLIMG images:** a binary format that keeps RGB and subpixels intact instead |
| 20 | + of baking them into terminal cells. |
| 21 | +* **Scenes and tilemaps:** multi-layer maps with collision, slopes and one-way |
| 22 | + platforms, plus static, dynamic and foreground render passes. |
| 23 | +* **Gameplay systems:** physics, particles, tweens, timers, pathfinding, AI |
| 24 | + behaviour trees, audio, save/load and a document store. |
| 25 | +* **Multiplayer:** a rednet wrapper with heartbeats, and a high-level server |
| 26 | + with rooms, middleware and an optional console. |
| 27 | +* **Developer friendly:** LuaLS annotations throughout, generated API docs, and |
| 28 | + source, minified and compressed release bundles. |
| 29 | + |
| 30 | +## Installation |
| 31 | + |
| 32 | +Fetch the installer and run it: |
| 33 | + |
| 34 | +```bash |
| 35 | +wget https://pyroxenium.github.io/Obsidian/install.lua |
| 36 | +``` |
| 37 | + |
| 38 | +Run without arguments it opens a graphical installer; pass a variant to skip |
| 39 | +straight to the download: |
| 40 | + |
| 41 | +```bash |
| 42 | +install minified |
| 43 | +``` |
| 44 | + |
| 45 | +| Variant | Result | Notes | |
| 46 | +| --- | --- | --- | |
| 47 | +| `source` | `obsidian/` folder | Editable original sources | |
| 48 | +| `bundled` | `obsidian.lua` | Readable single file | |
| 49 | +| `minified` | `obsidian.lua` | Smaller, instant startup (default) | |
| 50 | +| `compressed` | `obsidian.lua` | Smallest download, decompresses on load | |
| 51 | + |
| 52 | +Whichever you choose, the engine is loaded by name: |
| 53 | + |
| 54 | +```lua |
| 55 | +local Engine = require("obsidian") |
| 56 | +``` |
| 57 | + |
| 58 | +Both layouts answer that call: a folder containing `init.lua`, or a single |
| 59 | +`obsidian.lua` next to your program. |
| 60 | + |
| 61 | +## Quick start |
| 62 | + |
| 63 | +```lua |
| 64 | +local Engine = require("obsidian") |
| 65 | + |
| 66 | +local scene = Engine.scene.new() |
| 67 | +scene.name = "Hello" |
| 68 | + |
| 69 | +local player = scene:spawn() |
| 70 | +scene:attach(player, "pos", Engine.math.vec2(10, 5)) |
| 71 | + |
| 72 | +scene.onDraw = function() |
| 73 | + Engine.buffer:drawText(2, 2, "Hello Obsidian", "0", "f") |
| 74 | +end |
| 75 | + |
| 76 | +Engine.setScene(scene) |
| 77 | +Engine.start() |
| 78 | +``` |
| 79 | + |
| 80 | +See [guides/engine_quickstart.md](guides/engine_quickstart.md) for a longer |
| 81 | +walkthrough and [guides/ecs_guide.md](guides/ecs_guide.md) for the ECS model. |
| 82 | + |
| 83 | +## Project structure |
| 84 | + |
| 85 | +* `src/` — the engine. Installed as `obsidian`. |
| 86 | + * `init.lua` — entry point and module loader. |
| 87 | + * `engine.lua` — subsystem wiring, main loop, scene transitions. |
| 88 | + * `core/` — one file per subsystem (`buffer`, `scene`, `ecs`, `ui/`, …). |
| 89 | + * `flimg.lua` — the FLIMG image codec, shared with Basalt. |
| 90 | +* `guides/` — prose documentation. |
| 91 | +* `examples/` — runnable sample programs. |
| 92 | +* `tools/` — development tooling, not shipped with the engine. |
| 93 | +* `bundle/` — generated single-file releases. |
| 94 | +* `install.lua` — the web installer. |
| 95 | +* `manifest.txt` — source file list the installer reads; regenerated by CI. |
| 96 | + |
| 97 | +## Asset formats |
| 98 | + |
| 99 | +| Extension | Contents | Loaded with | |
| 100 | +| --- | --- | --- | |
| 101 | +| `.obs` | Multi-frame sprite: character, foreground and background layers | `Engine.loader.loadSprite` | |
| 102 | +| `.oui` | UI layout definitions | `Engine.loader.loadUI` / `scene:loadUI` | |
| 103 | +| `.pe` | Particle emitter configuration | `Engine.loader.loadEmitter` | |
| 104 | +| `.flimg` | Binary image with RGB colours and subpixels | `Engine.loader.loadImage` | |
| 105 | + |
| 106 | +`.obs`, `.oui` and `.pe` are serialised Lua tables; see |
| 107 | +[filetypes.md](filetypes.md) for their structure and validation rules, and |
| 108 | +[src/FLIMG.md](src/FLIMG.md) for the FLIMG binary layout. |
| 109 | + |
| 110 | +## Rendering pipeline |
| 111 | + |
| 112 | +Each frame runs a fixed sequence: |
| 113 | + |
| 114 | +1. Clear |
| 115 | +2. Static pass (tilemap and static elements, cached between frames) |
| 116 | +3. Query pass (ECS) |
| 117 | +4. Sort pass (z-index) |
| 118 | +5. Entity pass |
| 119 | +6. UI pass |
| 120 | +7. Present (compose layers, blit changed rows) |
| 121 | + |
| 122 | +Static content is redrawn only when the camera moves or the scene is marked |
| 123 | +dirty; otherwise the rows entities touched last frame are restored from cache. |
| 124 | + |
| 125 | +## Tooling |
| 126 | + |
| 127 | +Run from the repository root. All of these work under plain Lua as well as |
| 128 | +inside CraftOS-PC. |
| 129 | + |
| 130 | +```bash |
| 131 | +lua tools/docgen.lua --check |
| 132 | +``` |
| 133 | + |
| 134 | +```bash |
| 135 | +lua tools/bundle-host.lua --compress |
| 136 | +``` |
| 137 | + |
| 138 | +* `docgen.lua` — generates the API reference from the source annotations. |
| 139 | + Without arguments it writes to `docs/`; `--check` validates only. |
| 140 | +* `bundle.lua` / `bundle-host.lua` — build a single-file release. Default is |
| 141 | + minified; `--no-minify` keeps readable source, `--compress` adds compression. |
| 142 | +* `smoketest.lua` — loads the engine and verifies every subsystem came up. Run |
| 143 | + it from a computer that has Obsidian installed as `obsidian`. |
| 144 | +* `minify.lua` — the Lua minifier used by the bundler. |
30 | 145 |
|
31 | 146 | ## License |
| 147 | + |
32 | 148 | This project is licensed under the MIT License. |
0 commit comments