Skip to content

Engine API reference

The Crossfire Engine’s public API, generated from the doc comments in its source (package crossfire, imported by games as import e "engine:."). 1260 declarations in 24 areas.

The Crossfire Engine: a 2D game engine on SDL3, with Box2D physics, and the runtime of the Crossfire Editor’s games.

Games are scenes of nodes. A node has a transform relative to its parent, a layer, a tint and optional update and draw procedures; node kinds (sprites, labels, menus, cameras, physics bodies, particle emitters, sound players, LDtk levels…) embed Node as their first field. A game owns its scenes, switches between them and holds what lives as long as the game: resources, input, mix buses, globals. The application owns the window and runs the frame loop.

Application the window and its renderer, audio and text; the frame loop (app.odin)
Game resolution and scaling, scenes by name, input, sound, globals (game.odin)
Scene nodes, add and remove queues, the camera, physics, tweens (scene.odin)
Node transform, parent and children, layer, visibility, hooks (node.odin)

Most games are made in the editor: scenes are XML files (project_format.odin) built at run time (project_loader.odin), and game code is scripts, Odin structs attached to nodes (script.odin). Code can make everything as well.

Example

package mygame
import e "engine:."
import sdl "vendor:sdl3"
Ship :: struct {
using node: e.Node,
speed: f32,
}
main :: proc() {
app: e.Application
game := new(e.Game)
game.size = {1280, 720}
game.build = proc(game: ^e.Game) {
scene := game->createScene("Space")
ship := e.CreateNode(scene, Ship)
ship.position = {640, 360}
ship.speed = 300
ship.update = proc(node: ^e.Node, _: []sdl.Event, dt: f64) {
ship := cast(^Ship)node
move := e.Input_GetVector("ui_left", "ui_right", "ui_up", "ui_down")
ship.position += move * ship.speed * f32(dt)
}
ship.draw = proc(_: ^e.Node, renderer: ^sdl.Renderer) {
// In the node's own space: (0, 0) is its position
e.DrawCircle(renderer, {0, 0}, 16, {120, 200, 255, 255})
}
_ = game->switchScene("Space")
}
if !e.Application_Setup(&app, "Space", {1280, 720}) do return
e.Application_Run(&app, game)
// Destroys the game too
e.Application_Cleanup(&app)
}

Where things are

  • Drawing: primitives.odin (shapes, DrawTexture), text_primitives.odin, render_target.odin, layers.odin, transform.odin (the draw state), camera.odin, debug.odin (debug shapes, the overlay).
  • Nodes: project_loader.odin (Sprite, AnimatedSprite), ui_label.odin, ui_menu.odin, particles.odin, audio_nodes.odin, ldtk_nodes.odin, timer.odin, ticker.odin.
  • Motion: animation.odin, animation_player.odin, tween.odin, easing.odin.
  • Physics: physics.odin (the world, queries, the character mover), physics_nodes.odin, physics_events.odin, physics_joints.odin, physics_debug.odin.
  • Input: input.odin (state and actions), input_rebind.odin (rebinding, rumble).
  • Game data: globals.odin, data.odin, save.odin, assets.odin, localization.odin.
  • Running games: player.odin (the player program), pack.odin (games in one file), the platform layer (platform_native.odin, platform_web.odin; player_web.odin for browsers).

Memory: each node lives in its own arena, freed when it’s removed (Node_GetAllocator); a scene’s and the game’s shared data live in their arenas (Scene_GetAllocator, Game_GetAllocator); context.temp_allocator is freed every frame.

  • Core: application, game, scenes and nodes: The application and its frame loop, the game and its scenes, nodes and their transforms, events, timers and the package’s memory model. (127)
  • Rendering: Drawing shapes and textures in a node’s space, render targets, texture atlases, tile batches and the choice of renderer. (47)
  • Text and fonts: Drawing and measuring text, bitmap and MSDF fonts, and localization. (31)
  • Camera: The Camera2D node, follow modes and pans, parallax layers, camera zones, smooth zoom and camera views. (34)
  • Input: Keyboard, mouse and gamepad state, input actions, and rebinding. (56)
  • Physics: The Box2D world, physics nodes and joints, contact and area events, queries, materials, collision traced from images and debug drawing. (77)
  • Audio: SDL_mixer setup, sound and music nodes, mix buses, bus effects, level meters and adaptive music. (69)
  • Animation: Sprite animations and their player, animation assets, Animator keyframe clips, tweens, easing curves, state machines and skeletal animation. (150)
  • Particles and lines: Particle emitters on the CPU and the GPU, Line2D and Trail2D. (47)
  • Lighting: 2D lights, occluders, shadows and the scene’s light map. (12)
  • Shaders and screen effects: Shader bundles and materials on nodes, compiling GLSL, and ScreenEffect nodes. (31)
  • UI: Labels, menus, UI controls (panels, buttons, progress bars, text fields, scroll boxes, rich text), layouts and themes. (74)
  • Tilemaps and Aseprite: Aseprite files, their use in a running game, and TileMap nodes. (78)
  • LDtk: LDtk projects as plain data, and LDtkLevel nodes built from them. (72)
  • Dialogue: Dialogue files and their runner, Yarn Spinner import, and the DialogueBox node. (43)
  • Navigation: Navigation regions and grids, A* paths, and NavAgent nodes. (18)
  • Scripts, globals, data and saves: Scripts attached to nodes, global scripts, data resources, saved games and hot reload’s snapshots. (39)
  • Scene changes: Transitions, scenes over scenes, loading screens and menu actions. (15)
  • Project format and loading: The project and scene XML format, its parser, and building scenes from parsed data. (56)
  • Assets and import: The resource manager, typed asset handles and import settings. (23)
  • Platform, player and web: The player program, the platform layer (desktop and browser), the browser player, data packs and static SDL linking. (72)
  • Steam, touch and local multiplayer: Steam achievements, stats and cloud files; touch input and on-screen controls; local multiplayer players and split screen. (67)
  • Debug and live: Debug drawing and the debug overlay, and the live link with the editor. (21)
  • Utilities: Paths and the package overview. (1)