Create / Modding reference / Base content catalog
Base content catalog
Every id and asset the base game ships, so your mod can reference them
instead of guessing. Six registries matter to a mod author: section
prototype ids (what source: Prototype(id: "<id>") can name), ship ids
(what design: Prototype(id: "<id>") can name - tabled in
Ships), style ids (what a design's style: can
name), scenario ids (what NextScenario and campaigns can target), UI
theme ids (what a theme's inherit: can name), and
base asset paths (what dep://base/<path> can reach). All of it is generated from the Rust builders
by cargo run content gen into
assets/base/**/*.content.ron - the generated RON is the shipped truth, and
content -- lint checks your references against it.
base is the IMPLICIT universal dependency: every mod may reference base
content and dep://base/ assets without listing base in
meta.dependencies. Declaring it explicitly is allowed and also resolves -
the shipped portal mods do - but it is never required.
Section prototypes
Lengths are in METERS and speeds in meters per second: the number in the file is
the number in the world, and there is nothing to convert. World units survive
in one place a creator ever touches - the BUILD GRID a ship is assembled on,
whose cell is 10 m on a side. A section's collider, its link_points and its
position in a ship's sections list are counted in cells, and so is a
thruster's exhaust cone; everything else on this page is metric.
A prototype id is used two ways: a ship's section list references it
compactly (source: Prototype(id: "<id>") resolves the whole config, meshes
and sounds included, with an optional patch over it), and a mod Section item that reuses the id REPLACES that
part everywhere. See Ship sections for mods for
the Section grammar and the overlay flow.
Ids are lowercase snake_case, in the <variant>_<kind>_section form. Every
base prototype is GENERIC - a hull cell, a drive, a mount, a bay - so the same
part serves every hull. Section kinds are Hull, Thruster, Controller,
Turret, Torpedo, and Railgun.
Core sections (the editor palette)
| id | kind | display name | health | notes |
|---|---|---|---|---|
reinforced_hull_section |
Hull | Reinforced Hull Section | 200 | the armor workhorse |
basic_thruster_section |
Thruster | Basic Thruster Section | 70 | magnitude 1.0; authored 1x1 shell bell; one socket on the -Z mounting face; cone plume starts at Z = 0.51 with radius 0.24 and exits +Z |
vector_thruster_section |
Thruster | Vector Thruster Section | 480 | 3x3x2 collider and footprint; magnitude 9; nine -Z mounting sockets; one vectoring bell and plume |
capital_thruster_section |
Thruster | Capital Thruster Section | 1250 | 5x5x3 collider and footprint; magnitude 25; 25 -Z mounting sockets; one capital bell and plume |
basic_controller_section |
Controller | Basic Controller Section | 100 | steering lag 0.5 s, max torque 9760.0; the hull derives its own turn ceiling from that torque, its inertia and its length |
light_hull_section |
Hull | Light Hull Section | 60 | scavenger-grade hull |
cargo_hull_section |
Hull | Cargo Hull Section | 200 | the reinforced cell's stats under caged freight; a visual choice until real hull types arrive |
tank_hull_section |
Hull | Tank Hull Section | 200 | the reinforced cell's stats around a pressure vessel in open frame rails |
pdc_kinetic_turret_section |
Turret | PDC Turret (Kinetic) | 130 | the gatling every craft mounts, on a 0.5 mount box; fits any hull face. Kinetic 4.0/hit at 100 rps, ammo 500, +200 after 3 s idle |
pdc_pierce_turret_section |
Turret | PDC Turret (Pierce) | 130 | the same 500-round, +200 after 3 s idle gatling loading penetrators: Pierce 2.0/hit, dealt to every section it rakes through |
pdc_twin_kinetic_turret_section |
Turret | Twin PDC Turret (Kinetic) | 130 | the same slugs from the two-barrel mount: each tube at half the gatling's cadence, so two offset streams at the same total rate and magazine drain |
pdc_twin_pierce_turret_section |
Turret | Twin PDC Turret (Pierce) | 130 | penetrators from the two-barrel mount - half per-hit damage through every layer, split across two offset streams |
torpedo_section |
Torpedo | Torpedo Bay (Serpent) | 100 | blast 750 dmg over a radius of 300 m, ordnance 10 hp, ammo 6 restoring +1 after 10 s idle; loads the WEAVING Serpent - cruise 320 m/s, ~390 PDC rounds an intercept, killed ~400 m out |
lance_torpedo_section |
Torpedo | Torpedo Bay (Lance) | 100 | the same six-round, +1 after 10 s idle bay and warhead loading the straight-running Lance: no weave, cruise 350 m/s, ~116 PDC rounds an intercept, killed ~1.14 km out |
railgun_lance_section |
Railgun | Railgun Lance | 180 | the spinal lance: no traverse, so the HULL aims it. A 1.5 s charge you can see walk the bore, then Pierce 300 to every layer it rakes until 1800 slug power runs out; a slug at 15,000 m/s for 1.2 s, rake radius 10 m, recoil 45 at the muzzle, one round reloading over 12 s |
docking_port_section |
Docking | Docking Port Section | 90 | the sealed-hatch port: DOCK holds the hull to the ship it has locked, port face to port face, within 10 m of gap, 15 deg of opposed and 5 m/s of closing speed. Its sleeve reaches 5 m out once the dock holds and is art alone. The workship, both frame tenders and the line warship carry one |
cargo_intake_section |
Cargo intake | Cargo Intake Section | 90 | a 3x2x1 hold mouth behind an accordion door on its -Z face: the door opens for a canister within 40 m, and the intake takes one whole, at any speed, once it touches the 1 m deep trigger in front of the 22.2 x 15.3 m opening, if the hold has room. One jettison may queue several canisters; each drops out at 3 m/s. The line warship carries one on its top deck |
mining_beam_section |
Mining | Mining Beam Section | 90 | a 1x1x1 emitter behind sliding doors on its -Z face: while its own input_mapping key is held the doors part, the tip runs out, and once a second the beam cuts a 1.5-cell sphere from the locked rock where it hits within 100 m. The line warship carries one at its bow, bound to V |
Every shipped prototype authors its damage
effects by kind, and the whole catalog follows one
rule: Hull wears ([Cracks]) (the default, so it is omitted), Controller,
Turret, Torpedo, Railgun, Docking, Cargo intake and Mining wear ([Cracks, Sparks]), and Thruster wears
([Cracks, Sparks, Plume]).
No shipped mod authors the field at all, so base is the worked example.
Cladding (not a prototype)
A ship's outer SKIN is DERIVED from the structure it wraps, as a pure function of it: nothing places a plate, no id names one, and none is saved. Build the structure and the skin follows. There is nothing here for a mod to reference.
A ship asks for it with one field - skin: true on the
ship's hull - and gets destructible cladding: each plate
carries its own health and mass, comes off when it is shot out, and leaves the
hull behind it bare. Build the hull out of the unit-cell sections above;
modelled parts a mod brings are shapes of their own sizes and are not on the
lattice the derivation reads.
What the cladding LOOKS like is a style, which IS content and does have an id.
Skin styles
| id | what it is |
|---|---|
industrial |
a working hull: exposed services, corrugation, radiators, safety-yellow paint on its edges |
armoured |
flat plate, a belt down every straight edge, sensor blisters |
civilian |
a private yacht's: pale satin paint, a cobalt livery rail, lit cabin windows |
salvage |
mismatched patches, weld beads, a lashed drum, a whip antenna |
A ship names one with style: Some("<id>") beside skin: true on its
hull. A mod declaring
a Style with the same id replaces that look everywhere; a new id is a new look.
See Ship skin styles.
Open-world ships wear one of these by role, intact or wrecked: civilian
civilian, industrial industrial, scavenger salvage, armored armoured.
Overlay the id to restyle them. The open world does not start if one of these
ids is missing.
Modelled ship parts (not base content)
Base ships NO parts cut for one craft. Every base hull is built out of the generic prototypes above, on the build grid, and clad by the derived skin.
A mod that brings modelled craft brings their part prototypes and their meshes
with it. The Ledger is the worked example: its racer,
cargoa, cargoa_raider, cargob and cargob_lance are assembled from
racer_*, cargoa_* and cargob_* prototypes it declares itself, over GLBs it
carries under its own gltf/parts/. Those ids resolve only where The Ledger is
installed; nothing in base references them.
Turret MOUNTS are not prototypes either, in base or in a mod. A hull names where
a gun goes; the gun is pdc_kinetic_turret_section, seated on the face it stands
on, and a scavenger-grade craft flies the SAME gun with a
patch: (health: Some(60.0)) on the mount.
Scenario ids
What NextScenario((scenario_id: ...)), a Campaign member list, and the
Scenarios picker can target. Only a role: Chapter
scenario is a picker row; a backdrop or a practice range stays off it but is
still launchable by id.
| id | display name | in the picker | what it is |
|---|---|---|---|
open_world |
Open World | no | the New Game start (role: OpenWorld): the line warship at the origin of the world generated from the seed the player picks |
tutorial |
Basic Training | yes | the first-flight course: the Fleet gunnery range, a qualification card read over the radio |
season_one_chapter_one |
A Useful Job | yes | Season 1, chapter one: thread a working lane on RCS, come about on a stranded ship, and dock to take three people off |
menu_waystation |
Waystation Traffic | no | menu backdrop: hauler convoy; done after a 150 s rotation limit |
menu_gauntlet |
Torpedo Gauntlet | no | menu backdrop: a doomed point-defense stand; done when the stand falls |
menu_weave |
Asteroid Weave | no | menu backdrop: waypoint run through a dense rock band; done after a 150 s rotation limit |
menu_duel |
Duel Cycle | no | menu backdrop: a duel ended by a siege torpedo; done when the victor is erased |
drill_momentum |
Momentum Range | no | practice range: two marks and no flight computer |
drill_stop |
STOP Range | no | practice range: one mark, and room to overshoot it |
drill_autopilot |
Autopilot Range | no | practice range: a rock to fly out to, and a mark to come home to |
drill_gunnery |
Gunnery Range | no | practice range: five hulks on the line, and none of them answer |
The four drill_* ranges belong to the handbook: each is reached from the
Practice button of the lessons that name it, and from nowhere
else.
The base bundle ships ONE campaign, in
assets/base/campaigns/base.content.ron:
| id | header | chapters |
|---|---|---|
season_one |
Season 1 | season_one_chapter_one |
A campaign is a list, not a container: every chapter it names is also an
ordinary picker row that can be launched on its own, and what the campaign adds
is the order they are meant to be flown in and the header the Scenarios board
draws them under. A mod may add its own campaigns, or replace season_one by
reusing its id - see Campaigns.
There are no other content kinds - a content file holds Section, Scenario,
Campaign, Ship, Style, Lesson and UiTheme items only; factions are
not content, and neither is impact audio, a comms channel or the table a
generated hull is drawn from - all three are engine-owned. The base ship ids
are tabled in Ships, the style ids
above, the theme ids below.
New Game is base-owned: new_game_scenario: Some("open_world") in
assets/base/base.bundle.ron is honored only from the base bundle; a mod
declaring it is warned and ignored.
UI theme ids
What a UI theme's inherit: can name, and what declaring the
same id RESTYLES. Both are root themes, so either is a complete parent.
| id | display name | what it is |
|---|---|---|
base/phosphor |
Phosphor | the shipped default: the CLI-drawn terminal - flat phosphor-on-black fills, square-ish corners, a block-meter slider and bracketed [TAG] badges |
base/hardware |
Hardware | the moulded casing: case-gradient faces, drop-shadow bevels, amber selection, round corners, a solid slider fill and chip badges |
A player whose selected theme stops resolving - they disabled the mod that
declared it - falls back to base/phosphor, so a mod must never leave that id
unpaintable.
Assets: what dep://base/ can reach
dep://base/<path> resolves against the base bundle's own folder
(assets/base/<path>), gated on <path> being in the base bundle's declared
resources list - an undeclared path is a lint/merge Error, not a silent
404. A #Scene0-style gltf label is stripped before the membership check,
so dep://base/gltf/hull-01.glb#Scene0 is fine.
The editor reads this same list. A row holding an image, a sound or a model
opens a picker of the files the installed bundles declare, writes the dep://
ref for the one you pick (with the #Scene0 label where a mesh needs it), and
marks a dep:// path no bundle ships - so you never type one of these paths
from memory.
The declared list, complete:
Meshes (25 glb)
Named meshes (all use label #Scene0). First the thruster bells:
gltf/shell_bell.glb,gltf/shell_vector.glb,gltf/shell_capital.glb- the three thruster bells
Then the generated section parts the catalog renders
(scripts/gen-section-parts.py, committed under gltf/):
gltf/hull_personnel.glb,gltf/hull_cargo.glb,gltf/hull_tank.glb- the three hull cell looks (reinforced, cargo, tank)gltf/core_wires.glb- the controller coregltf/pdc_gatling_yaw.glb,gltf/pdc_gatling_pitch.glb,gltf/pdc_gatling_barrel.glb- the gatling PDC joint meshesgltf/pdc_twin_yaw.glb,gltf/pdc_twin_pitch.glb,gltf/pdc_twin_barrel.glb- the twin PDC joint meshesgltf/pdc_housing.glb- the stow housing both PDC mounts sink into, with its animatablestow_lid_*nodesgltf/bay_tube.glb- the two-cell torpedo bay, with its animatabledoor_petal_*iris nodesgltf/railgun_lance.glb- the three-cell spinal lance, with its animatablecharge_boltnodegltf/dock_flush.glb- the docking port, with its animatabledock_tubesleevegltf/intake_accordion_3x2x1.glb- the cargo intake, with its animatableintake_slat_*door nodesgltf/cargo_canister_cuboid.glb- the cargo canister an intake drops and a mined rock shedsgltf/mining_beam_compact.glb- the mining beam, with its animatablestow_lid_*doors andbeam_tip
The retired first-pass art stays in the bundle so old refs resolve, but no
base section renders it: gltf/hull-01.glb, gltf/turret-yaw-01.glb,
gltf/turret-pitch-01.glb, gltf/turret-barrel-01.glb,
gltf/torpedo-bay-01.glb.
Base ships no per-craft part meshes. A mod that brings modelled craft carries
them itself, under its own gltf/parts/.
Cladding ships no meshes and never will: a ship's skin is derived from its structure and built at run time - see Cladding.
Greebles (54 glb)
The decoration models the base styles scatter, under
dep://base/gltf/greebles/, named <kit>_<piece>.glb: the four authored
kits - armoured_* (10), civilian_* (12), industrial_* (14),
salvage_* (14) - plus four magenta placeholder_* pieces no base style uses.
All are generated from committed JSON recipes (scripts/gen-greebles.py,
scripts/greeble-recipes/), and a mod can ship its own .glb the same way.
Sounds (31 wav)
All under dep://base/sounds/: ammo_dry.wav, bay_door.wav,
destroy_rock.wav, destroy_ship.wav, dry_fire.wav, explosion.wav,
impact.wav, impact_explosive.wav, impact_pierce.wav, impact_rock.wav,
lock_off.wav, lock_on.wav, pdc_stow_close.wav, pdc_stow_open.wav,
pdc_twin_fire.wav, radar_deny.wav, radar_retarget.wav,
railgun_charge.wav, railgun_fire.wav, railgun_reload.wav, rcs_loop.wav,
safety_on.wav, salvage_pickup.wav, thruster_capital_loop.wav,
thruster_loop.wav, thruster_vector_loop.wav, torpedo_detonate.wav,
torpedo_launch.wav, turret_fire.wav, warn_hull.wav, warn_lock.wav.
(UI chrome sounds - menu clicks, objective chimes - are engine assets, not base bundle resources, and are NOT dep-referenceable.)
Images (7)
textures/cubemap.png- the stock skybox, and the sky the training range is flown undertextures/cubemap_alt.png- the alternate skybox: aSetSkyboxswap target and what the editor sandbox loadstextures/asteroid.png- the asteroid surface texturethumbnails/tutorial.png- the picker platebanner.png- the base mod's bannerportraits/*.png- the faces aNarrativeCueputs on the comms card:player.png, the player's own label, andrange-control.png, the training range's voice, both in the HUD's own green; and season one's crew -jonah.png,leila.png,tomas.png,rina.png,samir.png,nadia.pngandelena.png- drawn from the story's character palettes. Reusable by any mod - a portrait is just an image ref, and a mod that wants a face of its own ships it under its own tree
Skybox .png.meta sidecars ride along with their image automatically and are
never listed or referenced directly, but a sky needs one: it is what makes the
stack a cube. Both cubemaps above carry the same two settings, and
assets/mods/example/textures/nebula.png.meta is the copy a mod of your own
starts from. array_layout: Some(RowCount(rows: 6)) cuts the stacked PNG into
six array layers at load time, before the renderer uploads it.
asset_usage: ("MAIN_WORLD | RENDER_WORLD") keeps the decoded pixels in main
memory after the upload as well, which is why a sky costs its size twice - once
on the card and once in main memory - and why
Scenarios asks you to size the faces for both.
Ship a sky with no sidecar and the stack uploads as one tall 2D texture. A later reinterpret still rescues the binding, but not the upload, and 4096 px faces are 24576 px stacked: over the 16384 texture limit of smaller GPUs, where the upload itself is fatal.
The overlay rule
How a mod item interacts with this catalog (implemented in
crates/nova_assets/src/merge.rs):
- The matching key is the id string per kind -
Sectionmatches onbase.id;Scenario,Campaign,Ship,Style,LessonandUiThemeonid. Names and file paths never participate. - Same id as base (or an earlier bundle) = REPLACE, whole item. It is not a field-level patch: an overlay must restate every field it wants to keep. Sections replace in place, so the editor palette order is preserved.
- New id = ADD alongside the catalog. Prefix your own ids with your mod's
name (
example_*in the shipped example mod) so they cannot collide. - Same id twice within ONE bundle = a conflict: the first item is kept, the duplicate skipped and logged.
- Merge order is catalog order (base first), then downloaded mods, then a topological pass so a dependency merges before its dependents - so a mod overlays base and everything it depends on, and the last independent mod wins.
See the source
The builders behind this page live under
crates/nova_authoring/src/base_content/: sections/ owns the section
prototypes, one module per family (hull, controller, thruster, turret,
torpedo_bay, railgun, docking_port), styles.rs the
skin styles, ships/ owns the block hulls,
scenarios/ groups the training range and the main-menu backdrops, and
lessons.rs owns the handbook screens. The two UI themes are built one level
down, in crates/nova_ui/src/theme/base.rs, beside the format they are
written in. If this page and the generated RON
ever disagree, the RON is the
truth and this page has a bug - the content_ron_parity test pins the RON to
the builders.