Concept index
The routing table. Search a concept (the search icon or S), open the named
files, start reading at the entry symbol. Paths are repo-relative; every row
was verified against the tree. For API detail run
cargo doc --open -p <crate> locally - every crate exposes a prelude. For
prose depth, follow the chapter linked at each group heading.
Boot and frame flow
Depth: Architecture.
| Concept | Crate(s) | Key files | Entry symbol | Orientation |
|---|---|---|---|---|
| App boot, app assembly, plugin order | nova_core | crates/nova_core/src/lib.rs | AppBuilder | build() wires the whole plugin stack; game binary + CLI flags in src/main.rs. |
| Game states, pause | nova_gameplay, nova_menu | crates/nova_gameplay/src/lib.rs, crates/nova_menu/src/pause.rs | GameStates, PauseStates | State enums + GameMode live in gameplay; ESC overlay, toggle_pause and the clock freeze in menu. |
| Frame flow: Update vs FixedUpdate | nova_ship, nova_gameplay | crates/nova_ship/src/lib.rs, crates/nova_gameplay/src/plugin.rs | SpaceshipSystems | NovaShipPlugin chains the set brackets identically in both schedules; avian physics runs in FixedPostUpdate. Which schedule your system goes in: the Architecture chapter. |
| Units: meters, and the one engine seam | nova_events, nova_ui | crates/nova_events/src/units.rs, crates/nova_events/src/scale.rs, crates/nova_ui/src/units.rs | Meters, METERS_PER_UNIT | Everything authored, named as a constant or shown to a player is SI; Bevy, avian, meshes and the build grid count in world units at 10 m each. to_engine/from_engine are the only crossing and every call site is a documented boundary; nova_ui::units formats a readout without converting. The whole rule, and what stays engine-side: Architecture. |
| Asset loading gate, mod merge | nova_assets | crates/nova_assets/src/plugin.rs, crates/nova_assets/src/merge.rs | GameAssetsPlugin | GameAssetsStates gates entry to the menu/game; register_bundles merges base + enabled mods into the Game* resources. |
The ship
Depth: Ship sections internals.
| Concept | Crate(s) | Key files | Entry symbol | Orientation |
|---|---|---|---|---|
| Ship building from sections | nova_scenario, nova_ship | crates/nova_scenario/src/objects/spaceship.rs, crates/nova_ship/src/sections/base_section.rs | insert_spaceship_sections | Observer on the ship root spawns one child per SectionKind config, resolving prototypes; SpaceshipConfig is the authored shape. |
| Section integrity: damage, disable, destroy | nova_gameplay | crates/nova_gameplay/src/integrity/mod.rs, crates/nova_gameplay/src/damage.rs | NovaIntegrityPlugin | Health store and the disable/destroy chain; typed DamageType + the travel rule (apply_damage, pierce_remainder). Health decides WHEN a body dies; the two readings below decide what it looks like. |
| How far gone a body looks | nova_gameplay | crates/nova_gameplay/src/integrity/erosion.rs | DamageLevel | One scalar, 0..1, derived from the entity’s OWN Health. Grades every whole-body effect. |
| Where a body was hit (marks, carve cost, merge) | nova_gameplay | crates/nova_gameplay/src/integrity/carve.rs | DamageMarks, mark_radius | Spheres in the body’s local frame, priced by what the hit ABSORBED at DAMAGE_PER_UNIT_VOLUME (8 hp per cubic WORLD unit, so per 1000 m^3 - an inverse volume, and engine-side for that reason); record_blast_marks cuts one crater per body. |
| Authored per-section damage looks | nova_ship | crates/nova_ship/src/sections/damage_effects.rs, damage_cracks.rs, damage_sparks.rs, damage_plume.rs | DamageEffects, fit_damage_effects | Cracks/Sparks/Plume, one component each, default [Cracks]. No ship section ever loses geometry. |
| Carve debris: dust and severed pieces | nova_gameplay | crates/nova_gameplay/src/integrity/spew.rs, crates/nova_gameplay/src/integrity/chunk.rs | CarveSpew, ShardLook, spawn_carved_chunk | Shards are keyed on the WEAPON CLASS - kinetic and pierce chip, explosive does not; only a cut that SEVERED material spawns a real body, floored at CHUNK_MIN_VOLUME. |
| Severing, wreck fragments, structural collapse | nova_ship | crates/nova_ship/src/sections/integrity.rs | ShipIntegrityPlugin | Builds the section graph, splits disconnected structure (sever_disconnected_structures -> ShipWreckFragmentMarker), runs cascade_structural_collapse. |
| Neutralization (combat-dead) | nova_gameplay | crates/nova_gameplay/src/integrity/neutralize.rs | NeutralizedMarker | An armed ship that loses all weapons, or the flight computer it had, fires OnNeutralizedEvent; an unarmed ship instead goes this way on the last working thruster it ever had (HadThruster); the hull may survive. |
| Neutralized brake (a beaten hull stops on its own RCS) | nova_ship | crates/nova_ship/src/flight/neutralized_brake.rs | NeutralizedBrakeType, neutralized_brake_system | A neutralized non-player, non-station root brakes toward world rest by writing its RcsIntent, paid from its own RcsBudget; no engine needed. Docked, no computer, RCS off, empty, or a well past RCS_GRAVITY_AUTHORITY ends it for good; AI writers and helm orders refuse the hull. |
| Procedural hulls: the collapse, the plan | nova_wfc | crates/nova_wfc/src/lib.rs, crates/nova_wfc/src/collapse.rs, crates/nova_wfc/src/tiles.rs, crates/nova_wfc/src/plan.rs | TileSet, WfcPlan | TileSet::build reads a WfcPlan against the section catalog; hull() collapses one seed into a ShipDesign and runs it through the game’s own content lint before handing it out. The plan is CODE, not content: WfcPlan::standard_hull is the shipped one, and each caller (the editor’s Generate block, wfc_arena) builds its own from that plus its own UI rows. Grid geometry, seeds and zones: crates/nova_wfc/src/grid.rs. Whether a part can stand on the grid at all is nova_ship::cell_grid_fit, and nova_ship::oriented_part reads it as grid cells at one cube rotation (crates/nova_ship/src/sections/cell_grid.rs); the open-world part snapshot and ship layout (crates/nova_world_base/src/ship_layout.rs) read both too. |
| Ship skins, styles, greebles | nova_ship | crates/nova_ship/src/sections/shell_skin.rs, crates/nova_ship/src/sections/skin_style.rs, crates/nova_ship/src/sections/skin_surface.rs, crates/nova_ship/src/sections/greeble_solver.rs, crates/nova_ship/src/sections/skin_decor.rs | ShipSkinPlugin | Cladding derived from structure; styles resolve by id (ShipStyleConfig, GameStyles). A style authors a two-surface StylePalette, its fixtures and greeble_rules (GreebleRules: link types, greebles with four link points, near terms, caps). solve_decor solves the rules over the skin’s quad graph (skin_surface, solve_greebles) with the seed greeble_seed(style id). |
| Turrets, aiming | nova_ship | crates/nova_ship/src/sections/turret_section/mod.rs, crates/nova_ship/src/sections/turret_section/aim.rs | TurretSectionPlugin | Authored joint tree; lead-intercept aim (update_turret_aim_point, muzzle_on_target); arcs and firing in sibling files. |
| Torpedoes, point defense | nova_ship | crates/nova_ship/src/sections/torpedo_section/mod.rs, crates/nova_ship/src/input/point_defense/mod.rs | TorpedoSectionPlugin, SpaceshipPointDefensePlugin | Bay + guided round lifecycle (TorpedoGuidance, TorpedoBlast); PD splits target assignment from mount authority (borrowed player mounts). |
| The spinal lance: commit, charge, shot, recoil | nova_ship | crates/nova_ship/src/sections/railgun_section/mod.rs, crates/nova_ship/src/sections/railgun_section/firing.rs | RailgunSectionPlugin, RailgunCharge | The hull aims it. charge_and_fire_railgun runs the whole cycle in one fixed-step system; the slug is a Pierce round with layers: u32::MAX, so slug_power alone bounds it. The AI’s crude commit envelope: input/ai/railgun.rs (AIRailgun). |
| The rake: a slug that widens its cut | nova_gameplay, nova_ship | crates/nova_gameplay/src/rounds.rs, crates/nova_ship/src/sections/railgun_section/firing.rs | RoundRake, sweep_raking | Authored rake_radius inserts RoundRake; three passes per step - the tip arms bodies it hits, a sphere trailing it sweeps each armed body’s colliders, contacts charge by depth then axis outward out of the one budget. Measured in examples/systems/system_railgun_lance.rs. |
| Docking: the candidate pair, the joint, the break | nova_ship | crates/nova_ship/src/sections/docking_section/port.rs, crates/nova_ship/src/sections/docking_section/admission.rs, crates/nova_ship/src/sections/docking_section/connection.rs | DockingPorts, DockAdmission, DockingConnection, DockingSystems::Release | DOCK names two hulls; a new dock needs both a port candidate (face gap between RETRACTED faces, opposed axes, relative speed, graded on the STRICTER of the two envelopes and tie-broken on EntityId) and DockAdmission, which a ship target refuses while Hostile, Enemy, answering fire, or fighting (a neutralized target always admits) and a station target refuses while every port is held, or is a living station on the Enemy side or hostile to the ship (station_admission; a derelict or neutralized station and a station the player owns, OwnedStationMarker, admit on any side, and a station’s refusal reaches the HUD as a notice through FlightVerbHints::dock_refusal). One FixedJoint with an explicit anchor and basis holds the pose they met in; nothing writes a velocity. A ship holds one connection; a station is a hub holding one per port (StationDock/StationDocks, DockedStation), and the station with every docked hull is one assembly. One hull drives the assembly: DockingConnection.helm (DockedHelmType: Neutral, Held(player), or Station(station) for a living station, which refuses HELM; a derelict or neutralized hull, ship or station, hands the helm to the player at capture) picks it, DockedShip.drives/DockedStation.drives gates every actuator on the other roots, and DockedAssembly gives the driver the combined mass, centre of mass and inertia. DOCK again from either hull, or the player provoking a docked Neutral past NEUTRAL_RETALIATION_THRESHOLD, are the pilot-facing ways out. |
| The bore sight | nova_hud | crates/nova_hud/src/bore_sight.rs | BoreSightPlugin | The lance’s line of fire in world space, walked through the same pierce_remainder as the round; a ring per section the shot would destroy; gated on WeaponsHot, dimmed on an empty magazine. |
| Flight autopilot verbs (STOP, GOTO, ORBIT, MATCH, the AI DOCK approach), PD attitude controller | nova_ship | crates/nova_ship/src/flight/state.rs, crates/nova_ship/src/flight/autopilot.rs, crates/nova_ship/src/flight/dock_corridor.rs, crates/nova_ship/src/sections/controller_section.rs, crates/nova_ship/src/physics/pd_controller.rs | ShipCapabilities, Autopilot | The ship ROOT carries what it is permitted to do; the flight layer flies the maneuvers (NovaFlightPlugin); PDControllerPlugin is the attitude loop, and a controller section is the attitude hardware it needs. MATCH is AutopilotAction::MatchTarget, flown on RCS alone. |
| Leg detours around rocks and planetoids | nova_ship | crates/nova_ship/src/flight/navigation.rs | plan_leg, DetourPolicy | The sphere-detour planner every GOTO and GotoPos leg asks each tick, and the AI formation leg in its leader’s frame. It holds no policy: the caller states the clearance in a DetourPolicy and gets a corner back. |
| Radar locking, targeting | nova_ship | crates/nova_ship/src/input/targeting/mod.rs, crates/nova_ship/src/input/targeting/state.rs | SpaceshipTargetingPlugin | Radar search writes the two sticky lock slots on the ship root: TravelLock, CombatLock. |
| Gravity wells | nova_gameplay | crates/nova_gameplay/src/gravity.rs | GravityWell | Inverse-square wells with an SOI cutoff; only anchored planets and authored anchors publish one. Ships and asteroids feel their pull. |
Scenario and modding
Depth: Scenario engine.
| Concept | Crate(s) | Key files | Entry symbol | Orientation |
|---|---|---|---|---|
| Scenario engine, mission scripting | nova_scenario, nova_events | crates/nova_scenario/src/lib.rs, crates/nova_events/src/engine.rs | NovaScenarioPlugin | A scenario is handlers = event + filters + actions over NovaEventWorld; the generic queue/dispatch (EventHandler) is nova_events. |
| Scenario events, filters, actions (modding events) | nova_scenario | crates/nova_scenario/src/events.rs, crates/nova_scenario/src/filters.rs, crates/nova_scenario/src/actions/mod.rs | EventConfig, EventFilterConfig, EventActionConfig | One dispatch enum each; actions fan out to the flow/mission/sequence/ship/spawn/timer/view submodules beside mod.rs. |
| Scenario variables, expressions, watches | nova_scenario | crates/nova_scenario/src/variables.rs, crates/nova_scenario/src/world.rs | VariableExpressionNode, NovaEventWorld | Typed literals + expression tree (VariableConditionNode for filters); watches sample typed world queries into variables. |
| Scenario objects (asteroid, planet, spaceship, beacon, crate, light, anchor) | nova_scenario | crates/nova_scenario/src/objects/mod.rs, crates/nova_scenario/src/actions/spawn.rs | ScenarioObjectsPlugin, ScenarioObjectKind | One module per kind under objects/; the spawn action dispatches on the kind enum. |
| Scenario loading, lifetime scoping, teardown | nova_scenario | crates/nova_scenario/src/loader/mod.rs, crates/nova_scenario/src/loader/lifecycle.rs | ScenarioLoaderPlugin | LoadScenario/UnloadScenario observers; everything tagged ScenarioScopedMarker dies at teardown; scenario_is_live gates the ship sets. |
| Mod formats, bundles, portal | nova_mod_format, nova_modding, nova_assets | crates/nova_mod_format/src/lib.rs, crates/nova_modding/src/lib.rs, crates/nova_assets/src/portal/mod.rs | BundleManifest, Content, PortalPlugin | Engine-free serde wire types -> RON asset loaders -> portal fetch/verify/install. The static portal is generated by scripts/gen-portal.py over webmods/. |
| Content generation (base RON, builders, lint) | nova_authoring | crates/nova_authoring/src/cli.rs, crates/nova_authoring/src/generation.rs | cli::main | cargo run content gen serializes the base_content builders into the committed base *.content.ron; content lint validates any content tree. Never hand-edit generated RON. |
Interface
| Concept | Crate(s) | Key files | Entry symbol | Orientation |
|---|---|---|---|---|
The TAB interface and the ; command modal | nova_command, nova_interface | crates/nova_command/src/commands.rs, crates/nova_interface/src/pane.rs, crates/nova_interface/src/lib.rs | InterfacePlugin, InterfaceSystems, CommandsSystems | Pure command language and terminal model in nova_command (COMMAND_CATALOG, CommandTerminal); the Tab interface with its Map, Ship and Inventory panes, and the ; CRT modal, in nova_interface. |
| Keybinds: the action table, rebinding, the capture | nova_input, nova_menu | crates/nova_input/src/registry.rs, crates/nova_input/src/poll.rs, crates/nova_menu/src/settings.rs | InputBindings, InputSources | One table of named actions; each owner registers its own defaults, every rig is BUILT from it, and every rebind surface reads it. Settings’ Controls tab takes the next press through InputSources; overrides persist in settings_store. |
| Flight HUD widgets | nova_hud | crates/nova_hud/src/lib.rs | NovaHudPlugin | One module per instrument (crosshairs, ammo, markers, comms, keybind dock); reads the ship, never drives it. |
| Main menu, menu backdrops | nova_menu | crates/nova_menu/src/lib.rs, crates/nova_menu/src/ambience.rs | NovaMenuPlugin | The backdrop is a role: Backdrop scenario from the menu’s shuffled rotation (MenuBackdropRotation); a backdrop’s BackdropDone makes advance_menu_backdrop cut to the next one. NOVA_MENU_BACKDROP pins the first one for capture. |
| Training handbook: lessons, field notes, progress | nova_training, nova_menu | crates/nova_training/src/catalog.rs, crates/nova_training/src/validate.rs, crates/nova_menu/src/training.rs, crates/nova_menu/src/training_store.rs | TrainingCatalog, TrainingProgress | A lesson is CONTENT (Content::Lesson): register_bundles merges base + mods into TrainingCatalog, and the menu draws whatever it is handed. Practice may only name a role: Lesson scenario and proven_by any launchable one; both are lint_lesson, at lint and then at load. Progress is a SECOND file beside settings.ron (TrainingProgressPlugin): opening a lesson reads it, and only a Victory on a scenario its proven_by names completes it. Field notes are derived from the same lessons (facts.rs) and drawn on three surfaces - the menu’s bottom-left notice corner beside the first-launch offer, the boot screen (compiled boot_field_notes, before any catalog exists) and the scenario load screen, which prefers a note from a lesson that names the scenario. Each corner notice carries its own switch (TrainingPromptSetting, FieldNoteSetting): the card writes it, Settings > Interface brings it back, and neither touches the loading screens. A lesson’s demonstration is real footage at assets/base/training/<id>.webp, recorded by the lesson_* capture producers (scripts/capture-lesson-media.sh) and cut by the grid the LESSON authors; every base lesson has a producer, and one authored without one keeps scripts/gen-lesson-media.py’s placeholder, which never redraws over captured footage. |
| Scenario roles | nova_scenario | crates/nova_scenario/src/loader/mod.rs, crates/nova_scenario/src/lint/scenario.rs | ScenarioRole | Chapter (a level, the picker row), Backdrop (menu scenery, poses its own camera, reports BackdropDone), Lesson (a handbook practice range). A campaign may list only chapters that need no New Game session. |
| Station visits and trade profiles | nova_world_base, nova_gameplay | crates/nova_world_base/src/station_visits.rs, crates/nova_gameplay/src/station_visits.rs, crates/nova_gameplay/src/trade_profile.rs | StationVisits, TradeProfileDesign | drive_station_visits is the one writer of StationVisits: a generated AI ship with a profile binds a nearby living station, docks, runs its trades and posts its jobs once (the receipt), then departs. A profile is content (GameTradeProfiles); the trade plans against both holds and purses and never creates cargo or credits. |
| Scenario world | nova_scenario, nova_world_base | crates/nova_scenario/src/loader/mod.rs, crates/nova_world_base/src/lib.rs | ScenarioWorldType | Void (the default: authored objects only) or Generated((seed, bounds)): the base generator streams around the scenario’s one player ship. seed: None takes the New Game seed (OpenWorldSession), so only New Game and Load start it; a fixed seed is a picker row. |
| Shared UI themes and widgets | nova_ui | crates/nova_ui/src/theme/mod.rs, crates/nova_ui/src/widget/mod.rs | NovaUiPlugin | Moddable UI themes (UiThemeConfig -> ActiveUiTheme) and the widget factories every UI-drawing crate consumes. |
| Ship editor, link points, placement | nova_editor, nova_ship | crates/nova_editor/src/lib.rs, crates/nova_editor/src/snap.rs, crates/nova_ship/src/sections/link_points.rs | NovaEditorPlugin | Editor build scene; snap_placement mates socket frames; the editor solver decides or refuses a drop. |
| Mod project, Mod Hub, package, import, asset bench | nova_editor, nova_assets | crates/nova_editor/src/project.rs, crates/nova_editor/src/asset.rs, crates/nova_editor/src/project/store.rs, crates/nova_editor/src/project/package.rs, crates/nova_editor/src/ui/hub.rs | ModProject | One mod held in memory: KINDS lists its content, one asset is open, package.rs owns the zip and the import checks. |
Tooling
Depth: Automation harness, Measuring performance and Building and running.
| Concept | Crate(s) | Key files | Entry symbol | Orientation |
|---|---|---|---|---|
| Automation harness, autopilot scripts, screenshot capture | nova_autopilot, nova_debug | crates/nova_autopilot/src/autopilot.rs, crates/nova_debug/src/harness.rs | AutopilotPlugin | Env-armed step driver (NOVA_AUTOPILOT, NOVA_CAPTURE); Nova presets and the shoot capture idiom live in the debug harness module. |
| Probe, run reports, what an example claims | nova_probe, nova_probe_cli | crates/nova_probe/src/capabilities/mod.rs, crates/nova_probe/src/contract.rs, crates/nova_probe_cli/src/native.rs | NovaProbePlugin | One bundle wires every capability; probe run/scenario/report (subcommands of the game binary, debug feature) spawn and grade runs. Web capture app: crates/nova_perf_web/src/main.rs. |
| Frame cost, scene census, the capture window | nova_probe | crates/nova_probe/src/capabilities/frametime.rs, framecost.rs, census.rs | nova_frametime, nova_framecost, nova_census | Wall-clock deltas over a fixed window, plus where the milliseconds went and what the scene contained. Knob table: cargo doc -p nova_probe. |
| World-state snapshot (read the world, not a render) | nova_probe | crates/nova_probe/src/capabilities/snapshot.rs | nova_snapshot, probe_snapshot | One JSON object per snapshot: ships, sections, fixtures, weapon state, rounds in flight. Sorted and rounded, so two snapshots of one frozen frame are byte-identical. |
| WFC arena: benching generated hulls | examples, nova_wfc | examples/playable/wfc_arena.rs, examples/playable/wfc_arena/stamps.rs | arena_tiles | Fields collapsed hulls against each other. The collapse itself is nova_wfc (see The ship); the arena names a spinal gun as its plan’s keel.bow_gun and stamps a large-drive stern no single plan can express. Lobby, pause and result flow sit beside it in examples/playable/wfc_arena/. |
| Debug tooling (Nova Debug window, overlays, F12 screenshots) | nova_debug | crates/nova_debug/src/lib.rs, crates/nova_debug/src/hud/mod.rs | DebugPlugin, DebugHudPlugin, DebugOverlays | Compiled only under the debug feature; F11 opens the Nova Debug window (freezes flight in PauseStates::Debug), F12 screenshot, --norender, --debugdump. |
| Web preview, this book at /dev/ | scripts, web | scripts/serve-web.sh, scripts/preview-web.sh, web/webpack.config.js | serve-web.sh | Live-serves site + /play/ + /mods/ + this book at /dev/, all watched; the preview script builds the static deploy shape. |