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.
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_decor.rsShipSkinPluginCladding derived from structure; styles resolve by id (ShipStyleConfig, GameStyles). A style authors a two-surface StylePalette and, per fixture, a three-word FixturePlacement (region, density, orientation) that skin_style expands privately into the engine’s own ScatterRule; deterministic greeble scatter (scatter_decor).
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 SHIPS; 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 the target refuses while Hostile, Enemy, answering fire, or fighting (a neutralized target always admits). One FixedJoint with an explicit anchor and basis holds the pose they met in; nothing writes a velocity. One hull drives the pair: DockingConnection.helm (DockedHelmType) picks it, DockedShip.drives gates every actuator on the other root, and DockedAssembly gives the driver the combined mass, centre of mass and inertia. DOCK again from either hull, or the player hitting a docked Neutral, 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), PD attitude controllernova_shipcrates/nova_ship/src/flight/state.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.
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 only picker row), Backdrop (menu scenery, poses its own camera, reports BackdropDone), Lesson (a handbook practice range), OpenWorld (the open world’s bootstrap, the base bundle’s New Game start). A campaign may list only chapters.
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.rsNovaEditorPluginSandbox build scene; snap_placement mates socket frames; the editor solver decides or refuses a drop.

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 (inspector, overlays, F12 screenshots)nova_debugcrates/nova_debug/src/lib.rsDebugPluginCompiled only under the debug feature; F11 overlay toggle, 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.