Table of Contents

Architecture

OpenAC is organized by dependency layer. Lower layers never reference higher ones, and the game's state lives in one place regardless of whether a window is open.

                 ┌──────────────────────┐   ┌──────────────────────┐
                 │   AcDream.App        │   │   AcDream.Headless   │
                 │ Vulkan renderer,     │   │ no-window host,      │
                 │ game UI, audio,      │   │ bots, multi-session  │
                 │ input                │   │ scheduler            │
                 └──────────┬───────────┘   └──────────┬───────────┘
                            └──────────┬───────────────┘
                              ┌────────▼────────┐
                              │ AcDream.Runtime │  GameRuntime: session,
                              │                 │  entities, inventory,
                              └────────┬────────┘  movement, physics, magic
                    ┌──────────────────┼──────────────────┐
           ┌────────▼───────┐ ┌────────▼───────┐ ┌────────▼────────┐
           │ AcDream.Core.  │ │ AcDream.       │ │ AcDream.Platform│
           │ Net            │ │ Content        │ │ paths, RID,     │
           │ UDP, ISAAC,    │ │ DAT reader,    │ │ OS services     │
           │ messages       │ │ prepared pak   │ │                 │
           └────────┬───────┘ └────────┬───────┘ └─────────────────┘
                    └─────────────────┬┘
                             ┌────────▼────────┐
                             │  AcDream.Core   │  gameplay, physics,
                             │                 │  anim, world logic
                             └─────────────────┘

Projects

Project Responsibility Depends on
AcDream.Platform Portable application paths (XDG on Linux, LocalAppData on Windows), runtime identity, process services. BCL
AcDream.Core Gameplay logic: physics and collision, movement, animation, terrain, scenery, spells, world rules. Pure logic, no window or GPU. Plugin.Abstractions
AcDream.Content Reads the game's DAT files and the machine-local prepared package acdream.pak. No graphics dependency. Core
AcDream.Core.Net The wire protocol: UDP transport, ISAAC cipher, fragment assembly, reliable delivery, and every game-message parser and builder. Core
AcDream.Runtime GameRuntime, the presentation-independent kernel. Owns the session, entities and objects, inventory, character state, selection and interaction, combat and casting, local movement, physics simulation, projectiles, environment, and portal transit. Exposes borrowed views, typed commands, and ordered deltas. Core, Core.Net, Content, Platform, Plugin.Abstractions
AcDream.App The graphical client: Vulkan 1.3 renderer over Silk.NET, world streaming, the game UI built from the game's own layout data, audio, and input. Projects runtime state; owns no gameplay truth. Runtime, UI.Abstractions, Core, Core.Net, Content, Platform
AcDream.Headless Runs one or many GameRuntime sessions without a window: deterministic bot commands and events, a scheduler, shared immutable content, resource telemetry. Windows and Linux. Runtime
AcDream.UI.Abstractions Input actions, key chords and bindings, the input dispatcher, view models, and panel contracts shared by the game UI and plugins. Core, Runtime
AcDream.Plugin.Abstractions The BCL-only contract plugins compile against: game state, events, commands, and markup panels. Plugins never reference AcDream.App. BCL
AcDream.Bake Offline tool that builds acdream.pak from the DAT files. Content, Platform
AcDream.Cli Offline DAT inspector. Core
AcDream.Launcher.Core Installer, verified downloader, atomic updater, self-updater, profiles, and the client process supervisor. Testable without a GUI. Platform
AcDream.Launcher The Avalonia desktop launcher over Launcher.Core. Launcher.Core

samples/ holds three render-pack samples that exercise the renderer's extension points. tools/ holds the shader compiler and the render-pack validator (see tools/README.md).

The two rules that shape the code

Behavior comes from the original game. Anything the original client did in the world (how a slope stops you, when an animation swaps, what bytes go on the wire) is reproduced as observed. Readable structure, original semantics.

Gameplay truth has one owner. GameRuntime and its owners hold the only copy of session, entity, inventory, movement, and physics state. The graphical client and the headless host borrow views of the same objects; neither keeps a mirror. This is what lets a bot and a window run the same game.

Walks, moves and jumps the client carries out on its own are layered the same way. AcDream.Core.Navigation plans with no client state: it captures the collision world into a grid of standing points and searches routes and leaps over it. AcDream.Runtime owns the moving parts: the walk controller, the route driver and scripted movement, the plugin navigation API (RuntimeNavigationAutomation) and the /nav and /motor chat commands. Both hosts construct those same objects, so a plugin navigates identically in the graphical client and headless; the graphical client adds only the debug overlay. Physics is read on the update thread, while grids are built and searched on worker tasks from a captured copy. See navigation.md for the design, the API and the known limits.

Content model

The client reads the game's DAT files directly for most data. World meshes and collision, which are expensive to decode, come from acdream.pak, a validated memory-mapped package that AcDream.Bake produces once per machine from those same DAT files. The package is machine-local and never committed.

Rendering

The renderer is Vulkan 1.3 only, through Silk.NET, with bindless textures and multi-draw indirect. Shaders are GLSL compiled to committed SPIR-V by tools/compile-shaders.ps1; a test re-hashes the sources against the manifest so a stale binary fails CI. The startup capability probe reports an actionable error if the device lacks a required feature.

UI

The gameplay UI is the game's own: layouts are imported from its layout data and bound to runtime state by focused controllers. Plugin panels use a markup vocabulary documented in plugin-ui-markup.md and render in the same look.

Tests

Most src projects have a matching tests/AcDream.<Name>.Tests project. Tests that need something the machine may not have carry a Lane trait (InstalledDat, PreparedPackage, Live, Vulkan, Windows, Linux, Timing, Manual, SystemFont); the portable filter in release-gate.md excludes them, and CI runs the hardware lanes on machines that have the hardware.