-
Notifications
You must be signed in to change notification settings - Fork 2
Engine Architecture Overview
This page explains how Gondwana thinks. If you understand this page, the codebase stops feeling large.
Gondwana is composed of a small number of explicit systems:
- Engine
- Scene / SceneLayer
- View / Camera / Viewport
- Backbuffers / Refresh Queues
- Rendering pipeline
- Direct Drawing
- Input
- Audio / Video
- State serialization
Each system has a narrow responsibility and minimal overlap.
The Engine owns:
- The main loop
- Timing and tick coordination
- Dispatcher contexts
- Global orchestration
- Synchronous and asynchronous logging
It does not own game rules, scene content, or rendering decisions.
Think of the Engine as the conductor, not the orchestra.
A Scene represents a world.
A SceneLayer represents a spatial slice of that world. Most layers are tile-based or sprite-based, but the engine does not enforce a data model.
SceneLayers:
- Have world-space bounds
- Own their drawables
- Support visibility, z-order, and parallax
- Can be independently refreshed or culled
There is no required ECS, inheritance hierarchy, or asset system.
A View answers the question:
What part of the world are we looking at, and how is it projected onto the screen?
- Camera defines world-space position, zoom, and rotation
- Viewport defines the screen-space rectangle
- View binds the two together
Multiple views are first-class and expected. Split screen, picture-in-picture, mini-maps, and debug overlays are built-in concepts, not hacks.
Gondwana uses dirty-region rendering to maintain predictable performance.
- World-space refresh queues track what changed
- Screen-space dirty rectangles track what must be redrawn
- Full redraws are explicit and intentional
This approach scales to large worlds without relying on brute-force redraws.
Rendering is explicit and multi-pass.
At a high level:
- SceneLayers determine which drawables intersect the view
- World-space coordinates are transformed via the Camera
- Screen-space clipping is applied via the Viewport
- Dirty regions are resolved
- The backbuffer is published
World pixels and screen pixels are tracked separately, by design.
If something redraws, there is always a reason.
DirectDrawing exists for cases that may or may not belong to a SceneLayer:
- UI overlays
- Transient effects
- Debug visuals
DirectDrawing is powerful and sharp. It bypasses some of the engine’s safety rails.
If DirectDrawing becomes your default tool, it is usually a sign that a layer abstraction is missing.
The Input system is responsible for collecting, normalizing, and exposing user input in a predictable and platform-agnostic way.
Key characteristics:
- Poll-based, not event-driven
- Explicit update timing within the engine loop
- Supports multiple input sources (keyboard, mouse, gamepad, touch)
- Designed to be deterministic and testable
Input is gathered early in the tick and made available to gameplay systems for the remainder of the frame. The engine does not attempt to infer intent or provide “action mapping magic” by default. Higher-level abstractions are expected to be built on top, not baked in.
The Audio / Video systems provide non-blocking playback of time-based media without entangling them in the render loop.
Design intent:
- Asynchronous, fire-and-forget playback
- No implicit coupling to frame rate
- Multiple concurrent sounds and overlapping instances
- Explicit lifecycle and completion signaling
Audio is treated as a first-class runtime system, not a side effect of rendering. Video playback (where supported) is layered similarly: started, updated, and completed independently of draw timing.
The engine avoids:
- Frame-tied audio updates
- Hidden threading behavior
- “Magic” auto-cleanup rules
Media playback is explicit, observable, and predictable—especially under load.
The engine favors explicit serialization and stable engine state snapshots.
This design supports save/load, replay, tooling, and future editor integration without forcing those concerns into the runtime loop.