Sindri forge mark SINDRI
engine v0.1.4 · ready
GitHub
ai-as-peer · 2d engine · rust · lua

rust owns the engine.
lua owns gameplay.
the ai understands both.

Sindri is a 2d game engine, editor workspace, and local AI-assisted tooling stack written in Rust. The AI lives inside the workspace as a peer — every action lands as a reviewable proposal, so you stay in control.

View on GitHub Read the docs
wgpu·rapier2d·lua 5.4·ollama · local-first·mit / apache-2.0
01 what the engine already does
Hardware-accelerated 2d rendering

Batched sprites, shapes, tilemaps, particles, text, and lighting on top of wgpu. Offscreen rendering and screenshots included.

wgpu
Rapier2D physics

Rigid bodies, colliders, triggers, and collision callbacks wired into the world and exposed to scripts.

rapier2d
Lua scripting with hot reload

Entity-attached scripts with lifecycle callbacks and deferred world mutation. Save the file, keep playing.

lua 5.4 · mlua
Local AI tooling

AI-assisted entity and scene actions through Ollama. Runs on your machine — no external API required.

ollama · local-first
Lightweight world / ECS

World + EntityId, immutable and mutable queries, built-in gameplay components, and a fluent EntityBuilder.

world · entitybuilder
Scene serialization

Scenes save and load through the editor, with undo/redo commands and editor/runtime parity tracking.

.sndr scenes
Cameras, grids, pathfinding

Camera zoom, bounds, world/screen conversion, typed grids, and A* pathfinding out of the box.

camera2d · a*
Audio and input

Audio through rodio; frame-accurate input with action mapping for keyboard and beyond.

rodio
02 ai flow · proposals, not actions

Every AI action lands as a reviewable proposal.

The assistant is a peer collaborator with full agency over the project — it can stage scenes, scripts, and components. But nothing touches your project until you accept it. No cloud, no API key: everything runs locally through Ollama.

01
Ask Cmd-K: “Ask Sindri to build something…” — or point at an entity and describe the behavior you want.
02
Review The AI stages scripts, components, and entities as ghosts — dashed outlines and diffs, scoped to your project.
03
Accept or reject Accept all, reject all, or refine per change. Nothing lands in the scene until you say so.
AI proposal · awaiting review

Make the drone follow the beacon and play a chime when it gets close.

you · cmd-k
script Rewrite update() to chase target drone.lua
- local speed = 0
+ local target = world:find("Beacon")
+ self:move_towards(target, 140 * dt)
component Add AudioSource · chime.ogg Drone
ghost · AudioSource { clip: "chime.ogg", range: 96 }
2 changes pending
03 philosophy · on layering

Not a giant everything-engine. A cohesive workflow.

The goal is not just to render sprites. The goal is to make gameplay iteration, scripting, tooling, and editor workflows feel cohesive. Rust is the right layer for the parts you write once and lean on forever; Lua is the right layer for the gameplay you rewrite twenty times a day.

fast gameplay iteration
lightweight ECS-style workflows
editor/runtime convergence
adoption parity between engine, editor, and AI tooling
workspace
crates/
  sindri/          engine core
  sindri-server/   local engine/editor http server
  sindri-ai/       ollama client + ai action types

editor/            tauri 2 + react editor
examples/          curated examples, not subsystem spam
docs/              engine documentation
04 scripting · lua with hot reload
player.lua
● hot reload
local speed = params.speed or 220.0
function on_update(self, dt)
local input = self:input()
local transform = self:transform()
local move = input:axis("A", "D")
local pos = transform:position()
transform:set_position(
vec2(pos.x + move * speed * dt, pos.y)
)
end

Entity-attached scripts. Save the file, see it live.

Lua 5.4 through mlua, with lifecycle callbacks, deferred world mutation, collision and trigger callbacks, and physics, camera, animation, and tilemap helpers. Scripts hot-reload while the game runs.

player controllers enemy logic triggers camera behavior weapons editor-attached behavior
quick start
$ cargo run -p hello_sindri
$ cargo run -p scripted_asteroids
05 curated example suite
hello_sindri minimal onboarding platformer rust-first gameplay and physics scripted_asteroids lua scripting and hot reload flagship editor_scene scene loading and editor workflow rendering particles, lighting, camera effects
06 sindri pixel · the companion sprite editor
in development · tauri 2 + react

A pixel-art editor that speaks Sindri.

Sindri Pixel is the companion sprite and pixel-art editor — a local-first Tauri app that shares the engine's workspace, keyboard muscle memory, and AI-as-peer philosophy. Draw sprites, stack layers, animate frames, then hand them straight to your Sindri scenes.

12 tools·layers·animation frames·symmetry + tiling·top-down / side / iso·local-first
Follow on GitHub
drone.png · 16 × 16
pencil · P 4 frames
frames
● 12 fps · loop
toolbox 12 tools · keyboard-first
P
PencilPaint pixel by pixel.
E
EraserClear pixels back to transparent.
G
FillFlood-fill a contiguous area.
I
EyedropperSample any pixel into the active color.
L
LineSnap straight pixel lines.
R
RectOutline or filled rectangles.
C
CircleOutline or filled ellipses.
V
MarqueeSelect a rectangular region.
W
Magic WandSelect every matching pixel.
A
LassoDraw a freehand selection.
M
MoveNudge the selection or layer.
H
PanGlide around the canvas.
what it does
Layers & opacity

Stack layers with per-layer visibility and opacity, then composite down when a sprite is ready.

Frames & animation

A timeline of frames with per-frame duration — scrub, set the loop, and preview the animation live.

Symmetry & tiling

Mirror strokes vertically, horizontally, or both, and preview seamless tiling as you draw.

Palettes

Build and reuse color palettes; the eyedropper and swatches keep your ramp one click away.

Command palette

Cmd-K jumps to any tool, layer, or action — the same muscle memory as the engine workspace.

Guided lessons

A built-in tutorial mode walks through drawing and animating — from following along to authoring your own.

same ai-as-peer · now for sprites

The assistant proposes palette, frame, and layer edits — you decide.

Sindri Pixel carries the engine's peer model into the canvas. The AI stages changes as reviewable proposals — ghosts and diffs first — and nothing repaints your sprite until you accept it. Local, through the same workspace, no external API.

palette changes — extend or rebalance a ramp
frame changes — add in-betweens and idle loops
layer changes — new layers, staged before they land
AI proposal · awaiting review

Give the drone a 2-frame idle bob and a warmer palette ramp.

you · cmd-k
palette Extend ramp · +3 warm shades drone.pal
frame Insert in-between · idle 02 timeline
layer New layer · glow Drone
ghost · Layer { name: "glow", opacity: 0.6, blend: "add" }
3 changes pending