orbistoun documentation

orbistoun is a high-level hardware emulator in Rust. Guest x86-64 code runs natively - the hardware CPU and your CPU are the same architecture - so the work is reimplementing the operating system underneath it and translating GPU command streams to Vulkan.

New here? The root README has the pitch and a one-command start, and THE_LOOP.md explains what the tool actually does, start to finish, including which steps still need a person. This page is the index to everything deeper.

The words

Repository layout

CRATES.md says what each crate is for - the dependency spine first, then execution, graphics, and tooling. It was the root README's "Workspace layout" section.

crates/         Cargo workspace members (see CRATES.md)
docs/           This documentation
docs/decisions/ One file per decision; DECISIONS.md is the generated index
docs/worklog/   One file per entry, in document order
docs/backlog/   One file per item, with a status column in the index
docs/roadmap/   One file per phase, likewise
tools/          Offline generators, mostly for the shader work - see tools/README.md
compat/         Per-title compatibility records - what we learned, always tracked
symbols/        Symbol databases produced by the name search - ours, so tracked
titles/         Guest modules - never tracked, and nothing here ever will be
frontend/web/   Static landing page; no build step
assets/         Logo and shared images
.githooks/      Pre-push static-analysis gate

Why crates/, not src/: in Cargo a workspace groups its member crates under crates/ - this is the Rust convention. src/ in Rust is a single crate's source. The repo root holds only the manifests and tool config that must live there (Cargo.toml, rust-toolchain.toml, deny.toml, licences); no application code sits at the root.

Architecture

Two ideas do most of the work.

The dependency spine. core -> elf -> nid -> mem -> hle -> loader, and only then the subsystem shims. This order is not stylistic: a subsystem shim is never reached until a guest has loaded, allocated, and spawned threads, so writing the audio shim before the address space works produces code that cannot be exercised.

Interception is linking. Guest modules import by NID - a 64-bit hash of the symbol name - and the loader resolves each one against the HLE registry, writing the result into the guest's relocation slots. There is no hooking pass. A consequence worth stating plainly: the complete list of what a title needs is available statically, before any guest instruction runs.

The honest status

No emulator for this target anywhere runs a commercial game. orbistoun is younger than the others, and what it does today is that every executable in the local corpus loads, links, and executes real guest code - while rendering nothing and having never spawned a guest thread.

Detail, deliberately unflattering, is in PROJECT_STATUS.md. The number that matters is the share of calls answered by a real implementation rather than a placeholder - not a screenshot, and not a raw call count, which rises when stubs start lying.

Reference

Guide

Written for somebody using orbistoun rather than changing it. These four were in the tree and in nothing's index, so the published docs listed them under Guide and this page did not mention they existed.

Start here

Build and contribute

Project

Next steps

Adding to a log

DECISIONS, WORKLOG, BACKLOG and ROADMAP are directories with a generated index. Add a file under decisions/, worklog/, backlog/ or roadmap/, then regenerate its table:

tools/split-decisions.sh --index orbistoun
tools/split-doc.sh --index orbistoun BACKLOG 3 backlog

Do not edit an index by hand - it is overwritten, and the splitter refuses to run over one. check-decisions.sh also fails if a ## Dnnn heading appears in the index, because an entry written there is read by nothing and lost on the next regeneration.

The split exists because two sessions appending to one file collide, and because this log reached 1,069,818 bytes - past the point where GitHub renders markdown at all.