re: all 144 chatter rule tables named; the undeclared 8 are NOT tutorial
Three more naming routes: strip _msg from a message table (137/144, superset
of route 1, zero non-rule hits), predict the name from the Sperkers roster
(6/6, control 0/4), and sweep the naming grammar (1/144). Union 144/144,
and every rule table has its _msg companion.
Refutes the reading left by 3f20787: the undeclared tables are two story-stage
tables and six TCAF fleet/ship tables, no tutorial content at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
@@ -8,7 +8,7 @@ in the layout cutscene-message-table.md already documents.
|
||||
|
||||
Run: python3 preset_messages.py > ../../docs/re/data/preset-messages.txt
|
||||
"""
|
||||
import sys, os, glob, collections
|
||||
import sys, os, re, glob, collections
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from unit_substructures import pak_entries
|
||||
import unitgroup as U
|
||||
@@ -170,9 +170,15 @@ def main():
|
||||
harvest.add(n)
|
||||
harvest.add(v)
|
||||
byharvest = {}
|
||||
byderived = {}
|
||||
for c in harvest:
|
||||
if c.startswith('PresetMessage_'):
|
||||
byharvest.setdefault(U.name_hash('message\\' + c), 'message\\' + c)
|
||||
if not c.startswith('PresetMessage_'):
|
||||
continue
|
||||
byharvest.setdefault(U.name_hash('message\\' + c), 'message\\' + c)
|
||||
# route 3: a message table's name gives its rule table's name
|
||||
if c.endswith('_msg.tbl'):
|
||||
b = 'message\\' + c[:-len('_msg.tbl')] + '.tbl'
|
||||
byderived.setdefault(U.name_hash(b), b)
|
||||
|
||||
declared = collections.Counter()
|
||||
ums_found = []
|
||||
@@ -190,12 +196,60 @@ def main():
|
||||
for v in declared:
|
||||
bydecl.setdefault(U.name_hash('message\\' + v), 'message\\' + v)
|
||||
|
||||
# route 4: names predicted from the Sperkers roster before they were hashed.
|
||||
# TCAF_Fleet<X><Y> speaks (TCAFOP<Y>, TCAF<X>); TCAF_..Ship<X> speaks
|
||||
# (ADANPL<X>, TCAF<X>). Six gaps in two series, all six confirmed.
|
||||
PREDICTED = ['TCAF_FleetBB', 'TCAF_17thFleetBB', 'TCAF_17thFleetCA',
|
||||
'TCAF_17thFleetCB', 'TCAF_17thFleetShipA', 'TCAF_17thFleetShipB']
|
||||
# same-shaped names that the series does NOT contain, as the control
|
||||
CONTROL = ['TCAF_FleetCC', 'TCAF_17thFleetCC', 'TCAF_ShipA_01',
|
||||
'TCAF_17thFleetShipC_01']
|
||||
bypred = {}
|
||||
for c in PREDICTED:
|
||||
n = 'message\\PresetMessage_%s.tbl' % c
|
||||
bypred.setdefault(U.name_hash(n), n)
|
||||
|
||||
A = {h: n for h, n in byharvest.items() if h in rule}
|
||||
B = {h: n for h, n in bydecl.items() if h in rule}
|
||||
C = {h: n for h, n in byderived.items() if h in rule}
|
||||
D = {h: n for h, n in bypred.items() if h in rule}
|
||||
print()
|
||||
print('naming route 1 (any harvested PresetMessage_ string): %d/%d' % (len(A), len(rule)))
|
||||
print('naming route 2 (UnitMessageSet_S* declarations) : %d/%d' % (len(B), len(rule)))
|
||||
print('the two routes agree on the same set : %s' % (set(A) == set(B)))
|
||||
print('naming route 3 (strip _msg from a message table) : %d/%d' % (len(C), len(rule)))
|
||||
print('naming route 4 (predicted from the Sperkers roster) : %d/%d' % (len(D), len(rule)))
|
||||
print('routes 1 and 2 agree on the same set : %s' % (set(A) == set(B)))
|
||||
print('route 3 is a superset of route 1 : %s' % set(A).issubset(C))
|
||||
print('route 3 names nothing that is not a rule table : %s' % all(
|
||||
h in rule for h in byderived if h in entries))
|
||||
print('CONTROL — same-shaped names outside the series, hits : %d/%d' % (
|
||||
sum(1 for c in CONTROL if U.name_hash('message\\PresetMessage_%s.tbl' % c) in rule),
|
||||
len(CONTROL)))
|
||||
A = dict(A); A.update(C); A.update(D)
|
||||
# route 5: sweep the naming grammar the other 143 names describe,
|
||||
# PresetMessage_<who>[_NN][_S<nn>-<p>].tbl, over every <who> already seen.
|
||||
whos = set()
|
||||
for n in A.values():
|
||||
base = n.rsplit('\\', 1)[-1]
|
||||
m = re.match(r'PresetMessage_(.+?)(?:_\d\d)?(?:_S\d\d-\d)?\.tbl$', base)
|
||||
if m:
|
||||
whos.add(m.group(1))
|
||||
stages = ['_S%02d-%d' % (st, ph) for st in range(1, 30) for ph in range(1, 5)]
|
||||
E = {}
|
||||
for w in sorted(whos):
|
||||
for nn in [''] + ['_%02d' % i for i in range(1, 21)]:
|
||||
for st in [''] + stages:
|
||||
n = 'message\\PresetMessage_%s%s%s.tbl' % (w, nn, st)
|
||||
h = U.name_hash(n)
|
||||
if h in rule and h not in A:
|
||||
E[h] = n
|
||||
print('naming route 5 (sweep of the grammar, %d <who> tokens): %d/%d' % (
|
||||
len(whos), len(E), len(rule)))
|
||||
A.update(E)
|
||||
print('UNION of all five routes : %d/%d' % (len(A), len(rule)))
|
||||
missing_msg = [n for h, n in A.items()
|
||||
if U.name_hash(n[:-4] + '_msg.tbl') not in entries]
|
||||
print('rule tables whose _msg companion is absent : %d' % len(missing_msg))
|
||||
print('UnitMessageSet_S* tables present: %d of %d (%s)' % (
|
||||
len(ums_found), len(STAGES), ' '.join(ums_found)))
|
||||
print('missing: %s' % ' '.join(s for s in STAGES if s not in ums_found))
|
||||
|
||||
Reference in New Issue
Block a user