Aetheria/docs/ship-collection-authoring.md
Meta Vens 23976aada7 Ship mounts: delete EquipmentHardpoints and the plan's Equipment list
The array's only reader was the dead SoundBank block in EntityInstance, which
looked up a hardpoint transform and did nothing with it. ShipModPlan.Equipment,
ShipModShips' assignment, the preview check, the FBX builder's HP.Equipment
case and its smoke assertion all fed that one dead reader. An HP.Equipment node
is now refused by the builder as an unknown hardpoint kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:34:05 +02:00

81 lines
5.9 KiB
Markdown

# Ship collection authoring
Status: FBX-to-Unity-prefab contract for ships using the current catalog path. Longinus and Djinni predate this contract and keep their current prefabs. The parallel mod-owned `.cc` path is specified in [moddable-ship-authoring.md](moddable-ship-authoring.md).
## Objective and ownership
One Blender collection exports one FBX model. Its hierarchy names the ship's presentation anchors. Unity builds
`Assets/Content/Prefabs/Ships/<Name>.prefab` from that model and assigns the components and references that the
runtime currently requires on a hand-built ship prefab. `GameData/Aetheria.cc` remains the owner of `HullData`,
hardpoint cells and types, gameplay stats, products, and the prefab's Addressables key. The model never decides a
hit, thruster force, weapon arc, or shield capacity.
Today `ShipInstance` reads manually filled arrays on each ship prefab. It matches their transform names against
`HullData.Hardpoints[].Transform`. Its shared ping, invisible material, explosion, shield, and tractor references
also live on each prefab. The builder derives the arrays from the FBX hierarchy and supplies the shared Unity
assets once, from their existing project paths. The old prefabs are left alone.
## Blender collection and export
- Name the collection `Ship.<Name>` and configure its collection exporter as FBX. Export to
`Assets/Models/Ships/<Name>.fbx`. The filename is the generated prefab name. Blender's collection exporter can
export a collection directly and repeat that export after edits.
- Export meshes and empties, with animation disabled. Use Blender's `-Z Forward`, `Y Up` axis conversion for Unity.
Keep the collection origin at the ship's simulation centre, with the nose pointing toward the exported +Z axis.
Apply object scales on visual and collision meshes; the `Shield` empty's scale is the deliberate exception.
- The importer owns every prefab under `Assets/Content/Prefabs/Ships/` whose matching model is in
`Assets/Models/Ships/`. Editing generated components by hand is temporary; the next export rebuilds them.
Put appearance in the FBX and gameplay values in the catalog.
The exported hierarchy uses **exact, case-sensitive names**. Names beginning `HP.`, `Pivot.`, or `SHIP.` are
reserved. IDs after a role prefix must be unique across the model. Other visual objects may have any names.
```text
<Name> FBX root
Body visible meshes, any nesting
SHIP.MapIcon one mesh; assigned the shared map material and Minimap layer
SHIP.HullCollider one low-poly closed convex mesh; rendered invisible, given a MeshCollider
SHIP.Shield one empty; its position and scale set the shield envelope
SHIP.TractorBeam one empty; its pose sets the tractor effect origin
HP.Thruster.PortAft empty; exact name copied to HullData.Hardpoints[].Transform
Emitter one mesh; thruster particle emission shape
HP.Weapon.PortGun empty; exact name copied to the catalog
Muzzle.0 empty; +Z is firing direction
Muzzle.1 optional additional barrel
HP.Radiator.Port empty; exact name copied to the catalog
RadiatorMesh one mesh; temperature emission surface
Pivot.0.-90.90.-80.80.60 optional empty parent of articulated mounts
```
`HP.Weapon` covers ballistic, energy, and launcher mounts; the catalog chooses which. Only thrusters, weapons and
radiators are visible and get a node; internal hardpoints have none. Each role gets its matching component and array.
`Muzzle.<nonnegative integer>` children are sorted numerically; their transforms become `FiringPoint`. A weapon
mount requires at least one. A `Pivot` name carries `Group.YawMin.YawMax.PitchMin.PitchMax.Speed` as signed
integers in degrees and degrees per second. It gets `ArticulationPoint`; child mounts follow its transform. Pivots are
presentation only: the simulation's catalog firing arc remains authoritative.
`SHIP.Shield` receives the existing Shield prefab as a child. That prefab's effective unscaled radius is one
Unity unit; the marker's three scale components are the intended envelope radii in world units. The builder adds
`ShieldEnvelope` to the Shield prefab root if absent. `SHIP.TractorBeam` receives the existing Tractor Beam
prefab. The four `SHIP.*` markers are required exactly once. Ship-specific mesh materials remain authored in
Blender/Unity's material import mapping; the builder only assigns the shared map-icon material.
## Build, validation, and failure
Re-exporting an FBX in `Assets/Models/Ships/` schedules a prefab rebuild after Unity finishes importing it.
`Aetheria/Build Ship Prefab From Selected Model` performs the same build on demand. The builder validates all
reserved names, required anchors, component meshes, muzzle numbering, and shared asset references **before**
replacing a prefab. A bad export reports an error and leaves the last valid prefab in place. The output is a
Prefab Variant of the FBX model, so mesh and transform identities remain tied to the source export.
After adding a ship, author its `HullData` and product in the catalog, set `HullData.Prefab` to the generated
prefab's GUID, and set every `HardpointData.Transform` to an exact `HP.*` name. Run the catalog asset check and
the Unity compile. A visual play check still owns size, materials, shield fit, barrel orientation, and thrust
appearance. The builder cannot infer the 2D schematic from a 3D mesh.
## Cut and build budget
This adds an Editor-only builder, its focused smoke, and this contract. It adds no runtime component, persistent field, package,
service, or build target. It replaces per-ship array and shared-reference authoring for newly exported ships.
The focused verification target is Unity Editor script compilation plus a synthetic named-hierarchy check; a
real Blender collection export is required before claiming end-to-end import fidelity.