Callisto Game Engine
A desktop game engine written in Odin.
Callisto is a desktop game engine written in Odin with a Vulkan renderer. It is still early in development and the API is subject to change.
When there is a stable release I will add documentation here.
At the moment, the notes here are to record decisions that I have made.
In the meantime, see the Callisto GitHub repository for a brief overview of how the engine is used, or
Callisto-Sandbox for a sample implementation.
1 - Assets
Game data stored on the disk.
Assets are classified as either Primitive or Aggregate.
Primitive assets MUST contain only information about themselves, while aggregate assets MAY contain references to other assets.
Planned primitives:
Image
Mesh
Audio
Input action map
Shader
Planned aggregates:
Material
(shader + images)Model
(mesh + materials)Construct
(fixed-length transform hierarchy)Level
This section is a work in progress. I may end up implementing a custom format that requires very little processing to deserialize.
In the meantime, I’m using Concise Binary Object Representation (CBOR) for serialization,
as it provides some desired attributes to the asset files:
- Named fields to avoid data loss when struct definitions change
- Small file size
- Existing Odin core library
File loading
Inspiration from Timothy Cain’s video, Arcanum “dat” files, development builds use a raw OS file system, or “loose assets”,
while release builds use packed bundles.
- data locality on the disk
- “seek” is much faster than “open”
- avoid file descriptor limits
- less overhead for many tiny assets (block alignment, OS file nodes)
- easy patches/modding with sequential overriding of the asset database
- more efficient compression
2 - Graphics
Details about the renderer, shaders, render passes etc.
2.1 - Coordinates for rendering
Transforming coordinates from world space to other spaces.
World coordinates
World coordinates are right-handed, +Z forward, +Y up, -X right.
Why?
- Want right handed coords
- glTF default, easy import
- Y-up intuitive for gravity
Projection and Clip space
Vulkan’s NDC space is defined as [x: -1, y: -1] top-left, [x: 1, y: 1] bottom-right, and z depth in the range [0, 1].
Callisto uses a reversed-depth, infinite far plane perspective projection.
- Better distribution of floating point precision
- No far plane clipping artifacts
Because of the reversed depth, shaders must use Greater
depth test (higher depth is closer).
To get from Callisto coords to Vulkan coords, the x and y axes must be flipped.
perspective :: proc(fovy, aspect, near: f32) -> (mat: Matrix4x4) {
ep :: math.pow(2, -20) // ep is a small value to prevent float rounding errors
g := 1 / math.tan(0.5 * fovy)
// Column-major matrix
//
// -g/s 0 0 0
// 0 -g 0 0
// 0 0 ep near * (1-ep)
// 0 0 1 0
mat[0, 0] = -g / aspect
mat[1, 1] = -g
mat[2, 2] = ep
mat[2, 3] = 1
mat[3, 2] = near * (1 - ep)
return mat
}