BeamNG.Earth
A 1:1 scale streamed Earth for BeamNG.drive: real elevation and satellite imagery, floating origin, LOD streaming from a companion server
How Aether works and how to build with it — for agents and humans.
GamesRust · PythonGitHub @iamacoffeepotOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
A pre-1.0 application engine for games and tools: a native substrate hosting native and WebAssembly actors over typed mail.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
aether is an application engine for games, tools, and interactive systems. A
thin native substrate owns the window, the GPU, audio, files, and the
network, and hosts both native and WebAssembly actors; actors never call
each other, they only send typed mail to a mailbox. A chassis
picks which native capabilities a process composes, so the same actor runs
under the desktop profile with a window and a wgpu renderer, under the
headless profile driven by a timer, or inside a test harness that reads back
frames.Read the full README ↗aether is an application engine for games, tools, and interactive systems. A thin native substrate owns the window, the GPU, audio, files, and the network, and hosts both native and WebAssembly actors; actors never call each other, they only send typed mail to a mailbox. A chassis picks which native capabilities a process composes, so the same actor runs under the desktop profile with a window and a wgpu renderer, under the headless profile driven by a timer, or inside a test harness that reads back frames.
What that buys you: a world drawn from world-space triangles, textured quads,
GPU shapes and text; a mesh DSL and OBJ import; audio with sampled instrument
banks and streamed tracks; keyboard, mouse and window input as subscriptions;
files, HTTP, TCP, subprocesses and the clipboard as ordinary mail. Guest code
compiles to wasm32-unknown-unknown and is loaded, replaced in place, and
introspected while the engine runs.
The engine is also driveable from outside the process. A test harness, a human at a console, or an agent can start engines, load and replace code, inspect live contracts, capture frames, and gather evidence over framed RPC without linking into the runtime.
The project is a Rust 2024 workspace and is still moving. Current code defines
what ships; Accepted Architecture Decision Records under docs/adr/ preserve
the load-bearing design and its rejected alternatives. A few applications built
on the engine live in this tree today, the release demo among them; they
consume the library rather than belong to it. The
engine is written with an AI coding agent as a deliberate bet, under recorded
decisions and CI gates; How this is built says exactly
what that means.
The full mdBook navigation lives in SUMMARY.md.
operator
│ MCP / framed RPC
▼
stable tunnel → aether-mcp → hub + artifact stores
│ engine id
▼
child substrate
┌──────────────────────────┐
│ chassis capabilities │ native actors
│ registry + scheduler │ mail runtime
│ wasm components │ guest actors
│ logs/traces/cost/capture │ evidence
└──────────────────────────┘
aether-mcp adapts agent-facing JSON tools to live engine RPC/mail. The tool's
active schema is the argument reference.Read Process topology and chassis and Guest/native boundaries for the detailed model.
Prerequisites: rust-toolchain.toml pins the toolchain and adds the
wasm32-unknown-unknown target, so rustup installs both on first use. On Linux
the audio and GPU crates need system packages: libasound2-dev to build, and
mesa-vulkan-drivers to run the rendering tests without a GPU (CI installs
exactly these). Component scenarios in the test suite need the component wasm
built first: run cargo xtask build-wasm once before cargo test. A scenario
whose wasm is missing fails rather than skipping; set AETHER_ALLOW_WASM_SKIP=1
to take the skip deliberately. The fleet-harness scenarios also need the
chassis binaries, which cargo xtask dist packages together with the wasm into
dist/.
The workspace root has no default binary.
cargo build
cargo test
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo fmt -- --check
Run a chassis explicitly:
# Desktop: window/input/GPU/audio profile
cargo run -p aether-chassis-desktop --bin aether-desktop
# Headless: timer-driven engine profile
cargo run -p aether-chassis-headless --bin aether-headless
# Hub: fleet supervision and artifact stores
cargo run -p aether-chassis-hub --bin aether-hub
Use --print-config after the binary separator to inspect the knob registry and
its environment/default selections without booting the engine. This discovery
dump runs before config-file and per-capability CLI overlays, so it is not the
final effective configuration:
cargo run -p aether-chassis-headless --bin aether-headless -- --print-config
cargo xtask package --profile release --spec crates/aether-demo/demo.json --assets crates/aether-mesh/examples
A teapot authored in the mesh DSL, drawn by the kit mesh viewer and framed
by the kit camera and camera controller: WASD pan, the arrow keys yaw and
pitch, and Z/X zoom. Nothing is sent by hand; the demo's last component sends
the viewer its load at boot. The image above is a desktop-chassis capture of
that composition. The command writes a depot to target/package/; run
target/package/aether-desktop with no flags at all, because everything the
demo needs is inside it.
Without packaging, the same composition runs straight out of the checkout — build the component wasm, then boot the desktop chassis against the demo's boot manifest (from the repository root, since a boot manifest resolves its paths against the working directory):
cargo xtask build-wasm
cargo run -p aether-chassis-desktop --bin aether-desktop -- \
--boot-manifest crates/aether-demo/demo.boot.json \
--assets-dir crates/aether-mesh/examples
See crates/aether-demo/README.md.
Pre-1.0. Every crate carries one workspace version (0.3.0-alpha on this
commit) and none are published to crates.io yet. APIs move between minor
versions; the ADRs record why, and docs/adr/ is the place to check before
depending on a subsystem. What changed since 0.3.0-alpha is in
CHANGELOG.md.
Error policy: unwrap and expect are clippy-denied in production code, so
the several thousand hits a grep finds are test assertions. Errors cross
boundaries as typed enums. A trap inside the native runtime aborts the process
on purpose (ADR-0063) rather than continuing on corrupted state.
Working today: the desktop, headless, and hub chassis and the in-process substrate harness; the mail scheduler and settlement tracking; wasm component load, drop, and in-place replace with state carried across the swap; rendering (world triangles, textured quads, GPU shapes, text) with a depth-tested camera; audio with built-in and sampled instruments plus streamed tracks; window control and native menus; input subscriptions; file, HTTP, TCP, subprocess, and clipboard capabilities; per-actor logs, traces, and cost tables; frame capture; the package depot; and the two in-repo test harnesses.
Not here yet: no scene or asset editor application and no control set (a screen is drawn from render shapes and text draws); no replication or netcode layer, only the framed RPC the hub and its engines speak plus the HTTP and TCP capabilities; no asset pipeline beyond the mesh DSL, OBJ import, WAV and SFZ audio, and TTF fonts, so there is no importer, no texture format past raw RGBA pixels, and no asset build step.
Start the local MCP stack only when a task needs it:
scripts/ensure-tunnel.sh
Codex reads the aether-hub endpoint from .codex/config.toml; MCP clients that
consume .mcp.json use the same local endpoint. Starting a subprocess cannot add
tools to an already-open client session, so reconnect the server in that surface
if the mcp__aether-hub__* tools are still absent.
A safe session follows this loop:
list engines
→ spawn one owned engine
→ inspect live kinds/handlers
→ upload before selecting an artifact
→ load/send/observe
→ terminate the exact owned engine
Stored artifacts, running engines, and loaded component instances are separate resources. Read Operating a live engine before automating fleet or replacement work.
A component crate exposes a wasm cdylib and depends on aether-actor.
use aether_actor::{ActorInitError, WasmActor, WasmCtx, WasmInitCtx, actor};
use aether_kinds::{Ping, Pong};
pub struct Echo;
#[actor]
impl WasmActor for Echo {
const NAMESPACE: &'static str = "example.echo";
fn init(_ctx: &mut WasmInitCtx<'_>) -> Result<Self, ActorInitError> {
Ok(Self)
}
#[handler::request]
fn on_ping(&mut self, _ctx: &mut WasmCtx<'_>, ping: Ping) -> Pong {
Pong { seq: ping.seq }
}
}
aether_actor::export!(public = [Echo]);
For multi-actor modules, every export lives in one public list:
aether_actor::export!(public = [Console, Inspector, Worker]);
A load names the type by namespace unless the module exports exactly one.
Build for wasm32-unknown-unknown, call upload_component with the
artifact path, then call publish/load_component with the returned
registry selector—not a host wasm path.
See Writing a component and Components and lifecycle.
| Layer | Crates | Responsibility |
|---|---|---|
| Data and wire | aether-data, aether-codec, aether-math, aether-kinds | ids, schemas, canonical encoding, framing, shared vocabulary |
| Guest SDKs | aether-actor and its derive crate | actor authoring, exports, contexts, replies |
| Runtime | aether-substrate | registry, mail, scheduler, native/wasm hosts, settlement |
| Native services | aether-render, aether-audio, aether-fs and the rest of aether-<cap> | one crate per capability mailbox: render, text, audio, clipboard, window, FS, HTTP, TCP, process, RPC, component, lifecycle, fleet, inventory, trace |
| Chassis and harnesses | aether-chassis + aether-chassis-* | per-chassis crates over a shared composition layer; harnesses in aether-harness-* |
| Guest actors | aether-kit, aether-mesh, aether-demo | camera and mesh viewer; the geometry DSL library; the release demo's bring-up component |
| Operator bridge | aether-mcp | MCP tools, live schemas, RPC and bounded evidence projection |
| Tooling | xtask, fixture crates, excluded fuzz/ | dist/bundle discovery, compatibility artifacts, nightly fuzz targets |
Capability request/reply kinds normally live with their capability, in that
capability's own crate at aether-<cap>/src/kinds.rs. aether-kinds is
reserved for genuinely cross-cutting or explicitly upstream contracts.
Choose the narrowest boundary that proves the change:
fuzz/ crate for untrusted parsers and wire boundaries.See Tests that earn their place and SubstrateHarness and FleetHarness.
Packaging commands have distinct outputs:
cargo xtask dist # component wasm + chassis artifacts + dist/manifest.json
cargo xtask package --chassis desktop --components aether-kit
# a shippable depot: chassis binary + content-addressed pack/
They are not the same operation as landing a PR or publishing a versioned release. Read Distribution and packaging.
Planned work lives in GitHub issues. Managed issue-body sections hold the Plan,
declared surface, and size/model route; a hidden trusted record binds approval
to that Plan digest and an exact base commit. Implementation uses one isolated
issue worktree and draft PR, never the primary main checkout. PR titles and
commits use Conventional Commits. Before opening or updating a draft, run:
cargo fmt -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
GitHub Actions owns the expensive build/test matrix; CI pass and Lint title
are the checks a head must pass before it lands (main has no branch
protection, so nothing enforces them). The draft's current head must also have no active change
request, resolved threads, and declared-surface containment. Landing is an
explicit separate operation. Keep PRs focused, preserve unrelated user changes,
and do not push directly to main or merge
without that authority. The full lifecycle is written up in
Agent and contributor workflow.
Repository-agent mechanics are surface-specific:
AGENTS.md, .agents/skills/, and the active Codex tool schema.CLAUDE.md and .claude/skills/.Architecture and public APIs are shared; tool syntax and workflow harnesses are not translated by mechanical substitution. Human contributors can start at CONTRIBUTING.md.
docs/guide/ — task-oriented mdBook source.docs/adr/ — numbered decision records; check status and supersession.AGENTS.md / .agents/skills/ — Codex repository constraints and workflows.CLAUDE.md / .claude/skills/ — the same for Claude Code..github/workflows/ — hosted CI; conventions in its README.Build the guide with mdBook (cargo install mdbook; CI pins 0.4.40):
mdbook build docs
See Maintaining the guide before changing navigation or adding a high-drift recipe.
This codebase is developed with Claude Code. Every load-bearing decision is
recorded as an Architecture Decision Record before the code lands; the records
sit under docs/adr/, each carrying the alternatives that were rejected and
why. Every change arrives as a pull request. Its CI pass check aggregates
formatting, clippy with warnings denied, rustdoc, the sharded test suite,
duplicate-code detection, unused-dependency detection, lockfile freshness, and
a check on newly added lint suppressions, and a pull request lands on main by
squash-merge once that check and the Lint title check are green.
Licensed under either Apache License 2.0 or MIT, at your option. Contributions are dual-licensed under the same terms unless explicitly stated otherwise; see CONTRIBUTING.md.