Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

ConceptCrate(s)Key filesEntry symbolOrientation
App boot, app assembly, plugin ordernova_corecrates/nova_core/src/lib.rsAppBuilderbuild() wires the whole plugin stack; game binary + CLI flags in src/main.rs.
Game states, pausenova_gameplay, nova_menucrates/nova_gameplay/src/lib.rs, crates/nova_menu/src/pause.rsGameStates, PauseStatesState enums + GameMode live in gameplay; ESC overlay, toggle_pause and the clock freeze in menu.
Frame flow: Update vs FixedUpdatenova_ship, nova_gameplaycrates/nova_ship/src/lib.rs, crates/nova_gameplay/src/plugin.rsSpaceshipSystemsNovaShipPlugin 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 seamnova_events, nova_uicrates/nova_events/src/units.rs, crates/nova_events/src/scale.rs, crates/nova_ui/src/units.rsMeters, METERS_PER_UNITEverything 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 mergenova_assetscrates/nova_assets/src/plugin.rs, crates/nova_assets/src/merge.rsGameAssetsPluginGameAssetsStates gates entry to the menu/game; register_bundles merges base + enabled mods into the Game* resources.

The ship

Depth: Ship sections internals.

ConceptCrate(s)Key filesEntry symbolOrientation
Ship building from sectionsnova_scenario, nova_shipcrates/nova_scenario/src/objects/spaceship.rs, crates/nova_ship/src/sections/base_section.rsinsert_spaceship_sectionsObserver on the ship root spawns one child per SectionKind config, resolving prototypes; SpaceshipConfig is the authored shape.
Section integrity: damage, disable, destroynova_gameplaycrates/nova_gameplay/src/integrity/mod.rs, crates/nova_gameplay/src/damage.rsNovaIntegrityPluginHealth 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 looksnova_gameplaycrates/nova_gameplay/src/integrity/erosion.rsDamageLevelOne 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_gameplaycrates/nova_gameplay/src/integrity/carve.rsDamageMarks, mark_radiusSpheres 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 looksnova_shipcrates/nova_ship/src/sections/damage_effects.rs, damage_cracks.rs, damage_sparks.rs, damage_plume.rsDamageEffects, fit_damage_effectsCracks/Sparks/Plume, one component each, default [Cracks]. No ship section ever loses geometry.
Carve debris: dust and severed piecesnova_gameplaycrates/nova_gameplay/src/integrity/spew.rs, crates/nova_gameplay/src/integrity/chunk.rsCarveSpew, ShardLook, spawn_carved_chunkShards 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 collapsenova_shipcrates/nova_ship/src/sections/integrity.rsShipIntegrityPluginBuilds the section graph, splits disconnected structure (sever_disconnected_structures -> ShipWreckFragmentMarker), runs cascade_structural_collapse.
Neutralization (combat-dead)nova_gameplaycrates/nova_gameplay/src/integrity/neutralize.rsNeutralizedMarkerAn 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_shipcrates/nova_ship/src/flight/neutralized_brake.rsNeutralizedBrakeType, neutralized_brake_systemA 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 plannova_wfccrates/nova_wfc/src/lib.rs, crates/nova_wfc/src/collapse.rs, crates/nova_wfc/src/tiles.rs, crates/nova_wfc/src/plan.rsTileSet, WfcPlanTileSet::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, greeblesnova_shipcrates/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.rsShipSkinPluginCladding 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, aimingnova_shipcrates/nova_ship/src/sections/turret_section/mod.rs, crates/nova_ship/src/sections/turret_section/aim.rsTurretSectionPluginAuthored joint tree; lead-intercept aim (update_turret_aim_point, muzzle_on_target); arcs and firing in sibling files.
Torpedoes, point defensenova_shipcrates/nova_ship/src/sections/torpedo_section/mod.rs, crates/nova_ship/src/input/point_defense/mod.rsTorpedoSectionPlugin, SpaceshipPointDefensePluginBay + guided round lifecycle (TorpedoGuidance, TorpedoBlast); PD splits target assignment from mount authority (borrowed player mounts).
The spinal lance: commit, charge, shot, recoilnova_shipcrates/nova_ship/src/sections/railgun_section/mod.rs, crates/nova_ship/src/sections/railgun_section/firing.rsRailgunSectionPlugin, RailgunChargeThe 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 cutnova_gameplay, nova_shipcrates/nova_gameplay/src/rounds.rs, crates/nova_ship/src/sections/railgun_section/firing.rsRoundRake, sweep_rakingAuthored 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 breaknova_shipcrates/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.rsDockingPorts, DockAdmission, DockingConnection, DockingSystems::ReleaseDOCK 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 sightnova_hudcrates/nova_hud/src/bore_sight.rsBoreSightPluginThe 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 controllernova_shipcrates/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.rsShipCapabilities, AutopilotThe 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 planetoidsnova_shipcrates/nova_ship/src/flight/navigation.rsplan_leg, DetourPolicyThe 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, targetingnova_shipcrates/nova_ship/src/input/targeting/mod.rs, crates/nova_ship/src/input/targeting/state.rsSpaceshipTargetingPluginRadar search writes the two sticky lock slots on the ship root: TravelLock, CombatLock.
Gravity wellsnova_gameplaycrates/nova_gameplay/src/gravity.rsGravityWellInverse-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.

ConceptCrate(s)Key filesEntry symbolOrientation
Scenario engine, mission scriptingnova_scenario, nova_eventscrates/nova_scenario/src/lib.rs, crates/nova_events/src/engine.rsNovaScenarioPluginA scenario is handlers = event + filters + actions over NovaEventWorld; the generic queue/dispatch (EventHandler) is nova_events.
Scenario events, filters, actions (modding events)nova_scenariocrates/nova_scenario/src/events.rs, crates/nova_scenario/src/filters.rs, crates/nova_scenario/src/actions/mod.rsEventConfig, EventFilterConfig, EventActionConfigOne dispatch enum each; actions fan out to the flow/mission/sequence/ship/spawn/timer/view submodules beside mod.rs.
Scenario variables, expressions, watchesnova_scenariocrates/nova_scenario/src/variables.rs, crates/nova_scenario/src/world.rsVariableExpressionNode, NovaEventWorldTyped literals + expression tree (VariableConditionNode for filters); watches sample typed world queries into variables.
Scenario objects (asteroid, planet, spaceship, beacon, crate, light, anchor)nova_scenariocrates/nova_scenario/src/objects/mod.rs, crates/nova_scenario/src/actions/spawn.rsScenarioObjectsPlugin, ScenarioObjectKindOne module per kind under objects/; the spawn action dispatches on the kind enum.
Scenario loading, lifetime scoping, teardownnova_scenariocrates/nova_scenario/src/loader/mod.rs, crates/nova_scenario/src/loader/lifecycle.rsScenarioLoaderPluginLoadScenario/UnloadScenario observers; everything tagged ScenarioScopedMarker dies at teardown; scenario_is_live gates the ship sets.
Mod formats, bundles, portalnova_mod_format, nova_modding, nova_assetscrates/nova_mod_format/src/lib.rs, crates/nova_modding/src/lib.rs, crates/nova_assets/src/portal/mod.rsBundleManifest, Content, PortalPluginEngine-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_authoringcrates/nova_authoring/src/cli.rs, crates/nova_authoring/src/generation.rscli::maincargo 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

ConceptCrate(s)Key filesEntry symbolOrientation
The TAB interface and the ; command modalnova_command, nova_interfacecrates/nova_command/src/commands.rs, crates/nova_interface/src/pane.rs, crates/nova_interface/src/lib.rsInterfacePlugin, InterfaceSystems, CommandsSystemsPure 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 capturenova_input, nova_menucrates/nova_input/src/registry.rs, crates/nova_input/src/poll.rs, crates/nova_menu/src/settings.rsInputBindings, InputSourcesOne 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 widgetsnova_hudcrates/nova_hud/src/lib.rsNovaHudPluginOne module per instrument (crosshairs, ammo, markers, comms, keybind dock); reads the ship, never drives it.
Main menu, menu backdropsnova_menucrates/nova_menu/src/lib.rs, crates/nova_menu/src/ambience.rsNovaMenuPluginThe 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, progressnova_training, nova_menucrates/nova_training/src/catalog.rs, crates/nova_training/src/validate.rs, crates/nova_menu/src/training.rs, crates/nova_menu/src/training_store.rsTrainingCatalog, TrainingProgressA 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 rolesnova_scenariocrates/nova_scenario/src/loader/mod.rs, crates/nova_scenario/src/lint/scenario.rsScenarioRoleChapter (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 profilesnova_world_base, nova_gameplaycrates/nova_world_base/src/station_visits.rs, crates/nova_gameplay/src/station_visits.rs, crates/nova_gameplay/src/trade_profile.rsStationVisits, TradeProfileDesigndrive_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 worldnova_scenario, nova_world_basecrates/nova_scenario/src/loader/mod.rs, crates/nova_world_base/src/lib.rsScenarioWorldTypeVoid (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 widgetsnova_uicrates/nova_ui/src/theme/mod.rs, crates/nova_ui/src/widget/mod.rsNovaUiPluginModdable UI themes (UiThemeConfig -> ActiveUiTheme) and the widget factories every UI-drawing crate consumes.
Ship editor, link points, placementnova_editor, nova_shipcrates/nova_editor/src/lib.rs, crates/nova_editor/src/snap.rs, crates/nova_ship/src/sections/link_points.rsNovaEditorPluginEditor build scene; snap_placement mates socket frames; the editor solver decides or refuses a drop.
Mod project, Mod Hub, package, import, asset benchnova_editor, nova_assetscrates/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.rsModProjectOne 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.

ConceptCrate(s)Key filesEntry symbolOrientation
Automation harness, autopilot scripts, screenshot capturenova_autopilot, nova_debugcrates/nova_autopilot/src/autopilot.rs, crates/nova_debug/src/harness.rsAutopilotPluginEnv-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 claimsnova_probe, nova_probe_clicrates/nova_probe/src/capabilities/mod.rs, crates/nova_probe/src/contract.rs, crates/nova_probe_cli/src/native.rsNovaProbePluginOne 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 windownova_probecrates/nova_probe/src/capabilities/frametime.rs, framecost.rs, census.rsnova_frametime, nova_framecost, nova_censusWall-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_probecrates/nova_probe/src/capabilities/snapshot.rsnova_snapshot, probe_snapshotOne 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 hullsexamples, nova_wfcexamples/playable/wfc_arena.rs, examples/playable/wfc_arena/stamps.rsarena_tilesFields 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_debugcrates/nova_debug/src/lib.rs, crates/nova_debug/src/hud/mod.rsDebugPlugin, DebugHudPlugin, DebugOverlaysCompiled 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, webscripts/serve-web.sh, scripts/preview-web.sh, web/webpack.config.jsserve-web.shLive-serves site + /play/ + /mods/ + this book at /dev/, all watched; the preview script builds the static deploy shape.