A modular 2D game engine written in Rust, powered by Epitaph — a bytecode-compiled scripting language with .hack-inspired syntax.
Games are written in .ep scripts, compiled to bytecode, and executed inside a
lightweight stack-based VM. The engine handles rendering, audio, input,
persistence, networking, and asset packing through a collection of focused
crates.
cargo install --path crates/ns # install the CLI
ns init my-game # scaffold a new project
cd my-game
ns run # build + run (dev mode)| Crate | Description |
|---|---|
epitaph |
Language: lexer, parser, compiler, VM, stdlib |
ns-core |
Engine runtime: game loop, rendering, input, scripting host |
ns-audio |
Audio subsystem: AudioSink trait, backends (rodio), script plugin |
ns |
CLI: compile .ep to .epc, bundle into .pak, scaffold, run |
ns-assets |
PAK format, content loading, asset providers |
ns-world |
Minimal ECS (sparse sets, dense iteration) |
ns-network |
Optional networking: TCP, HTTP, WebSocket |
ns-epd |
Epitaph Data format (.epd) for structured game data |
ns-build-plugin |
WASI plugin ABI for build-time asset transforms |
ns-shell-minifb |
Reference platform shell (minifb window + input) |
.ep scripts ──► ns CLI ──► scripts.pak + game.pak + game.toml
raw assets ──►
┌──────────────────────────────────────────┐
│ ns-core (Engine) │
│ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ epitaph │ │ ns-assets│ │ns-world│ │
│ │ VM │ │ loaders │ │ ECS │ │
│ └──────────┘ └──────────┘ └────────┘ │
│ ┌──────────┐ │
│ │ ns-audio │ AudioSink (rodio, etc.) │
│ └──────────┘ │
└──────────────────────────────────────────┘
│
▼
┌──────────────┐
│ ns-shell-* │ Platform layer (window + input only)
└──────────────┘
Audio is owned by the engine — the platform shell only handles windowing and
input. Pass an AudioSink backend to the engine with engine.set_audio(...);
the default is silent no-op.
scripts/main.ep
sector game
access <gfx>
access <color>
access <window>
access <sys>
phase init() {
window.open(640, 480, "My Game")
}
phase tick(dt) {
sustain ev = window.poll_event() {
when ev == :close_requested {
sys.exit()
}
}
}
phase draw() {
gfx.fill_screen(30, 30, 60)
gfx.draw_text("Hello, NetSlum!", 10, 10, color.White)
}
Full docs live in docs/:
- Getting Started — project setup, compile, run
- Language Reference — syntax, types, control flow, coroutines
- Standard Library — math, time, color, string, list, etc.
- Engine API — gfx, audio, input, save, window, tilemap, ECS
- Networking — TCP, HTTP, WebSocket
- Build System —
nsCLI, build.toml, asset pipeline
See workspace Cargo.toml for license details.