Saida Engine
Saida Engine · Overview and install

Saida Engine

A local-first 3D engine for Windows desktop, the browser and XR. One scene model, one renderer and one gameplay API across every target, an editor you drive by hand, and a public beta you can download and run today without installing a toolchain.

Current release1.0.0 Beta 4 — a pre-release, unsigned, for manual testing and feedback.
Runs onWindows 11 x64 with a Vulkan 1.3 graphics driver. Nothing else to install.
Built withC++17, Vulkan and WebGPU, Jolt physics, QuickJS scripting, RmlUi interfaces.
LicenceGPL-3.0. Dependencies and assets keep their own licences.

Everything on this page comes from the engine's own specification, release procedure and published Beta 4 release notes. Where a surface is not qualified yet, this page says so rather than rounding it up.

#What Saida Engine is

One engine, four programs, and a promise that a scene looks the same wherever it runs.

Saida Engine builds 3D games for desktop, the Web and XR. The editor, the standalone player, the browser player and the command-line tool all share one scene model, one gameplay API and one renderer: Vulkan on the desktop and WebGPU in the browser go through the same code, and OpenXR replaces presentation without duplicating the pipeline.

That sharing is a stated invariant, not an aspiration. With identical content, camera and settings the visual result must be identical on every platform — a divergence in lighting, materials, shadows, colour or post-processing is treated as a regression to fix, not as an accepted platform variant.

ProgramWhat it does
SaidaEngineHub.exeCreates, lists and opens projects. The one to launch first.
SaidaEngine.exeThe editor: scene tree, inspector, viewport, gizmos, Play/Stop, undo/redo, Build.
SaidaEngineRuntime.exeThe editor-less desktop player. Your exported game is built on this template.
saida_tool.exeHeadless CLI: validate, inspect, render, compare and export without opening a window.

Saida Engine is local-first: the editor runs on your machine, your project is an ordinary folder of JSON and assets you can read and version, and nothing has to reach a server for you to work. It is the engine behind the Saida platform, but it is usable entirely on its own.

#Before you download

Two requirements, and one of them is your graphics driver.

RequirementDetail
Operating systemWindows 11 x64 is the supported desktop target for Beta 4. A Linux x86_64 archive also ships with this release — see route C below.
GraphicsAn Intel, AMD or NVIDIA GPU with a normal driver exposing Vulkan 1.3. Update the driver from the vendor if in doubt.
Disk and privilegesA few hundred megabytes under your user profile. No administrator rights are needed.
What you do NOT installNo Visual C++ Redistributable, no Vulkan SDK or runtime, no MSYS2, CMake, Python, compiler or any other build tool.

#Install Beta 4

Two Windows containers for exactly the same product, plus a Linux archive. Pick the installer for a normal setup, the ZIP if you would rather not install anything.

  1. Open the 1.0.0 Beta 4 release page and expand Assets.
  2. Download one of:
    • SaidaEngine-v1.0.0-beta.4-windows-x64-Setup.exe — per-user installer, with Start-menu shortcuts and an uninstaller;
    • SaidaEngine-v1.0.0-beta.4-windows-x64.zip — portable, extract and run;
    • SaidaEngine-v1.0.0-beta.4-linux-x86_64.tar.gz — the per-user Linux archive.
  3. Optional but recommended: check the file against SHA256SUMS.txt, published as an asset of the same release.
  4. Run it. Details for each route below.
PowerShell
# Compare the result with the SHA-256 published in the Beta 4 release notes.
Get-FileHash .\SaidaEngine-v1.0.0-beta.4-windows-x64-Setup.exe -Algorithm SHA256

# Same check for the portable archive.
Get-FileHash .\SaidaEngine-v1.0.0-beta.4-windows-x64.zip -Algorithm SHA256

Route A — the installer

The installer runs as your own user, asks for no administrator prompt, and puts the program under your local app data. It creates a SaidaEngine folder in the Start menu with two shortcuts, SaidaEngine Hub and SaidaEngine Editor, and registers itself in Windows so it appears in Settings → Apps.

Route B — the portable ZIP

Extract the archive anywhere you can write, keep the folder together, and launch SaidaEngineHub.exe. Nothing is written outside the folder except your projects and settings. This is the route to use on a machine where you would rather not install software at all, or to keep several engine versions side by side.

Inside the archive
SaidaEngine-v1.0.0-beta.4-windows-x64\
  SaidaEngineHub.exe        project manager — start here
  SaidaEngine.exe           the editor
  SaidaEngineRuntime.exe    the editor-less player an export is built on
  saida_tool.exe            headless CLI: validate, inspect, export
  glfw3.dll  vulkan-1.dll   shipped with the package, not installed system-wide
  shaders\  assets\         compiled shaders, editor assets and fonts
  WitnessGame\              the sample project

glfw3.dll and vulkan-1.dll travel with the package on purpose: they are the two libraries the engine ships rather than expecting your system to provide. Moving a single executable out of the folder separates it from those libraries, its shaders and its assets, and it will not start.

Route C — Linux x86_64

Beta 4 also publishes a self-contained per-user archive for x86_64 Linux with glibc 2.35 or newer (Ubuntu 22.04 and 24.04, Debian 12 and compatible), an X11 or XWayland session, and a driver exposing Vulkan 1.3. It bundles GLFW, the Vulkan loader and the rest of the non-system dependency closure; it does not bundle the graphics driver, which is specific to your machine. No sudo is involved: install.sh verifies every payload file against its published hashes, then copies into your own home.

Terminal
tar -xzf SaidaEngine-v1.0.0-beta.4-linux-x86_64.tar.gz
cd SaidaEngine-v1.0.0-beta.4-linux-x86_64
./install.sh          # no sudo; installs under your own home

saidaengine-hub       # or saidaengine-editor, or saidaengine-tool

# Portable instead, straight from the extracted directory:
./payload/SaidaEngineHub

# Uninstall:
"${XDG_DATA_HOME:-$HOME/.local/share}/SaidaEngine/1.0.0-beta.4/uninstall.sh"

Uninstalling deliberately leaves your projects and user state under ~/.local/share/saidaengine alone. On a server or container with no graphical session the editor and Hub are not supported, but saida_tool still works for headless commands.

#First launch

Hub, then a project, then the editor. Ten minutes to something moving on screen.

  1. Start SaidaEngine Hub. It lists the projects it knows about and offers + New Project….
  2. Give the project a name and a parent directory, then press Create Project. The default parent is Documents\SaidaEngine\Projects.
  3. The editor opens on the new project. The panels are Scene Tree, Inspector, File Browser, the viewport, plus Animation and Profiler when you need them.
  4. Build a scene: add nodes in the Scene Tree, set their properties and components in the Inspector, move them with the gizmos. Every durable edit goes through an undoable command, so Ctrl+Z is reliable.
  5. Press Play to run the scene inside the editor, and Stop to come back. Play is read-only: the document you were editing is restored on Stop, so a running game cannot dirty your scene file.

Beta 4 ships a sample project, WitnessGame, inside the package. It is the engine's own vertical test game — scenes, scripts, signals, physics, animation, audio, UI, save/load and a scene change — and it is the fastest way to see a complete project that works before you build your own.

The editor can also skip the Hub entirely when you already know the path:

PowerShell
# The editor can open a project directly, without going through the Hub.
SaidaEngine.exe --project "C:\Users\me\Documents\SaidaEngine\Projects\MyGame"

#Update and uninstall

Your projects are yours: they live outside the program and nothing here deletes them.

Where things go on Windows
%LOCALAPPDATA%\Programs\SaidaEngine       the installed program
%USERPROFILE%\Documents\SaidaEngine\Projects   where new projects are created
%APPDATA%\SaidaEngine\hub.json           the Hub's list of known projects
%APPDATA%\SaidaEngine\Games\<game>       a packaged game's saves and preferences
%APPDATA%\SaidaEngine\CrashReports\      crash reports and Windows minidumps
TaskHow
Update to a newer betaDownload the new release and install it. Betas are separate immutable tags; keep the old portable ZIP around if you need to reopen an older project.
Uninstall (installer route)Settings → Apps → SaidaEngine, or run Uninstall.exe from the install folder.
Uninstall (portable route)Delete the extracted folder.
What uninstalling removesThe files it installed plus the regenerable caches. It removes only folders that became empty — there is no blind recursive delete of the folder you chose.
What it never touchesYour projects under Documents, and your saves and preferences under the user profile.

#Scenes and behaviours

Nodes compose, behaviours do the work, signals carry the news. No god-controller, no gameplay singleton.

A scene is a tree of nodes. A node has a name, a transform, children, and a set of groups — the sanctioned way for anything to find it, instead of a global name lookup. Logic is attached as behaviours: small components with a clear responsibility, composed rather than inherited.

The engine ships behaviours for the things most games need — a tunable Character controller, a raycast Vehicle, Animator and AnimGraph, Health, StateMachine, Blackboard, CameraFollow, Spawner, SequenceDirector, LOD Group, AudioSource — and one, ScriptBehaviour, that runs your JavaScript.

Behaviours talk to each other through typed signals, cross-script calls and a shared blackboard, and a persistent autoload holds the state that has to outlive a scene change. Scene transitions and node removal are deferred, so a mutation can never invalidate the frame being rendered.

Projects, scenes and the authoring operations that mutate them are versioned JSON. An unknown type or a future schema is rejected outright rather than silently reinterpreted, and every project, script and import path is confined to the project's own root.

#Rendering

One renderer behind two backends, tuned for scenes that also have to run in a browser.

AreaWhat is there
BackendsVulkan 1.3 with dynamic rendering on desktop; WebGPU in the browser. GLSL is compiled to SPIR-V, then transpiled to WGSL for the Web.
MaterialsPBR metallic-roughness, lit and unlit, image-based lighting and ACES tonemapping.
LightingDirectional, point and spot lights, PCF shadow mapping, SSAO, DDGI global illumination, and xatlas lightmap baking.
Post-processingBloom and fog. MSAA on desktop; the Web player has none.
SkinningGPU skinning, with the depth pass using the same bone palette as the scene pass — an animated character casts the shadow of the pose it is actually in.
DiagnosticsAn editor profiler reporting camera and scene triangle counts at the renderer-selected LOD, collected only while it is open.

The engine is designed first for Web and mobile-class budgets, so startup time, CPU and GPU cost, allocations and memory footprint are treated as design constraints rather than as later optimisation. There is no heavy ECS and no general-purpose render graph: node composition and small abstractions instead, until a measurement justifies more.

#Physics

Jolt, wired into the scene as nodes you place rather than a world you configure elsewhere.

Node or behaviourUse
StaticBodyLevel geometry that does not move.
RigidBodySimulated dynamic bodies — crates, debris, vehicle chassis.
CharacterBodyA capsule controller with floor and slope state.
CollisionShapeThe shape a body collides with, recomputable from the mesh.
AreaA trigger volume; emits bodyEntered and bodyExited with the other node's name.
FixedJoint / PointJoint / HingeJointThe three joints qualified for V1.
CharacterThe tunable controller: acceleration, air control, coyote time, jump buffer, jump chains, turn modes, slope slide.
VehicleA raycast vehicle where each wheel is a ray and suspension, drive and grip are applied at the contact, so weight transfer comes out of the physics.

Scripts query the world with a filtered raycast and overlapSphere, both of which fail soft: with no physics world they answer nothing rather than throwing. Advanced constraints — slider, cone, motors — are not in V1.

#Animation

Import a rigged glTF, then drive it by clip name, by state graph, or by timeline.

CapabilityDetail
ImportglTF and GLB rigs and clips, plus BVH. Cubic-spline interpolation, retargeting, GPU skinning.
State graphsAn animation graph and state machine driven by a blackboard of float, bool and trigger parameters — the same parameters a script writes.
SequencesAuthored .sseq timelines with animation tracks, reflected property tracks and an event track that fires a signal your game can listen to.
Formats.sclip, .sgraph, .sretarget, .srig and .sseq, all loaded asynchronously without blocking the frame.
Fail-closedAn invalid graph or an unresolved sequence target disables playback with a logged diagnostic instead of half-applying itself.

A node that was imported from a model re-imports it when the scene loads, rather than serialising the whole imported hierarchy into your scene file — so re-exporting the model updates the game. Clip names and durations are inspectable from the CLI with saida_tool inspect-anim.

#Scripting and interface

JavaScript for gameplay, HTML and CSS for menus. Both sandboxed, both hot-reloading.

Gameplay scripting is QuickJS, attached to a node as a ScriptBehaviour. A script gets lifecycle hooks, inspector-editable properties, and a fixed set of capabilities: the node, the scene tree, time and timers, input, physics queries, audio, asset streaming and player storage. It gets no network, no filesystem and no OS access, and it edits and reloads while the game runs. The whole surface is documented in the scripting guide.

Interfaces are RmlUi. A heads-up display can be built from UICanvasNode and UITextNode nodes in the scene, which work on desktop and on the Web alike. On the desktop, a WebCanvasNode renders a real HTML/CSS document with a small DOM API for menus and richer screens; it hot-reloads transactionally, keeping the previous document on screen if the new one fails to load.

#Assets, audio and effects

Stream what you can, budget what is resident, and refuse content that would lie about itself.

KindAccepted
MeshesglTF and GLB, and OBJ. Meshopt is decoded at import and can be exported back from the import UI.
TexturesPNG and JPEG on every platform. KTX2 and Basis are a deliberate deferral, not an oversight.
AudioOgg Vorbis recommended, WAV accepted. MP3 and FLAC are not compiled in.
EffectsSaidaFX particles: a ParticleSystem node, .saidafx assets, presets from Fire to Rain, alpha and additive blending, shape emitters, drag, noise, attractors.

Assets load through an asynchronous loader with priorities and inspectable state, so nothing blocks a frame. During a scene, a GPU residency budget (512 MiB by default, adjustable from script) evicts the least recently used textures and meshes that the living scene no longer references. On a scene change, a mark-and-sweep frees what nothing holds any more.

Hostile or broken content is rejected at the door rather than half-loaded: glTF is validated after parsing, geometry with nothing usable in it is refused at decode, and a failed texture shows a magenta checkerboard instead of pretending to be fine. Audio is played by project alias, so gameplay code never names a file on disk.

#Tools around the editor

Everything the editor does by hand, something else can do without a window.

The headless CLI

saida_tool validates scenes, scripts, authoring operations, animation graphs, clip views, sequences and scenarios; inspects and cooks animation; renders and validates UI documents; compares a captured frame against a golden image; and exports a game. It prints JSON, returns meaningful exit codes, and is what continuous integration runs.

PowerShell
# Everything the editor's Build button does, without a window.
saida_tool.exe export-game MyGame.saidaproj --platform windows --out .\build

# The editor itself is scriptable too: same code path as the Build dialog,
# with the verdict as an exit code.
SaidaEngine.exe --project MyGame --build .\out
SaidaEngine.exe --project MyGame --build .\out-web --build-platform web

AutoLOD

A separate command-line tool built on meshoptimizer and xatlas. It generates level-of-detail chains inside a GLB, takes ratios and error thresholds, preserves open edges for modular assets, can bake a normal map from the high-poly version and can produce a far-distance proxy with a fresh atlas. Skinned meshes are out of scope.

MCP for AI assistance

The editor hosts a native MCP server so an assistant can inspect and modify a project through structured tools rather than by typing into files. The intended contract is per-tool permissions, validation, dry-run and diff, grouped transactions, snapshot and rollback, and an audit trail. Autonomous agents stay out of V1 for exactly as long as those guardrails are not closed.

Optional Python authoring plugin

saida-python-toolsis a standalone package for offline authoring chores — generators, converters, audits, asset reports. It is not built by CMake, never loaded by the editor or the runtime, and never copied into an export. Not installing Python changes nothing about your project or your shipped game.

#Shipping a game

An export is a folder you can hand to a player, or a folder you can serve.

The editor's Builddialog packages a project into a desktop folder containing the editor-less runtime, your scenes, assets, shaders and a boot manifest. Version, company, product name and icon are patched into the executable. The same operation exists on the command line, and the editor's own Build button is scriptable so a recipe runs exactly the code a human click runs.

A Web export produces the WebAssembly and WebGPU player instead. It must be served over HTTP or HTTPS — never opened from file:// — with the cross-origin isolation headers and the correct WebAssembly MIME type. Textures, OBJ meshes and animation assets are streamed on demand; scenes, scripts and glTF stay in the boot payload.

A packaged game writes its saves and preferences under the operating system's user data folder, keyed by the game's identity — never next to its own executable. Each desktop executable installs a crash reporter before boot, writing a text report and, on Windows, a minidump.

#Platform support

A platform counts as supported only when a clean release bundle has passed its verification.

SurfaceTargetWhat it needs
Desktop editor and playerWindows 11 x64A Vulkan 1.3 GPU and driver. The package ships its own GLFW and Vulkan loader.
Web playerRecent stable Chrome and Edge on desktopWebGPU enabled, a secure HTTP(S) context, cross-origin isolation, the right WebAssembly MIME type, IndexedDB.
Headless toolDebian 12 x64No GPU surface required for validation, folding and export.
Authoring WebAssemblyThe same browsers as the Web playerWebAssembly, ES modules and a host that follows the authoring contract.

Capabilities differ per runtime and the engine says so out loud: a platform capabilities report is logged at boot, and a missing backend fails or degrades explicitly rather than pretending to work. On the Web that means no MSAA, no WebCanvas documents, audio that waits for a user gesture, and touch input that desktop does not have.

#Known limits

The list the engine publishes about itself, unedited.

  • V1 exists only as a public beta. No beta, badge or green CI run equals stable qualification.
  • The Windows beta installer is unsigned. Authenticode signing needs the publishing key and a qualification of the signed bytes.
  • Web: WebGPU and HTTP are mandatory, the interface is limited to the HUD nodes, WebCanvas is absent, MSAA is absent, and gamepads without the standard browser mapping are ignored.
  • Point-light cubemap shadows and persistent lightmaps are absent.
  • XR lacks multiview MSAA, an overlay and a validated hardware matrix. A successful compilation is not a hardware test.
  • Advanced physics constraints (slider, cone, motors) and the extended animation API (scrubbing, root motion from script) are deferred.
  • A ray cast from a character controller currently hits the character's own inner body; the workaround is documented in the scripting guide.
  • Cloud saves do not exist. Local player storage does, with quotas, versioned envelopes and an explicit durability contract.

Performance claims are deliberately absent from this page. The engine's own rule is that any such claim requires a reproducible scene with a published GPU, driver, resolution, light, draw and particle counts, and CPU and GPU frame times.

#Building from source

Only if you intend to modify the engine. Playing with it does not require this.

The engine is GPL-3.0 and builds from a recursive Git LFS checkout. The supported Windows toolchain is MSYS2 UCRT64 with GCC, CMake and Ninja — do not mix MSVC, MINGW64 and UCRT64 binaries. A recent Vulkan GPU driver is required; the LunarG SDK is optional when the MSYS2 packages are installed.

MSYS2 UCRT64
git lfs install
git clone --recurse-submodules https://github.com/saias-o/SaidaEngine.git
cd SaidaEngine
git submodule update --init --recursive
git lfs pull

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build --parallel
ctest --test-dir build --output-on-failure

Web builds go through the Emscripten SDK and produce the player and the authoring surfaces separately. A public headless container image is also published for CI use:

Docker
docker pull ghcr.io/saias-o/saida-tool:latest

Pin a commit tag or an immutable digest for anything reproducible rather than the floating latest.

#Where to go next

Two guides and one repository.

  • The scripting guide — behaviours, the lifecycle, signals, autoloads and the complete JavaScript API, with examples taken from the engine's own demo games.
  • The engine repository — the canonical specification, the roadmap, the contribution rules and the release runbook, all kept in the repo rather than paraphrased elsewhere.
  • Releases — every beta is an immutable tag with its own notes, checksums and qualification statement.

Found a defect in a beta? That is what the beta is for. Report it against the exact tag you were running, since betas are never rebuilt in place.