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
+45 -3
View File
@@ -14,7 +14,14 @@ p.add_argument('--steam', type=Path, default=Path.home()/'.local/share/Steam')
p.add_argument('--external-addons', type=Path, help='Installed RHS/WCS/BMP source root; expose only audited closure in a separate Chat profile')
p.add_argument('--compat', type=Path, required=True, help='Disposable cloned Proton compatdata directory outside Steam')
p.add_argument('--profile', type=Path, required=True, help='Separate disposable successor Workbench profile')
p.add_argument('--smoke', choices=['escape-route', 'optional-site-skip', 'infantry-combat', 'medical-combat', 'hunter-faction', 'unconscious-camera', 'town-garrisons', 'site-garrisons', 'radio-interaction', 'enemy-loadout', 'aggression', 'air-logistics', 'air-assault', 'air-recon', 'airfield-markers', 'opening-tools', 'mortar-station', 'generated-sites', 'hq-local-handoff', 'infantry-transfer', 'hq-body', 'convoy', 'supply-convoys', 'hq-memory', 'hq-awareness', 'aircraft-field', 'aircraft-route', 'native-end-active', 'native-end-preparing', 'aircraft-control', 'aircraft-cancel', 'aircraft-translate', 'map-ownership', 'mortar-refresh', 'mortar-salvo', 'mortar-courier', 'station-teardown', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'mortar-expiry', 'mortar-transfer', 'mortar-fire', 'patrol-hq', 'victory', 'lost-helicopter', 'player-death', 'radio-network', 'hq-response', 'mortar-inventory', 'startup-failure', 'site-survey', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'], default='victory')
p.add_argument('--smoke', choices=['coordinated-ai', 'crash-start', 'crash-geometry', 'normal-escape-route', 'escape-route', 'optional-site-skip', 'infantry-combat', 'medical-combat', 'hunter-faction', 'unconscious-camera', 'objective-map', 'town-garrisons', 'site-garrisons', 'radio-interaction', 'enemy-loadout', 'aggression', 'air-logistics', 'air-assault', 'air-recon', 'airfield-markers', 'opening-tools', 'mortar-station', 'generated-sites', 'hq-local-handoff', 'infantry-transfer', 'hq-body', 'convoy', 'supply-convoys', 'supply-travel', 'mounted-ammo', 'alarm-hearing', 'hq-memory', 'hq-awareness', 'aircraft-field', 'aircraft-route', 'native-end-active', 'native-end-preparing', 'aircraft-control', 'aircraft-cancel', 'aircraft-translate', 'map-ownership', 'mortar-refresh', 'mortar-salvo', 'mortar-courier', 'station-teardown', 'inventory-hitzone', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'mortar-expiry', 'mortar-transfer', 'mortar-fire', 'patrol-hq', 'victory', 'lost-helicopter', 'player-death', 'radio-network', 'hq-response', 'mortar-inventory', 'startup-failure', 'site-survey', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'], default='victory')
p.add_argument('--trace-random-radius', action='store_true', help='Workbench-only read-only zero-radius caller traces; one normal Chat round, capped at sixteen records')
p.add_argument('--maintenance-refuel', action='store_true', help='Opt-in normal-route check: original held Southern fuel can transfers finite fuel through its native UAZ action; one arranged tank depletion, no stock creation')
p.add_argument('--mounted-swap-eligibility', action='store_true', help='Read-only mounted-ammo variant: one exact finite cargo/mounted magazine CanSwap call; no transfer or radio proof')
p.add_argument('--mounted-bmp', action='store_true', help='Read-only original BMP slot4 complete mounted counts and its natural HQ radio delivery; isolates unrelated opening hunters before unlock')
p.add_argument('--mine-stock', action='store_true', help='Read-only mounted-ammo check of exact callback-proved finite PMN4 cargo before and after natural radio delivery')
p.add_argument('--mounted-courier', action='store_true', help='Mounted-ammo variant: intentionally deplete one original installed magazine, then require natural HQ radio, finite pickup, native exchange and original-seat return')
p.add_argument('--mounted-intercept', action='store_true', help='After convoy driving, two synthetic witness samples exercise real HQ radio/planning and original escort detour/hold/expiry/resume')
p.add_argument('--convoy-cover', action='store_true', help='After convoy driving, arrange the existing prisoner to verify native sighting/radio HOLD and RESUME')
p.add_argument('--field-terrain-audit', action='store_true', help='After a fixed aircraft-field survey refusal, log one read-only 1681-node coarse terrain grid; never selects or qualifies a corridor')
p.add_argument('--field-service-cancel', action='store_true', help='Explicit aircraft-field variant: Stop the original retained service during measured cruise; requires physical cancellation landing')
@@ -24,10 +31,27 @@ p.add_argument('--flight-autohover', action='store_true', help='Opt-in owned nat
p.add_argument('--flight-action-inputs', action='store_true', help='Experimental exact-AI ActionManager inputs; Core powered-flight fixture only')
p.add_argument('--flight-input-diagnostics', action='store_true', help='Opt-in read-only powered-flight input/application and native rotor signal observations')
p.add_argument('--recon-takeover-only', action='store_true', help='Air-recon fixture: only native faction handover/release and explicit aircraft deletion')
p.add_argument('--body-recovery-only', action='store_true', help='Air-logistics fixture: only physical corpse inspection and returned document intelligence')
p.add_argument('--coordinated-blocked-only', action='store_true', help='Coordinated fixture: native movement, cancellation and unreachable-route failure only; explicitly excludes suppression qualification')
p.add_argument('--rounds', type=int, default=2)
p.add_argument('--timeout', type=int, default=360)
p.add_argument('--project', choices=['core', 'chat'], default='chat', help='Diagnostic fixture family (both load the combined mod)')
a = p.parse_args()
if a.smoke == 'coordinated-ai' and (a.project != 'core' or a.rounds != 1 or a.timeout < 720): p.error('coordinated-ai requires Core, one round and timeout at least720 seconds')
if a.coordinated_blocked_only and a.smoke != 'coordinated-ai': p.error('--coordinated-blocked-only requires --smoke coordinated-ai')
if a.smoke == 'inventory-hitzone' and (a.project != 'core' or a.rounds != 1 or a.timeout < 240): p.error('inventory-hitzone requires --project core --rounds 1 and timeout at least 240 seconds')
if a.smoke == 'crash-start' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 240): p.error('crash-start requires Chat, one round and timeout at least 240 seconds')
if a.smoke == 'crash-geometry' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 180): p.error('crash-geometry requires Chat, one round and timeout at least180 seconds')
if a.trace_random_radius and (a.smoke != 'normal-escape-route' or a.project != 'chat' or a.rounds != 1 or a.timeout < 420): p.error('--trace-random-radius requires Chat normal-escape-route, one round and timeout at least 420 seconds')
if a.smoke == 'objective-map' and (a.project != 'core' or a.rounds != 1): p.error('objective-map requires --project core --rounds 1')
if a.smoke == 'unconscious-camera' and a.project != 'core': p.error('unconscious-camera requires --project core to keep the general smoke fixture inactive')
if a.mine_stock:
if a.smoke != 'mounted-ammo' or a.project != 'chat' or a.rounds != 1 or a.timeout < 360:
p.error('--mine-stock requires --smoke mounted-ammo --project chat --rounds 1 and timeout at least 360 seconds')
if a.mounted_courier or a.mounted_swap_eligibility:
p.error('--mine-stock cannot combine with --mounted-courier or --mounted-swap-eligibility')
if a.maintenance_refuel and (a.smoke != 'normal-escape-route' or a.project != 'chat' or a.rounds != 1 or a.timeout < 420): p.error('--maintenance-refuel requires Chat normal-escape-route, one round and timeout at least 420 seconds')
if a.body_recovery_only and (a.smoke != 'air-logistics' or a.project != 'core' or a.rounds != 1): p.error('--body-recovery-only requires Core air-logistics and one round')
if a.recon_takeover_only and (a.smoke != 'air-recon' or a.project != 'core' or a.rounds != 1): p.error('--recon-takeover-only requires Core air-recon and one round')
steam, compat, profile = a.steam.resolve(), a.compat.resolve(), a.profile.resolve()
if not 1 <= a.rounds <= 10 or not 60 <= a.timeout <= 1800:
@@ -41,9 +65,18 @@ if a.smoke == 'mortar-courier' and (a.project != 'chat' or a.rounds != 1 or a.ti
if a.smoke in {'mortar-refresh', 'mortar-salvo', 'mortar-expiry', 'mortar-transfer', 'mortar-fire'} and (a.project != 'chat' or a.rounds != 1 or a.timeout < 400):
p.error('mortar-refresh/mortar-salvo/mortar-expiry/mortar-transfer/mortar-fire requires --project chat --rounds 1 --timeout at least 400')
if a.smoke in {'aircraft-field', 'aircraft-route', 'aircraft-control', 'aircraft-cancel', 'aircraft-translate'} and (a.project != 'chat' or a.rounds != 1 or a.timeout < 420): p.error('aircraft-field/aircraft-route/aircraft-control/aircraft-cancel/aircraft-translate requires Chat, one round, and at least 420 seconds')
if a.mounted_swap_eligibility and a.smoke != 'mounted-ammo': p.error('--mounted-swap-eligibility requires --smoke mounted-ammo')
if a.mounted_courier and (a.smoke != 'mounted-ammo' or a.project != 'chat' or a.rounds != 1 or a.timeout < 780): p.error('--mounted-courier requires --smoke mounted-ammo --project chat --rounds 1 and timeout at least780 seconds')
if a.mounted_courier and a.mounted_swap_eligibility: p.error('--mounted-courier and --mounted-swap-eligibility are mutually exclusive')
if a.mounted_intercept and (a.smoke != 'convoy' or a.project != 'chat' or a.rounds != 1 or a.timeout < 900): p.error('--mounted-intercept requires Chat --smoke convoy, one round and timeout at least900 seconds')
if a.mounted_intercept and a.convoy_cover: p.error('--mounted-intercept and --convoy-cover are mutually exclusive')
if a.convoy_cover and a.smoke != 'convoy': p.error('--convoy-cover requires --smoke convoy')
if a.convoy_cover and a.timeout < 900: p.error('--convoy-cover requires timeout at least900 seconds')
if a.smoke == 'supply-travel' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 480): p.error('supply-travel requires Chat, one round, and at least480 seconds')
if a.smoke == 'supply-convoys' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 900): p.error('supply-convoys requires Chat, one round, and at least900 seconds')
if a.smoke == 'alarm-hearing' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 360): p.error('alarm-hearing requires Chat, exactly one round, and timeout at least360 seconds')
if a.smoke == 'mounted-ammo' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 360): p.error('mounted-ammo requires Chat, exactly one round, and timeout at least360 seconds')
if a.mounted_bmp and (a.smoke != 'mounted-ammo' or a.project != 'chat' or a.rounds != 1 or a.timeout < 360 or a.mine_stock or a.mounted_courier or a.mounted_swap_eligibility): p.error('--mounted-bmp requires Chat mounted-ammo, one round, timeout at least360 seconds, without mine/courier/swap flags')
if a.smoke == 'convoy' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 600): p.error('convoy requires Chat, exactly one round, and timeout at least600 seconds')
if a.smoke == 'infantry-transfer' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 360): p.error('infantry-transfer requires Chat, one round and timeout at least360 seconds')
if a.smoke == 'hq-local-handoff' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 360): p.error('hq-local-handoff requires Chat, one round and timeout at least360 seconds')
@@ -107,6 +140,13 @@ for proc in Path('/proc').iterdir():
except (FileNotFoundError, PermissionError, ProcessLookupError): pass
command = ['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', profile_arg, '-logconsole', '-wbModule=WorldEditor', '-load', 'Worlds/ERR_Everon.ent', '-plugin=ERR_ValidateWorldPlugin', '-errPlay', '1', '-errSmoke', '1', '-errSmokeOutcome', a.smoke, '-noThrow', '-disableCrashReporter']
if a.convoy_cover: command += ['-errConvoyCover', '1']
if a.mounted_intercept: command += ['-errMountedIntercept', '1']
if a.mounted_swap_eligibility: command += ['-errMountedSwapEligibility', '1']
if a.mounted_courier: command += ['-errMountedCourier', '1']
if a.mounted_bmp: command += ['-errMountedBMP', '1']
if a.mine_stock: command += ['-errMineStock', '1']
if a.maintenance_refuel: command += ['-errMaintenanceRefuel', '1']
if a.trace_random_radius: command += ['-errTraceRandomRadius', '1']
if a.field_service_cancel: command += ['-errSmokeFieldServiceCancel', '1']
if a.field_terrain_audit: command += ['-errSmokeFieldTerrainAudit', '1']
if a.route_service_cancel: command += ['-errSmokeRouteServiceCancel', '1']
@@ -115,11 +155,13 @@ if a.flight_input_diagnostics: command += ['-errFlightInputDiag', '1']
if a.flight_action_inputs: command += ['-errFlightActionInputs', '1']
if a.flight_autohover: command += ['-errFlightAutohover', '1']
if a.recon_takeover_only: command += ['-errReconTakeoverOnly', '1']
if a.body_recovery_only: command += ['-errBodyRecoveryOnly', '1']
if a.coordinated_blocked_only: command += ['-errCoordinatedBlockedOnly', '1']
if a.project == 'core':
if a.smoke not in {'optional-site-skip', 'infantry-combat', 'medical-combat', 'hunter-faction', 'unconscious-camera', 'town-garrisons', 'site-garrisons', 'radio-interaction', 'enemy-loadout', 'aggression', 'air-logistics', 'air-assault', 'air-recon', 'airfield-markers', 'opening-tools', 'mortar-station', 'generated-sites', 'native-end-active', 'native-end-preparing', 'station-teardown', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'victory', 'startup-failure', 'site-survey', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'}: p.error('Unsupported Core-only fixture')
if a.smoke not in {'coordinated-ai', 'optional-site-skip', 'infantry-combat', 'medical-combat', 'hunter-faction', 'unconscious-camera', 'objective-map', 'town-garrisons', 'site-garrisons', 'radio-interaction', 'enemy-loadout', 'aggression', 'air-logistics', 'air-assault', 'air-recon', 'airfield-markers', 'opening-tools', 'mortar-station', 'generated-sites', 'native-end-active', 'native-end-preparing', 'station-teardown', 'inventory-hitzone', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'victory', 'startup-failure', 'site-survey', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'}: p.error('Unsupported Core-only fixture')
command[command.index('-plugin=ERR_ValidateWorldPlugin')] = '-plugin=ERR_ValidateBaseWorldPlugin'
command[command.index('-errSmoke')] = '-errBaseSmoke'
if a.smoke in {'station-teardown', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'} and a.project != 'core': p.error('This fixture requires --project core')
if a.smoke in {'station-teardown', 'inventory-hitzone', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'} and a.project != 'core': p.error('This fixture requires --project core')
if a.smoke in {'startup-failure', 'site-survey', 'transport-survey', 'extraction-startup-failure', 'extraction-boundary-failure'} and (a.project != 'core' or a.rounds != 1): p.error('This diagnostic requires --project core --rounds 1')
env = os.environ.copy()
env.update(STEAM_COMPAT_DATA_PATH=str(compat), STEAM_COMPAT_CLIENT_INSTALL_PATH=str(steam), WINEPREFIX=str(compat/'pfx'))