re: the stage numbering is consistent everywhere; the manifest still declares the cut S17
Correction first: the previous commit claimed the corpus 'did not know the stage NUMBERS'. It did -- structures/mission-script-ssb.md has recorded S01-S16, S18-S29, S17 absent by a three-way convergence (hash lookup, the table sweep, the loader's != 16 guard) since before that pass. What was actually new there is the player craft per stage and ResourceID's ordinal tags; the numbering is a fourth independent route, not a discovery. The question this item asked: do the ISL StageNN.ssb files and the UnitGroup_SNN.tbl tables use the same numbering, or is something silently mis-labelled? They are identical. Stage\StageNN.ssb, stage\UnitGroup_SNN.tbl and stage\Route_SNN.tbl all resolve for the same 28 N with an EMPTY symmetric difference; AIParams is the same minus 18-23. Nothing in the corpus is mis-keyed. Formation_SNN and Message_SNN resolve 0/40 -- those are field names, not files, and the four families above are the controls that make that negative real. New: Stage\script.tbl's SCRIPTS record lists 29 MISSION*.ssb fields -- MISSION1..MISSION29, including MISSION17 = Stage17.ssb -- and only 28 of 29 name a file that ships. Control: MISSIONn -> Stage<n>.ssb with the same n, 0/29 mismatched. So S17 is a cut mission the shipping manifest still names, which is why the loader carries an explicit != 16 guard rather than just running 0..27. Artefact +14 lines / 0 deletions; the other four regenerate byte-identical.
This commit is contained in:
@@ -31,6 +31,37 @@ def main():
|
||||
print(" stage\\AIParams_SNN.tbl N = %s (count %d)" % (ai, len(ai)))
|
||||
print(" stages with NO AIParams (the tutorials): %s" % [i for i in ug if i not in ai])
|
||||
|
||||
print("\n## CONTROL every per-stage file family uses the SAME numbering")
|
||||
fam = [('Stage\\StageNN.ssb', 'Stage\\Stage%02d.ssb'),
|
||||
('stage\\UnitGroup_SNN.tbl', 'stage\\UnitGroup_S%02d.tbl'),
|
||||
('stage\\Route_SNN.tbl', 'stage\\Route_S%02d.tbl'),
|
||||
('stage\\AIParams_SNN.tbl', 'stage\\AIParams_S%02d.tbl'),
|
||||
('stage\\Formation_SNN.tbl', 'stage\\Formation_S%02d.tbl'),
|
||||
('stage\\Message_SNN.tbl', 'stage\\Message_S%02d.tbl')]
|
||||
sets = {}
|
||||
for label, tpl in fam:
|
||||
sets[label] = {i for i in range(0, 40) if U.name_hash(tpl % i) in H}
|
||||
print(" %-26s %2d %s" % (label, len(sets[label]), sorted(sets[label])))
|
||||
a, b = sets['Stage\\StageNN.ssb'], sets['stage\\UnitGroup_SNN.tbl']
|
||||
c = sets['stage\\Route_SNN.tbl']
|
||||
print(" ssb == UnitGroup == Route : %s symmetric differences %s %s"
|
||||
% (a == b == c, sorted(a ^ b), sorted(a ^ c)))
|
||||
|
||||
import re as _re
|
||||
sh = U.name_hash('Stage\\script.tbl')
|
||||
sc = [r for r in U.parse(dict(pak_entries(mg))[sh]) if r['squadron'] == 'SCRIPTS'][0]
|
||||
n = U.named(sc)
|
||||
miss = {k: v for k, v in n.items() if k.startswith('MISSION') and v.endswith('.ssb')}
|
||||
nums = sorted(int(_re.match(r'MISSION(\d+)', k).group(1)) for k in miss)
|
||||
bad = [(k, v) for k, v in sorted(miss.items())
|
||||
if v != 'Stage%02d.ssb' % int(_re.match(r'MISSION(\d+)', k).group(1))]
|
||||
ship = [k for k, v in miss.items() if U.name_hash('Stage\\' + v) in H]
|
||||
print("\n## the manifest DECLARES a stage the disc does not ship")
|
||||
print(" Stage\\script.tbl SCRIPTS: %d MISSION*.ssb fields, numbers %s" % (len(miss), nums))
|
||||
print(" CONTROL MISSIONn -> Stage<n>.ssb with the same n: %d/%d mismatched" % (len(bad), len(miss)))
|
||||
print(" entries whose .ssb actually ships: %d/%d ; missing: %s"
|
||||
% (len(ship), len(miss), sorted(set(miss) - set(ship))))
|
||||
|
||||
recs = U.parse(E[U.name_hash('eng\\GP_HANGAR_ARSENAL_3D.tbl')])
|
||||
rid = [r for r in recs if r['squadron'] == 'ResourceID'][0]
|
||||
print("\n## ResourceID -- the player craft, keyed by stage")
|
||||
|
||||
Reference in New Issue
Block a user