A barebones game engine where every game is just a mod. The engine owns the window, GPU renderer, virtual file system, mod loader, ECS, native services such as physics and networking, and embedded TypeScript/JavaScript Wasm runtime. Gameplay lives in mods.
This enables the core philosophy of "you can do whatever": both developers and players are allowed to freely dissect and modify every part of the engine.
| Tool | Purpose |
|---|---|
| Rust + Cargo | Building the engine |
| Bun 1.4.2+ | Development dependencies, builds, tests and documentation |
# Build the engine-owned VM (Clang/LLVM with Wasm support required)
bun install --frozen-lockfile
rustup target add wasm32-unknown-unknown
bun run build:runtime
bun run build:guest
# Build native executables and stage their shared libraries
bun run build:native
# Run the client (or use core/meta.toml default_mode)
cargo run
# Run a headless server
cargo run -- --mode server
# Run with debug logging
cargo run -- --debug=all
cargo run -- --debug=ipc,modloader
# Load mods from a custom directory instead of mods/ and mods_user/
cargo run -- --mods /path/to/my/mods
# Run tests
bun run test:nativeBuilding the launcher from source for Windows MSVC requires Open Watcom 2.0
configured for DOS development, with wcl and wlink on PATH. The launcher
build compiles the Snake stub automatically. Open Watcom downloads
The native build helper configures the Rust library search path and stages the
matching Rust standard library. Use bun run build:native -- --release for an
optimized build. Player, editor and CLI share engine, scripting and graphics
libraries; keep binaries and libraries from the same build together.
Cargo.toml Workspace; plain cargo run/build selects the player
.cargo/config.toml Dynamic linking for native targets; Wasm builds stay independent
bun.lock Reproducible Bun development dependencies
AGENTS.md Architecture and contributor instructions
.gitattributes LF rules for SDK and mod sources
.editorconfig Editor defaults for mod sources
biome.json Shared mod-source formatter configuration
engine/ Shared whatever-engine native library (own Cargo.toml)
src/
lib.rs Shared engine services and tooling
engine.rs Client window, graphics, input and world snapshots
runtime/ Simulation worker, tick clock, modes and headless runner
editor.rs Atomic runtime edits and hierarchy projection
editor_transport.rs Private authenticated editor/player connection
performance.rs Native CPU phase and frame timings
scene/ Versioned scene documents and atomic instantiation
prefab.rs Named single-root templates and independent runtime spawning
references.rs Scene asset ownership and direct mod dependency validation
project/ Mod collections, scaffolding and managed game builds
build.rs Installed support discovery and automatic source builds
installation.rs Distribution paths and private native-library manifests
branding.rs Game icons and Windows launcher resources
paths.rs Portable paths and native presentation
files.rs Contained file operations, reference updates and local trash
sdk.rs Local TypeScript bindings to the installed editor SDK
starter.rs On-demand imports from the editor starter asset library
library.rs Asset library metadata, atomic imports and namespace remapping
library_archive.rs Portable ZIP pack/read validation and bounded extraction
library_tests.rs Archive, import, prefab and official-content integration checks
workflow_tests.rs Project, asset, SDK and dependency regression tests
renderer/ wgpu, cameras, meshes, sprites, text and shared world rendering
render.rs Renderer, pipelines and render passes
world.rs Shared ECS-to-render updates for player and editor
schema/ Shared value schemas and native validation
ecs/ Generational entities, typed components, hierarchy, references and tags
registry.rs Registered custom component schemas and defaults
snapshot.rs Mutation journals and revisioned scene deltas
tags.rs Bounded entity tags and queries
lifecycle.rs Inherited enabled state and deep entity cloning
presentation/ Frame deadlines, measured FPS and render-only pose interpolation
frame_clock.rs Phase-preserving FPS cap and time-weighted frame counter
motion.rs Adjacent tick poses, hierarchy interpolation and camera cuts
physics/ Native Rapier configuration, state and lifecycle
network/ QUIC, schemas/codecs, TLS and per-client data
script/ Source compiler, native capabilities and synchronous dispatch
sandbox/ Native file/VFS broker containment
mods/ Manifests, discovery, deterministic ordering and registry
vfs/ Layered asset and folder mounts
types.rs VFS trait, paths, errors and handle type
console/ Developer console, parser, completion and command registry
audio/ Audio playback and handle management
debug.rs Debug switches and category logging
logging.rs Log files, rotation and tracing setup
input.rs Keyboard/mouse accumulator
cursor.rs Embedded player cursor confinement and visibility
watchdog.rs Slow-tick diagnostics
resources/RUNTIME-LICENSES.md Embedded scripting third-party notices
resources/core/ Stock core template packaged with the editor
resources/starter/ Official .wasset source: prefabs, meshes, surfaces, UI, audio and scripts
script-vm/ Shared Wasmtime/QuickJS library; one embedded VM payload
src/runtime.rs Wasmtime instances, execution budgets and synchronous turns
src/tests.rs JavaScript/Wasm isolation and live-call regression tests
render-deps/ Shared graphics dependencies; keeps Windows DLL exports bounded
player/ Whatever executable; depends on shared engine crate
src/main.rs CLI, game loading, client/server entry point
editor/ Separate native editor application (own Cargo.toml)
src/app.rs Window, renderer, input and background build jobs
src/actions.rs Project/scene commands and native file dialogs
src/menus.rs Native menus and keyboard shortcuts
src/preferences.rs Text editor preferences, recent projects and welcome screen
src/mod_editor.rs Mod metadata and script creation
src/component_fields.rs Schema-generated custom component inspectors
src/component_reload.rs Background metadata inspection and status-bar progress
src/component_handles.rs Collider and joint handles in the scene viewer
src/ui.rs Workspace panels, browser, viewport and project settings
src/inspector.rs Typed core components and custom component editing
src/entity_picker.rs Entity references and hierarchy drops
src/presets.rs Native component helpers; object templates remain data
src/libraries.rs Searchable prefab catalog and background library import/export
src/browser.rs Folder navigation and typed asset tiles
src/asset_actions.rs Create folder, move, rename and recoverable delete dialogs
src/viewport.rs Surface picking and transform handles
src/viewport_geometry.rs Clipped overlays, rotated rings and camera frustums
src/player.rs Embedded player window hosting
src/live.rs Runtime hierarchy, live edits and temporary undo history
src/hierarchy.rs Tree, drag reordering and reparenting
src/document.rs Scene editing, undo/redo and safe saves
launcher/ Small branded game launcher; no engine dependencies
build.rs Builds and links the Snake stub for Windows MSVC
dosstub/ Standalone DOS Snake source and Watcom linker directives
wmod/ CLI companion using the same shared project tooling
games/ Ordinary game mod collections
test/ Development/test game; default player project in source builds
whatever.wproject Test project identity, mod selection and build settings
mods/ Its own core, debug, markbench, network_example and physics_demo mods
mods/markbench/ Deterministic workloads, scoring and reports
mods_user/ User-local development mods (gitignored)
graviton/ Separate game collection
coinwatch/ Starter-library FPS survival game with script navigation
whatever.wproject Editable single-core game project
mods/core/ Arena, game components and imported Whatever Starter assets
runtime/ @whatever-engine/api TypeScript package
guest/ Engine-owned minimal QuickJS Wasm guest (independent Cargo build)
polyfills.js Explicit text, buffer, timer and microtask services
src/lib.rs Guest ABI, JavaScript evaluation and bounded promise-job pump
compiler/ Embedded TypeScript transformation and static component metadata
components.ts Read-only class/field metadata extraction
environment.ts Contained virtual source filesystem
embedded/ SDK entry for engine deliveries and class registration
src/ Public namespaces, direct calls, compatibility requests and references
dispatch.ts Engine delivery and component/tick scheduling
live.ts Checked nested component field handles
input.ts Current tick input, physical key codes and immutable keyboard snapshots
time.ts Read-only simulation tick number and interval
schema.ts Shared Type descriptors and value validation
component.ts Custom Component classes and lifecycle scheduling
scene-store.ts Native scene reads and explicit retained snapshots
profiler.ts Native tick/frame measurements and monotonic clock
dist/ Built API, declarations and embedded Wasm guest (gitignored)
tools/ VM builds, generated assets and integration tests
build-script-assets.ts Embedded SDK/compiler bundle generation
build-script-guest.ts Reproducible QuickJS Wasm guest build and Windows LLVM support
build-native.ts Shared native build, loader setup and standalone game launcher
native-libraries.ts Native dependency closure, deduplication and relative loader paths
check-versions.ts Shared release version and lockfile audit
package-editor.ts Portable editor assembly, dependency bundling and relocation smoke
package-installers.ts MSI, DEB and PKG assembly with editor command registration
test-msi.ps1 Disposable-runner install, repair, upgrade and uninstall checks
process.ts Native child-process capture for packaging and tests
tests/native.ts Shared debug/release binary selection for integration tests
generate-starter.py Reproducible official library content generation
.github/workflows/
editor.yml Build/test portable archives and installers on Windows/Linux/macOS
release.yml Publish the same tested distributions on version tags
docs.yml Build/check modding docs and deploy main to GitHub Pages
docs/
releases/ Curated GitHub release notes
EDITOR.md Projects, native editor, CLI and branded deployment layout
ASSETS.md .wasset libraries, independent prefabs and official starter content
EMBEDDED_SCRIPTING.md Embedded VM/compiler, live calls and component references
SCRIPTING.md Public API, scene format and IPC reference
PHYSICS.md Native physics configuration and lifecycle
SHADER.md Shader contract, mesh formats and patterns
SANDBOX.md Wasm isolation, capabilities and broker containment
IPC.md Internal scripting ABI, source loading and execution order
website/ Astro Starlight modding documentation site
src/content/docs/ Authored tutorials and guides; references generated from docs/
scripts/ Reference generation and built-site link verification
astro.config.mjs Theme, navigation and configurable deployment base
The Astro Starlight site includes a first-mod tutorial, editor and component guides, the full scripting reference, and the native IPC specification with a message catalogue generated from the Rust definitions.
bun run docs:install
bun run docs:dev
# Build static HTML, the search index, and verify internal links:
bun run docs:buildThe existing docs/*.md references remain the source of truth. See
website/README.md for authoring and GitHub Pages setup.
The docs workflow checks pull requests and deploys main after Pages is enabled
with GitHub Actions as its source.
Run bun run build:native, then cargo run -p whatever-editor -- games/test to open the current mod collection. A project is a whatever.wproject manifest selecting ordinary mod directories. Scenes are versioned JSON .wscene files in each mod's scenes/ folder; scripts instantiate them with await Scene.loadScene("my_mod://main").
wmod creates projects and mods, validates collections and packages games through the same shared code as the editor. Deployed games contain a branded launcher, a bin/ directory with the player and shared libraries, and ordinary mod sources. See the editor and deployment guide for commands and the folder contract.
Choose Build Game and an output folder in the editor, or run wmod package <project> --output <folder>. The tools supply the player with its embedded VM and the branded launcher. Project settings control the game name, icon, company and version. Installed editor releases include their support binaries. A source checkout builds them when needed.
Biome formats JavaScript, TypeScript and JSON source under mods/, mods_user/ and games/ with 2 spaces, a 100-column line width and LF endings. Assets, dependencies and dist/ output are excluded. Gitignored local mods are included deliberately. The root biome.json is the shared configuration; .editorconfig provides matching editor indentation. Editors with Biome support can use this configuration for format-on-save.
bun run format # Format mod sources
bun run format:check # Check formatting without writing (also runs in CI)
bun run test:runtime # Check pending-result API types and shipped debug scriptsBiome is a pinned development dependency. Run bun install --frozen-lockfile after pulling the setup. Formatting does not enable lint fixes or import organization.
Each game owns its mods/ and optional mods_user/ (gitignored). The source checkout uses games/test. Each mod is a directory containing mod.toml.
[mod]
id = "my_game"
name = "My Game"
version = "0.1.0"
description = "A game built on the Whatever engine"
[script]
entry = "scripts/index.ts" # optional — omit if the mod has no scripts
[assets]
root = "assets" # defaultMods are loaded in topological dependency order. core always loads first.
Set default_mode = "client" or "server" in the [game] section of core's meta.toml. The CLI --mode client|server overrides it; old metadata defaults to client mode.
The simulation owns ECS and mod VMs on a worker with independent tick deadlines. It samples input/events, executes synchronous mod callbacks in dependency order, applies editor commands, advances native physics, then publishes presentation/editor state. Later calls and mods see preceding writes immediately. Async hooks do not overlap their own pending invocation. See tick semantics.
Rendering runs on the window thread and consumes the latest world snapshot and adjacent pose samples. Camera, geometry and moving lights interpolate local transforms between ticks for smooth presentation (roughly one tick of visual delay), without changing simulation/query/editor state. Reparenting, entity replacement and camera cuts snap to the new state. FPS caps use fixed deadlines, skip missed slots and do not accumulate wake-up delay. A slow tick does not block rendering; FPS caps, vsync and missing redraws do not schedule ticks. The simulation catches up after short overruns with fixed-size steps and drops excess backlog after a long stall. Published snapshots currently copy the world; pending GPU updates coalesce by entity and renderer type while frames are paused.
The player's F1 overlay shows presented frames and completed simulation ticks per second, both measured against wall time. With VSync on, the player requests a one-frame presentation queue and waits for the next buffer on a worker. The window thread keeps processing input and uses the latest simulation snapshot once the buffer is ready.
Server mode creates no window, graphics context, egui context or audio output device. It uses the same simulation worker with empty input. Enter built-in or mod console commands on stdin (help, help dev, netdemo codec). Stop it with Ctrl+C, SIGTERM on Unix, or quit / stop. The executable still links desktop libraries; a smaller server-only build is separate future work.
Mods may set sides = ["client"], ["server"] or ["client", "server"] inside [mod]. Omission supports both sides. Inactive mods are filtered before dependency checks and load ordering; active dependencies must exist on the selected side.
A script may provide a shared fallback and side overrides:
[script]
entry = "scripts/shared.ts" # optional fallback
client = "scripts/client.ts" # optional override
server = "scripts/server.ts" # optional overrideOnly one entry executes per mod. A mod with no matching entry still contributes its assets and metadata. Engine.mode is available before top-level mod evaluation. Window, audio and presentation settings reject server use; ECS, files and inter-mod messages remain available. The shipped core script and visual demo mods run on the client.
Run bun run test:server after building the embedded guest and engine to check headless startup and shutdown. The additional cargo test --workspace client_ticks_without_redraws -- --ignored integration case uses the embedded VM and verifies client ticks with a 1 FPS cap and no renderer consuming snapshots.
Rapier 3D runs natively on the simulation worker after mod commands and before world snapshots/results are published. Mods configure ordinary ECS world/body/collider/joint components, with typed entity references and native tuning options. See the physics API.
To try the shipped client playground, open the F2 console and enter
physicsdemo start. Use WASD to walk, Shift to sprint, the mouse to orbit, and R to
respawn. physicsdemo cubes [count] adds cubes; physicsdemo stop removes the scene
and restores the previous camera. The mod creates nothing until activated.
Assets are accessed via mod_id://relative/path:
core://shaders/sprite.wgsl
my_game://textures/player.png
- Create
games/test/mods_user/<mod_id>/mod.toml - Add assets to
games/test/mods_user/<mod_id>/assets/ - Optionally add
scripts/index.tsand set[script]inmod.toml cargo run— the mod is discovered and loaded automatically
Scripted mods run in isolated QuickJS Wasm instances inside Wasmtime. The engine discovers raw JS/TS/JSON sources, extracts metadata and compiles them on the destination machine using its embedded TypeScript compiler. Installed games are self-contained and mods distribute source. Entity/component operations and physics queries execute immediately against native state. See embedded scripting.
The VM embeds @whatever-engine/api. Leave it external in mod bundles. Installing the package is optional for editor types. The VM resolves only this package and contained local sources. See runtime policy.
See docs/SCRIPTING.md for the full reference.
After editing runtime/src/, regenerate index.d.ts:
bun run build:runtimeNew games own their main scripts, scenes and assets in core. The editor imports editable starter assets from its separate library when needed. The source checkout's test game keeps its own shaders and font. Diagnostic scripts and sample assets live in games/test/mods/debug. Open F2 and enter help dev; nested help works too, such as help dev render light. Tests that delay ticks, log every tick or exercise the sandbox run only when requested. The client debug suite provides the demonstration camera; the server entry imports only headless tools. Markbench replaces the Mandelbrot test with deterministic engine workloads, native timings and automatic scores. Run markbench run quick or markbench run standard.
games/test/mods/network_example is a QUIC messenger with separate client/server entries and a shared typed specification. Start a headless server and run netdemo host 4444; in each client (F2), run netdemo connect localhost:4444. Clients receive increasing player IDs and can use netdemo tell 2 "hello", netdemo say "hello everyone", netdemo players and netdemo ping (QUIC datagram). The demo defaults to TOFU; add strict after the address to require a trusted certificate. See Network API for transport, trust and client-data details.
TLS keys and saved trust live in the engine-owned local-data directory WhateverNetwork/<game_id>, outside mod file access. Servers generate a persistent development identity automatically, or operators can supply --tls-cert <chain.pem> --tls-key <key.pem>. Clients use the OS trust roots, optionally extended with --tls-ca <authority.pem>. --network-data <directory> selects an isolated identity/trust directory, useful for tests and separate server instances. Players provide only a server address.
The integration demo can run without windows or audio devices after building the embedded guest and engine: cargo test --workspace --locked network_messenger -- --ignored. Native QUIC/TLS tests also run under WSL with a separate Linux Cargo target directory.
bun run test:network runs schema/proxy tests and compiler checks against the generated public declarations. Native codec and registration tests run with cargo test --workspace. bun run test:server also exercises native network calls and stdin mod commands through embedded VMs.
Every run writes to logs/latest.log. On startup the previous file is gzip-archived as logs/yyyy-mm-dd_hh-mm-ss.log.gz (timestamp from its creation date). Both paths are gitignored.
Log line format:
[HH:MM:SS.mmm] [LEVEL] message — engine events (INFO / WARN / ERROR)
[HH:MM:SS.mmm] [category] message — debug category (ipc / modloader / window / vfs)
Stdout mirrors the log with ANSI colours (WARN yellow, ERROR red). The in-game developer console (F2) also shows INFO and above in real time.
Suggestions are sorted alphabetically; Up/Down cycles through the full list and previews the selected completion as dim text in the input. Tab or a click accepts it, while Enter runs only the text already entered. Escape dismisses suggestions first, then closes the console. The input stays anchored when suggestions appear. Help lists command usage and descriptions on separate, wrapping lines.
Console command collisions qualify every participant as <namespace>:<command>
(engine built-ins use core); the ambiguous plain name stops resolving. Duplicate
registrations within a namespace are errors, including a core mod shadowing a built-in.
Use scene load debug://editor to instantiate a scene from a loaded mod, or
core:scene load debug://editor if another mod also registers scene.
By default only events from this crate are captured. Set RUST_LOG to override:
RUST_LOG=debug cargo run # all levels from this crate
RUST_LOG=wgpu=warn,whatever_engine=debug cargo run # also include wgpu warningsPass --debug=<flags> to enable verbose category logging (comma-separated).
Lines are written to logs/latest.log alongside normal output and appear in the dev console (F2).
| Flag | What it logs |
|---|---|
all |
All categories below |
ipc |
Script diagnostics (legacy category name retained) |
modloader |
Mod discovery, dependency resolution, load order |
window |
Window lifecycle events |
vfs |
VFS reads, overrides, and cache misses |
Portable editor CI runs on Windows 2025, Ubuntu 24.04 and macOS 15 (Apple Silicon). Each job
builds and tests the workspace in the release profile, then assembles a release
archive and platform installer and runs relocation and installation checks. Windows
uses MSI, Ubuntu/Debian uses DEB, and macOS uses PKG. Installers register
whatever-editor and wmod for terminal use. Version tags publish the
exact distributions from successful main-branch CI for the tagged commit; all three platforms
must pass and their artifacts must still exist. Run bun run package:editor after bun run build:native -- --release
to reproduce packaging locally. See EDITOR.md for distribution
contents, platform requirements and live Scene/Play editing.
Rust components inherit [workspace.package].version. bun run check:versions
checks them, their lockfile entries and the npm workspace/API versions together;
release tags must match too. Game and mod versions are independent.
We skipped releasing 0.5.0 on the way from 0.4.0 to 0.6.0, so now it's a
tradition: Whatever release versions never contain the digit 5, including
prerelease and build identifiers. We always go from 4 to 6: 0.14.0 jumps to
0.16.0, 1.4.0 to 1.6.0, and 0.6.4 to 0.6.6. The version check enforces
this for the shared engine, tools and scripting API releases.