Stores as mass: a loadout system that needed no new physics

Hang four AMRAAMs and a pair of tanks on an F-16 and it should climb slower and top out lower. The trick was to produce a modified performance sheet instead of adding forces.

The requirement sounded simple: stores add weight, and weight changes how the aircraft flies. A clean F-16 and one carrying a strike loadout should feel like different aeroplanes.

The expensive way to do this is to model every store as a rigid body with drag and attach it to the flight model. We didn't need to, because AircraftPerformance was already shaped for it.

Two derived properties do the work

public float MaxThrustAccel  => thrustToWeight * 9.81f;
public float DragCoefficient => MaxThrustAccel / (maxLevelSpeed * maxLevelSpeed);

Thrust is stored as an acceleration, and drag is derived from top speed. A loadout doesn't need new forces. It needs to produce a modified performance sheet.

The loadout equations

Engine thrust is a fixed force, computed once from the datasheet:

thrustNewtons = thrustToWeight_ref × massKg_ref × 9.81

For a given loadout:

massTotal          = massKg_ref + Σ store.massKg
thrustToWeight_new = thrustToWeight_ref × (massKg_ref / massTotal)

dragDelta          = Σ store.dragIndex / 200
maxLevelSpeed_new  = maxLevelSpeed_ref / sqrt(1 + dragDelta)

Set those two fields, and substituting into DragCoefficient gives:

Cd_new = Cd_ref × (1 + dragDelta) × (massKg_ref / massTotal)

That is physically right. More drag area raises drag deceleration, and more mass lowers it for the same force. Top speed depends only on drag, not on weight, which is also right. Every downstream term, including thrust with altitude, induced drag and the over-ceiling penalty, follows from those two fields and stays consistent without extra work.

Data, not code

Every store is a JSON sheet with a real mass, a drag index, a rail standard and a faction. For example, the AIM-120C-5 weighs 161.5 kg with an 18 kg warhead and fits a NATO LAU-127 rail. Every hardpoint on every airframe lists the categories it allows and a mass limit. The loadout screen is a compatibility check between those two sets of data.

That same data drives this website. The arsenal pages are generated from the game's own weapon and aircraft files at build time, so the site can't advertise a store the game doesn't carry.

Asymmetry

The same data answers one more question for free: which way does the load pull? The loadout screen sums store.mass × station.xOffset across the wings. When the lateral moment passes 100 kg·m, it warns that you should expect a rolling moment. It doesn't forbid the load. Firing one of two wing missiles is a real situation, and the screen tells you about it instead of hiding it.