Field reference › Limits and capacities
Limits and capacities
The structural limits that are not about one field: how the 16 annexes carve up the id space, how many mounts, sensors, loadouts and multi-mount weapons a record can hold at once, which quantities a mount's own weapon load can and cannot state, what the magazine pool requires of a platform's magazine block, what a fixed byte width actually means for a name, and the one field family whose meaning changes above a threshold rather than simply overflowing. Every number below is read from the codecs at build time.
The id windows
Every id is 16 bits. The top four bits (bits 15..12) name the
annex a record belongs to, so each annex owns a window of 4,096
consecutive ids: flag*4096 .. +4095. 65535
(0xFFFF) is reserved and never a real record — every reference field
treats it as "none". An id that falls outside its own annex's
window still packs onto disk fine; the game resolves it against
whatever annex the top four bits name, which is very unlikely to be
the one that record actually lives in (Check's
Ids that
collide family flags exactly this).
| Annex | Kind | Id window |
|---|---|---|
A1 |
Ships and land units | 0–4,095 |
A2 |
Submarines | 4,096–8,191 |
B1 |
Aircraft | 8,192–12,287 |
C1 |
Guns | 12,288–16,383 |
D1 |
Missiles | 16,384–20,479 |
E1 |
ASW weapons | 20,480–24,575 |
F1 |
Torpedoes | 24,576–28,671 |
G1 |
Ordnance | 28,672–32,767 |
G2 |
ECM | 32,768–36,863 |
I1 |
Nuclear warheads | 36,864–40,959 |
J1 |
Radars | 40,960–45,055 |
M1 |
Sonars | 45,056–49,151 |
P1 |
Bases | 49,152–53,247 |
Y1 |
Loadouts | 53,248–57,343 |
Z1 |
Mounts | 57,344–61,439 |
Z2 |
Multi-mounts | 61,440–65,535 |
Array capacities
A handful of fields are not one value but a fixed-size array baked into the record's own byte layout — a platform's weapon mounts and sensors, a plane's list of loadouts it can fly with, a loadout's own list of weapons, a multi-mount's parallel weapon-and-quantity slots. The array's length is part of the struct, not a setting: every record of that annex has exactly that many slots, whether or not they are all filled. An unused slot holds 65535 ("none"); a full array means every slot already names something real. There is no way to add one more — the byte layout has no room for it — so freeing a slot by clearing an existing one is the only way to make room for another.
| Annex | Field | Capacity | Holds |
|---|---|---|---|
| A1 | MntId |
32 | weapon mounts a ship can carry |
| A1 | SensId |
16 | sensors a ship can carry |
| A2 | MntId |
16 | weapon mounts a sub can carry |
| A2 | SensId |
8 | sensors a sub can carry |
| B1 | SensId |
8 | sensors a plane or helo can carry |
| B1 | LoadId |
32 | loadouts a plane or helo can offer |
| P1 | MntId |
16 | weapon mounts a base can carry |
| P1 | SensId |
8 | sensors a base can carry |
| Y1 | WepId |
8 | distinct weapons in one loadout |
| Z2 | WepId |
8 | weapons a multi-mount can hold |
The two weapon-list fields (Y1 loadouts, Z2 multi-mounts) are edited as a growable-looking grid with an "+ Add" button, but the capacity is enforced the moment a save is attempted: asking to store more than the array holds is refused outright rather than silently truncated.
Mount weapon loads
A Z1 mount's WepId is one slot, and
a mount's load is one weapon or several, so which shape a load takes is
arithmetic rather than a setting. One weapon states its rounds as two
factors carried on the mount itself, NumMounts ×
NumRoundsMnt, both a u8 — so the quantities a
mount can state this way are the multiples its own launcher count can
reach, up to 255 launchers of 255
rounds each (65,025 rounds at the ceiling). Two or
more weapons have no such shape at all: a Z2
multi-mount is the only place a mixed load can go, and each of its
slots is a u8 too — at most 255 rounds of any
one weapon in it (see array
capacities above for how many slots one multi-mount has).
The mount editor — on a stored mount's own screen and on the create form alike — enforces this rather than leaving the arithmetic to whoever is typing:
- A mount with no launchers states nothing at all no matter what
NumRoundsMntsays, so setting a positive quantity on one is refused outright: the launcher count has to be set first. - A single weapon's quantity that is not a whole number of rounds per launcher cannot go on the mount itself. The save refuses once, naming the nearest quantities the mount could state; tick Allow an uneven single weapon to be stored as a multi-mount above the load grid to store it in a multi-mount instead if that is what was meant.
- A load of two or more weapons is never refused on this account — it has no inline shape to fall back from, so it is accepted straight away.
- Re-saving a load nobody changed always succeeds, whatever the launcher count, so a shipped mount that already carries zero launchers and zero rounds keeps round-tripping instead of starting to refuse itself.
See the Tools guide for moving an existing mixed load back onto its mount once the arithmetic allows it, and Check's own drift family for the multi-mount shapes a save from the mount editor itself would never leave behind.
Ratings: RCS and source level
Two fields rate a platform for the game's detection model rather than
describing it: RCS, how big a return it gives a radar, and
BaseSourceLevel, how loud it is to a sonar. Both are one
byte, so the file could hold more than the game's own scales use. The
highest each annex uses comes from the RCS and source-level tables the
database was built with, where detect range reaches the sensor's own
range; the record editor offers exactly these as its ladders.
| Records | Highest RCS |
|---|---|
| A1 ships and carriers | 237 |
| A1 mobile land units (Type 'm', 'o', 'r') | 200 |
| A2 submarines | 237 |
| P1 bases | 200 |
| B1 aircraft, D1 missiles, E1 standoff ASW | 164 |
Source level (A1 ships, A2 subs and F1 torpedoes) runs from 0 to 127; 92 is a ship's or sub's active sonar at full power. The game holds it in a signed byte, so 127 is the most it can hold, and a negative stored value is the same byte read the other way.
What Check does with a value outside these:
- An RCS above its annex's highest, or a source level above 92, is an advisory Rating out of range finding: legal bytes, probably not what was meant.
- A source level the game cannot hold (above 127, or negative) is blocking for battleset 22 and higher.
- Below battleset 22 the game assigns RCS and source level itself, so the stored values are not used: rating findings are not reported there, and a source level the game cannot hold is only a warning.
Magazine contiguity
Ships and bases are the only annexes with magazines, and they do not
carry their weapon stocks inline — each one points into one shared
pool (RES1_MAG_RECS) with a MagStart byte
offset and a MagCount. A platform's magazine rows must be
consecutive ascending records in that pool —
db_make load and the game both depend on it, and neither
one is forgiving about a block that partly overlaps another or runs
past the pool's own length. Several platforms may point at the same
whole block (the same MagStart and
MagCount), and each then carries the full stock; Clone
does that, and Share identical magazines on the magazine
pool's page points every platform at one block per distinct stock and
removes the rows that frees. The editor's own magazine editor keeps
all this by construction: an edit splices the platform's own slice and
renumbers every block after it, gives a platform on a shared block its
own copy, and reuses an identical block when there is one — never a
free-form write of MagStart/MagCount. See
Check's Magazine
blocks out of order and
Magazine pool nearly
full families for what a broken pool looks like.
The pool has its own ceiling, independent of any one platform:
MagStart is a 16-bit byte offset, so no block can
begin past byte 65,535 — 13,107 magazine records
at 5 bytes each. Past that, the writer
refuses to place another block; the export of everything that already
fits is unaffected.
Record sizes and fixed width
Every annex record is a fixed number of bytes end to end — the table
on the field reference gives each one — and a
bytes-kind field (a name, a class name) is exactly that
many bytes, never fewer and never more. Shorter is not padded and
longer is not truncated: the writer refuses a value that does not fit
the declared width exactly, the same way it refuses a number too big
for its integer kind (Check's
Will not fit in its
field family). The name fields, all sized CLASS_NAME_LEN
48 in the C headers:
| Annex | Field | Width |
|---|---|---|
| A1 | ClassName |
48 bytes |
| A2 | ClassName |
48 bytes |
| B1 | ClassName |
48 bytes |
| C1 | ClassName |
48 bytes |
| D1 | ClassName |
48 bytes |
| E1 | ClassName |
48 bytes |
| F1 | ClassName |
48 bytes |
| G1 | ClassName |
48 bytes |
| G2 | ClassName |
48 bytes |
| J1 | ClassName |
48 bytes |
| M1 | ClassName |
48 bytes |
| P1 | Name |
48 bytes |
| Z1 | ClassName |
48 bytes |
The damage-point overload
A weapon's Dp/SubDp/SurfDp
field is not always a damage value. Above
30,000, the same field carries an id
reference into I1 (nuclear warheads) or F1 (torpedo payload) instead —
a limit on what the number is allowed to mean, not on how big
it can be. Only the annexes whose field is wide enough to ever cross
that threshold can carry the overload; C1's Dp is a
u8 (max 255) and can never reach it, so a C1 gun's Dp is
always a plain damage figure.
| Annex | Field | Storage | Overload |
|---|---|---|---|
| C1 | Dp |
u8 (max 255) | too narrow to reach it — always a plain damage value |
| D1 | Dp |
u16 (max 65,535) | can reach the overload |
| E1 | Dp |
u16 (max 65,535) | can reach the overload |
| F1 | SubDp |
u16 (max 65,535) | can reach the overload |
| F1 | SurfDp |
u16 (max 65,535) | can reach the overload |
| G1 | Dp |
u16 (max 65,535) | can reach the overload |
Check's Points at the wrong annex family covers a Dp/SubDp/SurfDp value above the threshold the same way it covers any other cross-annex reference.