Eaglev0.1.0

Eagle: Vision & Architecture

Eagle is a Crystal-native game engine. Goals, in priority order:

  1. Easy things are easy, hard things are possible. A working game is a few

dozen lines. Everything is still reachable (raw GL, shaders, custom nodes).

  1. Crystal all the way down. Only two native dependencies: SDL2 (window,

input, gamepad, audio device) and the platform's OpenGL. Image decoding, audio mixing, fonts, physics, scene tree, particles, asset caching are Crystal.

  1. Library + engine + viewer. require "eagle" in any shard, or use the

eagle CLI to scaffold/run/view. Games compile to a single executable.

  1. Fast feedback loop. Deterministic frame stepping, screenshots to PNG,

headless-ish runs (EAGLE_FRAMES=60 EAGLE_SCREENSHOT=out.png) so tests and agents can verify rendering without a human.

Inspirations

Node2D/Node3D families, input action map, res:// asset paths, one-file shaders.

Layers

 ┌──────────────────────────────────────────────────────────────┐
 │ Games / Examples / CLI viewer                                │
 ├──────────────────────────────────────────────────────────────┤
 │ Nodes: Node2D Sprite2D Camera2D Label Area2D RigidBody2D …    │
 │        Node3D MeshInstance3D Camera3D Light3D Particles …     │
 ├──────────────────────────────────────────────────────────────┤
 │ Systems: SceneTree · Signals · Input (actions, gamepad)      │
 │          Assets (cache, res://) · Audio mixer · Physics2D/3D  │
 │          Particles · Fonts (bitmap + TTF) · Tween · Timer     │
 ├──────────────────────────────────────────────────────────────┤
 │ Graphics: Graphics2D (batched) · Renderer3D · Shader ·        │
 │           Texture · Mesh · Material · RenderTarget · Camera   │
 ├──────────────────────────────────────────────────────────────┤
 │ Platform: Window · Time · Events  (SDL2)   GL 3.3 core loader │
 ├──────────────────────────────────────────────────────────────┤
 │ Math: Vec2/3/4 Mat3/4 Quat Rect Color Transform2D             │
 └──────────────────────────────────────────────────────────────┘

Key decisions

on macOS (4.1 core max), Linux, Windows without a loader library. Backend is behind Eagle::GL; a Vulkan/Metal backend is possible later but not planned.

main thread each frame and pushes with SDL_QueueAudio. No foreign-thread callbacks into Crystal (GC-safe). Latency ~ 2 frames.

Crystal TrueType parser + rasterizer for real fonts.

(signal hit(damage : Int32)on_hit { |d| } / emit_hit(d)).

EAGLE_ASSETS. Cached by path; hot reload later.

Directory layout

src/eagle.cr              library entry
src/eagle/lib/            C bindings (sdl2, gl)
src/eagle/math/
src/eagle/core/           engine loop, window, time, events, log, signals, node tree
src/eagle/graphics/       gl objects, 2D batcher, 3D renderer, fonts
src/eagle/assets/         loader/cache and codecs (png, wav, obj, ttf)
src/eagle/audio/
src/eagle/physics/
src/eagle/particles/
src/eagle/nodes/          Godot-style nodes
src/cli.cr                `eagle` CLI (new/run/view)
examples/                 runnable examples & games
spec/                     unit specs (no window needed)
docs/plans/               plans and progress logs (this folder)

Roadmap (phases)

See 010-roadmap.md, updated as work lands.

Modular backends (added 2026-09-18 after user request for WASM/WebGL)

Everything platform-specific sits behind small abstract classes so backends are plug-and-play:

AbstractionDefault impl (desktop)Planned
Eagle::Platform::BasePlatform::SDLPlatform::Web (JS glue)
Eagle::GPU::DeviceGPU::GL33GPU::WebGL2
Eagle::Audio::DeviceAudio::SDLDeviceAudio::WebAudioDevice
Eagle::Input::SourceSDL eventsDOM events

Rules that keep WebGL2 reachable:

backend prepends the #version line and precision qualifiers. No geometry shaders, no compute, no gl_VertexID tricks, no bindless. UBO-free by default (plain uniforms) so GLES 3.0 and WebGL2 both work.

(RGBA8, RGB8, R8, depth24, float32 attributes).

Crystal's wasm32-unknown-wasi target is experimental; the web backend is a later phase and requires a JS shim for WebGL2/WebAudio/DOM input. The architecture above is what makes it possible without an engine rewrite.