Capture current mission, AI, map and administration development

Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
2026-10-13 22:52:53 +02:00
parent a951a96edc
commit 6a667d8deb
8104 changed files with 2124945 additions and 2061 deletions
@@ -0,0 +1,45 @@
17:01:59.889 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=8401.99
17:01:59.893 SCRIPT : ERR HELD MAP PASS: shared map inserted into real prisoner inventory
17:01:59.893 SCRIPT : ERR HELD MAP MODE REQUEST: mode=3 world=8401.99
17:02:00.661 SCRIPT : ERR HELD MAP FRAME: holder=<4516.43,62.5016,5084.53> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6,0,10750>..<1494,0,12796> zoom=0.333333
17:02:06.213 SCRIPT : ERR HELD MAP FRAME: holder=<4516.43,62.5016,5084.53> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6,0,10750>..<1494,0,12796> zoom=0.333333
17:02:10.310 SCRIPT : ERR HELD MAP PASS: shared map stays in hand through native animation
17:02:10.311 SCRIPT : ERR HELD MAP PASS: shared map does not open fullscreen menu
17:02:10.311 SCRIPT : ERR HELD MAP PASS: held surface refreshes across two real capture cycles
17:02:10.311 SCRIPT : ERR HELD MAP PASS: entire captured page stays inside native map bounds
17:02:11.776 SCRIPT : ERR HELD MAP FRAME: holder=<4516.43,62.5016,5084.53> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6,0,10750>..<1494,0,12796> zoom=0.333333
17:02:17.311 SCRIPT : ERR HELD MAP FRAME: holder=<4516.43,62.5016,5084.53> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6,0,10750>..<1494,0,12796> zoom=0.333333
17:02:18.645 SCRIPT : ERR HELD MAP TEXTURE: texture=496x682 mapWidget=496x682.667
17:02:18.645 SCRIPT : ERR HELD MAP PASS: texture and map canvas match the paper aspect, not the game viewport
17:02:22.217 SCRIPT : ERR HELD MAP INPUT STATE: ownerMatch=1 inHand=1 heldMatch=1 life=0 topMenu=NULL dialog=0 chat=0 focused=NULL
17:02:22.217 SCRIPT : ERR HELD MAP INPUT READY: frames=942 context=0
17:02:22.218 SCRIPT : ERR HELD MAP KEY RIGHT READY
17:02:22.454 SCRIPT : ERR HELD MAP INPUT: frames=951 value=1 blocked=0
17:02:22.484 SCRIPT : ERR HELD MAP INPUT: frames=952 value=1 blocked=0
17:02:22.503 SCRIPT : ERR HELD MAP INPUT: frames=953 value=1 blocked=0
17:02:22.518 SCRIPT : ERR HELD MAP INPUT: frames=954 value=1 blocked=0
17:02:23.230 SCRIPT : ERR HELD MAP FRAME: holder=<4516.58,62.4994,5084.53> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<1260,0,10750>..<2748,0,12796> zoom=0.333333
17:02:23.749 SCRIPT : ERR HELD MAP PASS: arrow action turns to the next fixed sheet through controller RPC
17:02:23.750 SCRIPT : ERR HELD MAP PASS: page turn keeps held item and restores raised focus
17:02:23.763 SCRIPT : ERR HELD MAP KEY DOWN READY
17:02:24.774 SCRIPT : ERR HELD MAP PASS: menu blocks page input
17:02:25.298 SCRIPT : ERR HELD MAP KEY DOUBLE READY
17:02:27.364 SCRIPT : ERR HELD MAP PASS: double map action opens the real interactive map
17:02:27.372 SCRIPT : ERR HELD MAP FULLSCREEN CLOSE TRACE
17:02:28.168 SCRIPT : ERR HELD MAP FRAME: holder=<4516.58,62.4995,5084.53> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<1260,0,10750>..<2748,0,12796> zoom=0.333333
17:02:29.922 SCRIPT : ERR HELD MAP PASS: interactive map preserves the selected paper sheet
17:02:29.922 SCRIPT : ERR HELD MAP KEY SINGLE READY
17:02:30.500 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=38491.8
17:02:30.755 SCRIPT : ERR HELD MAP CLEAR TRACE
17:02:31.963 SCRIPT : ERR HELD MAP PASS: single map press puts the paper away
17:02:31.963 SCRIPT : ERR HELD MAP KEY STORED READY
17:02:32.326 SCRIPT : ERR HELD MAP MODE REQUEST: mode=3 world=40295.8
17:02:35.561 SCRIPT : ERR HELD MAP PASS: double map press from storage waits for equip then opens interactive map
17:02:35.562 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=43473.7
17:02:35.585 SCRIPT : ERR HELD MAP FULLSCREEN CLOSE TRACE
17:02:35.775 SCRIPT : ERR HELD MAP CLEAR TRACE
17:02:38.630 SCRIPT : ERR HELD MAP PASS: ordinary map inserted
17:02:38.632 SCRIPT : ERR HELD MAP PASS: background capture active before stock map activation
17:02:42.706 SCRIPT : ERR HELD MAP PASS: ordinary map still opens fullscreen
17:02:42.706 SCRIPT : ERR HELD MAP CLEAR TRACE
17:02:42.709 SCRIPT : ERR HELD MAP COMPLETE
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

@@ -0,0 +1,29 @@
import ctypes as c, re, sys, time, os
from pathlib import Path
# Only the Xwayland display created by this specific hidden test process.
log=Path(sys.argv[1]);assert log.parent.name.startswith('err-held-pages-')
text=log.read_text(errors='replace');match=re.search(r'Starting Xwayland on (:\d+)',text);assert match
name=match[1];assert name!=os.environ.get('DISPLAY')
x=c.CDLL('libX11.so.6');t=c.CDLL('libXtst.so.6');P=c.c_void_p;U=c.c_ulong
x.XOpenDisplay.argtypes=[c.c_char_p];x.XOpenDisplay.restype=P
x.XKeysymToKeycode.argtypes=[P,U];x.XKeysymToKeycode.restype=c.c_uint
x.XFlush.argtypes=[P];x.XCloseDisplay.argtypes=[P]
t.XTestFakeKeyEvent.argtypes=[P,c.c_uint,c.c_int,U];t.XTestFakeKeyEvent.restype=c.c_int
d=x.XOpenDisplay(name.encode());assert d
x.XDefaultRootWindow.argtypes=[P];x.XDefaultRootWindow.restype=U
x.XQueryTree.argtypes=[P,U,c.POINTER(U),c.POINTER(U),c.POINTER(c.POINTER(U)),c.POINTER(c.c_uint)]
x.XFetchName.argtypes=[P,U,c.POINTER(c.c_char_p)]
x.XSetInputFocus.argtypes=[P,U,c.c_int,U];x.XFree.argtypes=[P]
root=x.XDefaultRootWindow(d);r=U();parent=U();children=c.POINTER(U)();n=c.c_uint()
x.XQueryTree(d,root,c.byref(r),c.byref(parent),c.byref(children),c.byref(n))
for i in range(n.value):
title=c.c_char_p();x.XFetchName(d,children[i],c.byref(title));caption=title.value.decode(errors='replace') if title.value else ''
if 'World Editor' in caption or 'WorldEditor' in caption:
x.XSetInputFocus(d,children[i],2,0);x.XFlush(d);print('Private test keyboard target:',caption,flush=True)
if title:x.XFree(title)
x.XFree(children)
key={'Right':0xff53,'Down':0xff54,'m':ord('m')}[sys.argv[2]];code=x.XKeysymToKeycode(d,key);assert code
for i in range(int(sys.argv[3]) if len(sys.argv)>3 else 1):
assert t.XTestFakeKeyEvent(d,code,1,0);x.XFlush(d);time.sleep(.09)
assert t.XTestFakeKeyEvent(d,code,0,0);x.XFlush(d);time.sleep(.14)
x.XCloseDisplay(d)
@@ -0,0 +1,44 @@
{
"result": "passed",
"cleanup": {
"cleanup_confirmed": true,
"idle_verified": true,
"errors": [],
"orphan_cleanup": {
"attempted": true,
"report": {
"scope": "/tmp/erri-headless-compat/pfx",
"candidates": [],
"term_sent": [],
"kill_sent": [],
"cleared": true
}
}
},
"checks": [
"shared map inserted into real prisoner inventory",
"shared map stays in hand through native animation",
"shared map does not open fullscreen menu",
"held surface refreshes across two real capture cycles",
"entire captured page stays inside native map bounds",
"texture and map canvas match the paper aspect, not the game viewport",
"arrow action turns to the next fixed sheet through controller RPC",
"page turn keeps held item and restores raised focus",
"menu blocks page input",
"double map action opens the real interactive map",
"interactive map preserves the selected paper sheet",
"single map press puts the paper away",
"double map press from storage waits for equip then opens interactive map",
"ordinary map inserted",
"background capture active before stock map activation",
"ordinary map still opens fullscreen"
],
"source_profile": "/tmp/err-held-pages-20261011-o",
"terrain": "Everon",
"input": "Actual arrow and M key events on the private headless Xwayland display",
"limitations": [
"Single local Workbench client; remote replication and JIP viewing not independently tested",
"Existing hand lowering/raising; no custom folding mesh",
"Atlas overview and numpad navigation are proposed, not implemented"
]
}
@@ -0,0 +1,42 @@
from pathlib import Path
import os,sys,re,subprocess,json,time,fcntl
root=Path('/home/jakub/devel/escapistsrereintroduced');sys.path.insert(0,str(root/'tools'))
from headless_game import assert_prefix_idle,cleanup_owned_run
compat=Path('/tmp/erri-headless-compat');lock=(compat/'.erri-workbench.lock').open('a');fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB);assert_prefix_idle(compat)
steam=Path.home()/'.local/share/Steam';wb=steam/'steamapps/common/Arma Reforger Tools/Workbench';proton=steam/'steamapps/common/Proton - Experimental/proton'
profile=Path('/tmp')/sys.argv[1];profile.mkdir();addons=profile/'addons';addons.mkdir()
(addons/'ArmaReforger').symlink_to(steam/'steamapps/common/Arma Reforger/addons/data',target_is_directory=True)
installed=steam/'steamapps/compatdata/1874880/pfx/drive_c/users/steamuser/Documents/My Games/ArmaReforger/addons'
projects={}
for p in installed.glob('*/addon.gproj'):
t=p.read_text();g=re.search(r'GUID "([A-Fa-f0-9]+)"',t)
if g:projects[g[1].upper()]=(p,re.findall(r'"([A-Fa-f0-9]{16})"',t.split('Dependencies',1)[-1]) if 'Dependencies' in t else [])
pending=['595F2BF2F44836FB','629B2BA37EFFD577','5E524E4FEECCA92B','65930CB4CD0237B2'];seen=set()
while pending:
g=pending.pop()
if g in seen or g=='58D0FB3206B6F859':continue
seen.add(g);p,deps=projects[g];(addons/('Dependency_'+g)).symlink_to(p.parent,target_is_directory=True);pending.extend(deps)
# Compile with the currently installed dependency manifests, not the obsolete
# historical smoke-test manifest hashes. No addon files are changed.
env=os.environ.copy();env.update(STEAM_COMPAT_DATA_PATH=str(compat),STEAM_COMPAT_CLIENT_INSTALL_PATH=str(steam),WINEPREFIX=str(compat/'pfx'),PULSE_SINK='erri_tests_silent',PULSE_PROP='application.id=org.escapistsrereintroduced.tests')
cmd=['gamescope','--backend','headless','-W','1280','-H','720','-w','1280','-h','720','-r','30','--',str(proton),'run',str(wb/'ArmaReforgerWorkbenchSteamDiag.exe'),'-gproj','Z:'+str(root/'addons/core/addon.gproj'),'-addonsDir','Z:'+str(root/'addons'),'-profile','Z:'+str(profile),'-logconsole','-wbModule=WorldEditor','-load','Worlds/ERR_Everon.ent','-plugin=ERR_ValidateWorldPlugin','-errPlay','1','-errHeldMapProbe','1','-noSound','-noThrow','-disableCrashReporter']
if len(sys.argv)>2 and sys.argv[2]=='signal':cmd.extend(['-errRescueSignalOnly','1'])
result='timeout';text='';start=time.monotonic();injected=set()
with (profile/'launch.log').open('w') as log:
child=subprocess.Popen(cmd,cwd=wb,env=env,stdout=log,stderr=subprocess.STDOUT,start_new_session=True)
try:
while time.monotonic()-start<300:
logs=sorted((profile/'logs').glob('*/console.log'))
if logs:text=logs[-1].read_text(errors='replace')
for marker,key,count in [('RIGHT','Right','1'),('DOWN','Down','1'),('DOUBLE','m','2'),('SINGLE','m','1'),('STORED','m','2')]:
if marker not in injected and 'ERR HELD MAP KEY '+marker+' READY' in text:
subprocess.run([sys.executable,'/tmp/err-private-map-key.py',str(profile/'launch.log'),key,count],check=True)
injected.add(marker)
if 'Can\'t compile' in text:result='compile-failed';break
if 'ERR HELD MAP COMPLETE' in text:result='passed';break
if 'ERR HELD MAP FAIL:' in text:result='probe-failed';break
if child.poll() is not None:result='process-exited';break
time.sleep(.5)
finally:cleanup=cleanup_owned_run(child,proton,env,compat)
(profile/'result.json').write_text(json.dumps({'result':result,'cleanup':cleanup},indent=2))
print(result);print('\n'.join(l for l in text.splitlines() if 'SCRIPT (E)' in l or 'ERR HELD MAP' in l or 'ERRM_Map' in l or 'MatUV' in l))
@@ -0,0 +1,10 @@
{
"addons/core/Configs/ERR/ObserverInput.conf": "78003c4e4ae50785569372d971f969795c36ae020fdc7d91af1e55f2e82d536a",
"addons/core/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et": "fd747932c6f21b923a8ca115062446c4bb9ca1656b2706d79b7c7b559e229a9c",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_SharedMapComponent.c": "0c83ae670742ada3625b13d87dad047071dd3aa20f1356779609d0630b465079",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_SharedMapPages.c": "6a915f4a7d9670a8debb53a04ec3cbd41fbbf293e70bde9e58c4a19cfffbe73b",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_NativeHeldMapProbe.c": "c816b06e5cd5f805cf068c376ad2d5407437c10f2a296d84246bffb5cfc62229",
"tests/test_shared_map_pages.py": "bd262912dfc11be720eba5634abdc8d0dbf61a871066d92d68393fe0ab34386e",
"tests/test_shared_map_viewport.py": "35281694475d87b8cc05b8589fe13f4b00a9ebbdb7b83ddfa69e886439c8bb2c",
"tests/test_shared_map_ownership.py": "bf79b9233eb40c54783d495bf94cc785d7311f4883d23ba9ce78f5d922d369c7"
}