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,80 @@
17:50:57.881 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=8287.8
17:50:57.884 SCRIPT : ERR HELD MAP PASS: shared map inserted into real prisoner inventory
17:50:57.884 SCRIPT : ERR HELD MAP MODE REQUEST: mode=3 world=8287.8
17:50:58.683 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<27.4678,0,164.808>..<12635.2,0,12772.5> zoom=0.0242708
17:51:04.247 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<27.4678,0,164.808>..<12635.2,0,12772.5> zoom=0.0242708
17:51:08.253 SCRIPT : ERR HELD MAP PASS: shared map stays in hand through native animation
17:51:08.253 SCRIPT : ERR HELD MAP PASS: shared map does not open fullscreen menu
17:51:08.253 SCRIPT : ERR HELD MAP PASS: held surface refreshes across two real capture cycles
17:51:08.253 SCRIPT : ERR HELD MAP PASS: entire captured page stays inside native map bounds
17:51:09.816 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<27.4678,0,164.808>..<12635.2,0,12772.5> zoom=0.0242708
17:51:15.386 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<27.4678,0,164.808>..<12635.2,0,12772.5> zoom=0.0242708
17:51:16.441 SCRIPT : ERR HELD MAP TEXTURE: texture=496x682 mapWidget=306.667x306.667
17:51:16.441 SCRIPT : ERR HELD MAP PASS: texture and map canvas match the paper aspect, not the game viewport
17:51:19.634 SCRIPT : ERR HELD MAP INPUT STATE: ownerMatch=1 inHand=1 heldMatch=1 life=0 topMenu=NULL dialog=0 chat=0 focused=NULL
17:51:19.634 SCRIPT : ERR HELD MAP INPUT READY: frames=608 context=0
17:51:19.635 SCRIPT : ERR HELD MAP KEY RIGHT READY
17:51:20.760 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<37.3178,0,83.9648>..<12716,0,12762.7> zoom=0.0357292
17:51:21.157 SCRIPT : ERR HELD MAP PASS: main Enter opens atlas index without a typed number
17:51:21.157 SCRIPT : ERR HELD MAP PASS: page turn keeps held item and restores raised focus
17:51:21.163 SCRIPT : ERR HELD MAP KEY DOWN READY
17:51:22.165 SCRIPT : ERR HELD MAP PASS: menu blocks page input
17:51:22.670 SCRIPT : ERR HELD MAP KEY PAGE READY
17:51:24.229 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6282,0,5380>..<7770,0,7426> zoom=0.333333
17:51:25.751 SCRIPT : ERR HELD MAP PASS: numpad digits plus main Enter select page 37 through validated RPC
17:51:25.752 SCRIPT : ERR HELD MAP KEY INDEX READY
17:51:27.243 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<37.3178,0,83.9648>..<12716,0,12762.7> zoom=0.0357292
17:51:27.806 SCRIPT : ERR HELD MAP PASS: numpad zero returns to index without following player
17:51:27.806 SCRIPT : ERR HELD MAP KEY CONSUME READY
17:51:28.256 SCRIPT : ERR HELD MAP INPUT: frames=935 value=1 blocked=0
17:51:28.267 SCRIPT : ERR HELD MAP INPUT: frames=936 value=1 blocked=0
17:51:28.291 SCRIPT : ERR HELD MAP INPUT: frames=937 value=1 blocked=0
17:51:28.312 SCRIPT : ERR HELD MAP INPUT: frames=938 value=1 blocked=0
17:51:28.332 SCRIPT : ERR HELD MAP INPUT: frames=939 value=1 blocked=0
17:51:28.355 SCRIPT : ERR HELD MAP INPUT: frames=940 value=1 blocked=0
17:51:28.386 SCRIPT : ERR HELD MAP INPUT: frames=941 value=1 blocked=0
17:51:28.398 SCRIPT : ERR HELD MAP INPUT: frames=942 value=1 blocked=0
17:51:28.425 SCRIPT : ERR HELD MAP INPUT: frames=943 value=1 blocked=0
17:51:28.448 SCRIPT : ERR HELD MAP INPUT: frames=944 value=1 blocked=0
17:51:28.471 SCRIPT : ERR HELD MAP INPUT: frames=945 value=1 blocked=0
17:51:28.492 SCRIPT : ERR HELD MAP INPUT: frames=946 value=1 blocked=0
17:51:28.514 SCRIPT : ERR HELD MAP INPUT: frames=947 value=1 blocked=0
17:51:28.547 SCRIPT : ERR HELD MAP INPUT: frames=948 value=1 blocked=0
17:51:28.561 SCRIPT : ERR HELD MAP INPUT: frames=949 value=1 blocked=0
17:51:28.585 SCRIPT : ERR HELD MAP INPUT: frames=950 value=1 blocked=0
17:51:28.624 SCRIPT : ERR HELD MAP INPUT: frames=951 value=1 blocked=0
17:51:28.650 SCRIPT : ERR HELD MAP INPUT: frames=952 value=1 blocked=0
17:51:28.664 SCRIPT : ERR HELD MAP INPUT: frames=953 value=1 blocked=0
17:51:28.689 SCRIPT : ERR HELD MAP INPUT: frames=954 value=1 blocked=0
17:51:28.710 SCRIPT : ERR HELD MAP INPUT: frames=955 value=1 blocked=0
17:51:28.745 SCRIPT : ERR HELD MAP INPUT: frames=956 value=1 blocked=0
17:51:28.760 SCRIPT : ERR HELD MAP INPUT: frames=957 value=1 blocked=0
17:51:28.783 SCRIPT : ERR HELD MAP INPUT: frames=958 value=1 blocked=0
17:51:28.805 SCRIPT : ERR HELD MAP INPUT: frames=959 value=1 blocked=0
17:51:28.837 SCRIPT : ERR HELD MAP INPUT: frames=960 value=1 blocked=0
17:51:28.852 SCRIPT : ERR HELD MAP INPUT: frames=961 value=1 blocked=0
17:51:28.991 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7473,5660.18> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6,0,10750>..<1494,0,12796> zoom=0.333333
17:51:29.871 SCRIPT : ERR HELD MAP PASS: right arrow turns page without reaching character movement
17:51:29.871 SCRIPT : ERR HELD MAP KEY WALK READY
17:51:31.428 SCRIPT : ERR HELD MAP WALK: displacement=0.798434
17:51:31.428 SCRIPT : ERR HELD MAP PASS: WASD movement remains available with atlas held
17:51:31.429 SCRIPT : ERR HELD MAP KEY DOUBLE READY
17:51:33.996 SCRIPT : ERR HELD MAP PASS: double map action opens the real interactive map
17:51:34.000 SCRIPT : ERR HELD MAP FULLSCREEN CLOSE TRACE
17:51:34.780 SCRIPT : ERR HELD MAP FRAME: holder=<5135.18,50.7351,5660.97> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<37.3178,0,83.9648>..<12716,0,12762.7> zoom=0.0357292
17:51:36.066 SCRIPT : ERR HELD MAP PASS: interactive map preserves the selected paper sheet
17:51:36.066 SCRIPT : ERR HELD MAP KEY SINGLE READY
17:51:36.766 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=46717.2
17:51:37.011 SCRIPT : ERR HELD MAP CLEAR TRACE
17:51:38.116 SCRIPT : ERR HELD MAP PASS: single map press puts the paper away
17:51:38.116 SCRIPT : ERR HELD MAP KEY STORED READY
17:51:38.578 SCRIPT : ERR HELD MAP MODE REQUEST: mode=3 world=48491.2
17:51:41.157 SCRIPT : ERR HELD MAP PASS: double map press from storage waits for equip then opens interactive map
17:51:41.157 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=51108.9
17:51:41.164 SCRIPT : ERR HELD MAP FULLSCREEN CLOSE TRACE
17:51:41.392 SCRIPT : ERR HELD MAP CLEAR TRACE
17:51:44.233 SCRIPT : ERR HELD MAP PASS: ordinary map inserted
17:51:44.236 SCRIPT : ERR HELD MAP PASS: background capture active before stock map activation
17:51:48.330 SCRIPT : ERR HELD MAP PASS: ordinary map still opens fullscreen
17:51:48.330 SCRIPT : ERR HELD MAP CLEAR TRACE
17:51:48.332 SCRIPT : ERR HELD MAP COMPLETE
@@ -0,0 +1,30 @@
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)
sequence={'Right':[0xff53],'w':[ord('w')],'enter':[0xff0d],'Down':[0xff54],'m':[ord('m')],'page':[0xffb3,0xffb7,0xff0d],'index':[0xffb0,0xff8d]}[sys.argv[2]]
for key in sequence * (int(sys.argv[3]) if len(sys.argv)>3 else 1):
code=x.XKeysymToKeycode(d,key);assert code
assert t.XTestFakeKeyEvent(d,code,1,0);x.XFlush(d);time.sleep(.6 if sys.argv[2] in ('w','Right') else .09)
assert t.XTestFakeKeyEvent(d,code,0,0);x.XFlush(d);time.sleep(.14)
x.XCloseDisplay(d)
@@ -0,0 +1,21 @@
{
"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
}
}
},
"native_checks_passed": 20,
"scope": "Hidden local native test: main Enter opening/confirming, numpad Enter confirming, arrow consumption, actual W displacement, menu guards, both double-M paths, ordinary map",
"source_profile": "/tmp/err-held-pages-consume-b"
}
@@ -0,0 +1,43 @@
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','enter','1'),('CONSUME','Right','1'),('WALK','w','1'),('PAGE','page','1'),('INDEX','index','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 'scenario preparation failed; spawning remains disabled' in text:result='scene-placement-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,6 @@
{
"addons/core/Configs/ERR/ObserverInput.conf": "89928b57fdd6fa3ae837fb2daf55f627a62a98fd111ffdb55c2874f1e040afaf",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_SharedMapComponent.c": "caaa71608ace7278f6ec343750ce21f8697826933b3119c1b706774c8a8a686c",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_AtlasPresentation.c": "ca2e3ea1b061fef3479d7a8c0f86e337813d908382a3344acf7adb34cefaf4f1",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_NativeHeldMapProbe.c": "f762a418f50259aece9ed344356f8d1eabf61c586164311deab0501d87a53478"
}