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
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@@ -0,0 +1,51 @@
17:28:26.555 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=13369.5
17:28:26.557 SCRIPT : ERR HELD MAP PASS: shared map inserted into real prisoner inventory
17:28:26.557 SCRIPT : ERR HELD MAP MODE REQUEST: mode=3 world=13369.5
17:28:27.304 SCRIPT : ERR HELD MAP FRAME: holder=<6998.38,113.564,5517.6> 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:28:32.821 SCRIPT : ERR HELD MAP FRAME: holder=<6998.38,113.564,5517.6> 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:28:36.720 SCRIPT : ERR HELD MAP PASS: shared map stays in hand through native animation
17:28:36.720 SCRIPT : ERR HELD MAP PASS: shared map does not open fullscreen menu
17:28:36.721 SCRIPT : ERR HELD MAP PASS: held surface refreshes across two real capture cycles
17:28:36.721 SCRIPT : ERR HELD MAP PASS: entire captured page stays inside native map bounds
17:28:38.344 SCRIPT : ERR HELD MAP FRAME: holder=<6998.38,113.564,5517.6> 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:28:43.873 SCRIPT : ERR HELD MAP FRAME: holder=<6998.38,113.564,5517.6> 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:28:44.812 SCRIPT : ERR HELD MAP TEXTURE: texture=496x682 mapWidget=306.667x306.667
17:28:44.812 SCRIPT : ERR HELD MAP PASS: texture and map canvas match the paper aspect, not the game viewport
17:28:47.369 SCRIPT : ERR HELD MAP INPUT STATE: ownerMatch=1 inHand=1 heldMatch=1 life=0 topMenu=NULL dialog=0 chat=0 focused=NULL
17:28:47.369 SCRIPT : ERR HELD MAP INPUT READY: frames=1401 context=0
17:28:47.369 SCRIPT : ERR HELD MAP KEY RIGHT READY
17:28:47.645 SCRIPT : ERR HELD MAP INPUT: frames=1421 value=1 blocked=0
17:28:47.663 SCRIPT : ERR HELD MAP INPUT: frames=1422 value=1 blocked=0
17:28:47.679 SCRIPT : ERR HELD MAP INPUT: frames=1423 value=1 blocked=0
17:28:47.706 SCRIPT : ERR HELD MAP INPUT: frames=1424 value=1 blocked=0
17:28:48.382 SCRIPT : ERR HELD MAP FRAME: holder=<6998.46,113.564,5517.6> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<37.3178,0,83.9648>..<12716,0,12762.7> zoom=0.0357292
17:28:49.392 SCRIPT : ERR HELD MAP PASS: arrow opens atlas index through controller RPC
17:28:49.393 SCRIPT : ERR HELD MAP PASS: page turn keeps held item and restores raised focus
17:28:49.399 SCRIPT : ERR HELD MAP KEY DOWN READY
17:28:50.400 SCRIPT : ERR HELD MAP PASS: menu blocks page input
17:28:50.904 SCRIPT : ERR HELD MAP KEY PAGE READY
17:28:52.371 SCRIPT : ERR HELD MAP FRAME: holder=<6998.46,113.564,5517.6> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<6282,0,5380>..<7770,0,7426> zoom=0.333333
17:28:53.943 SCRIPT : ERR HELD MAP PASS: physical numpad selects page 37 through validated RPC
17:28:53.943 SCRIPT : ERR HELD MAP KEY INDEX READY
17:28:55.381 SCRIPT : ERR HELD MAP FRAME: holder=<6998.46,113.564,5517.6> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<37.3178,0,83.9648>..<12716,0,12762.7> zoom=0.0357292
17:28:55.984 SCRIPT : ERR HELD MAP PASS: numpad zero returns to index without following player
17:28:55.985 SCRIPT : ERR HELD MAP KEY DOUBLE READY
17:28:58.031 SCRIPT : ERR HELD MAP PASS: double map action opens the real interactive map
17:28:58.042 SCRIPT : ERR HELD MAP FULLSCREEN CLOSE TRACE
17:28:58.811 SCRIPT : ERR HELD MAP FRAME: holder=<6998.46,113.564,5517.6> offset=<0,-204.781,0> size=<12800,580.312,12800> frame=<37.3178,0,83.9648>..<12716,0,12762.7> zoom=0.0357292
17:29:00.046 SCRIPT : ERR HELD MAP PASS: interactive map preserves the selected paper sheet
17:29:00.046 SCRIPT : ERR HELD MAP KEY SINGLE READY
17:29:00.866 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=47589.2
17:29:01.240 SCRIPT : ERR HELD MAP CLEAR TRACE
17:29:02.577 SCRIPT : ERR HELD MAP PASS: single map press puts the paper away
17:29:02.577 SCRIPT : ERR HELD MAP KEY STORED READY
17:29:02.712 SCRIPT : ERR HELD MAP MODE REQUEST: mode=3 world=49369.2
17:29:05.649 SCRIPT : ERR HELD MAP PASS: double map press from storage waits for equip then opens interactive map
17:29:05.649 SCRIPT : ERR HELD MAP MODE REQUEST: mode=1 world=52324.5
17:29:05.655 SCRIPT : ERR HELD MAP FULLSCREEN CLOSE TRACE
17:29:05.916 SCRIPT : ERR HELD MAP CLEAR TRACE
17:29:08.673 SCRIPT : ERR HELD MAP PASS: ordinary map inserted
17:29:08.674 SCRIPT : ERR HELD MAP PASS: background capture active before stock map activation
17:29:12.739 SCRIPT : ERR HELD MAP PASS: ordinary map still opens fullscreen
17:29:12.740 SCRIPT : ERR HELD MAP CLEAR TRACE
17:29:12.742 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],'Down':[0xff54],'m':[ord('m')],'page':[0xffb3,0xffb7,0xff8d],'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(.09)
assert t.XTestFakeKeyEvent(d,code,0,0);x.XFlush(d);time.sleep(.14)
x.XCloseDisplay(d)
@@ -0,0 +1,24 @@
{
"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": 18,
"terrain": "Everon",
"detail_pages": 70,
"scope": "Hidden local Workbench runtime, real XTest keys, ordinary map coexistence; no remote multiplayer/JIP claim",
"source_profile": "/tmp/err-held-pages-atlas-d",
"earlier_run_note": "atlas-c compiled but the unrelated generated prison could not be placed; runner interrupted and owned hidden processes cleaned before final atlas-d run."
}
@@ -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','Right','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,10 @@
{
"addons/core/Scripts/Game/ERR/30_Map/ERRM_AtlasPresentation.c": "a8f2cda43022a2142026a56698640455cc1a31b457b31cd77fc764af598e7888",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_SharedMapComponent.c": "2317e0a64e6b34e624cad7df38c121d59670d26778eb46bc9f06e87fda20c203",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_SharedMapPages.c": "b063d3d70b0ac39fd1e5f11ad41dcbc0a9ceb1680700e6e39d9d0651eacf68b9",
"addons/core/Scripts/Game/ERR/30_Map/ERRM_NativeHeldMapProbe.c": "636f17aa7e4a72b85d9d0245ae1248a4555005ac6b6addd5386eb5e04926b3c4",
"addons/core/Configs/ERR/ObserverInput.conf": "a2cb8f039f164865cbef40d69bba2569c296bf387f36a472ffcfb41cd5c11942",
"addons/core/UI/layouts/ERRMap/SharedMapRenderTarget.layout": "826c524248d2a2551998b32ab963a1c40751f16308d52d472befa423f1797b39",
"addons/core/Materials/ERRM_MapRenderTarget.emat": "4ab251037d40a850e3767c0de85136842bcd4fd130eda47bf8e19352b0d030e3",
"addons/core/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et": "cad0bc81945786ac6c2551f398c8e0f7c24cffa525000c43095fb835aeb21765"
}