Prepare independent successor playtest with spawn recovery and casualty feedback

This commit is contained in:
2026-09-19 22:12:52 +02:00
parent 61e165ef5b
commit 6cf989a060
266 changed files with 134064 additions and 154 deletions
+11 -7
View File
@@ -10,16 +10,20 @@ def validate_alignment_evidence(content, nonce, look_proof, approach_proof, proo
return _validate(content,nonce,look_proof,approach_proof,proof)
def validate_facing_evidence(content, nonce, look_proof, approach_proof, proof):
return _validate(content,nonce,look_proof,approach_proof,proof,facing=True)
def validate_facing_evidence(content, nonce, look_proof, approach_proof, proof, *, profile="standard"):
return _validate(content,nonce,look_proof,approach_proof,proof,facing=True,profile=profile)
def _validate(content, nonce, look_proof, approach_proof, proof, facing=False):
def _validate(content, nonce, look_proof, approach_proof, proof, facing=False, profile="standard"):
result={'verified':False,'errors':[],'scope':'stationary yaw-only alignment and native selection of the original prison lock after a verified interior approach; no F hold, unlock, exit or multiplayer qualification','held_action_verified':False,'escape_verified':False}
if facing:
result['scope']='stationary yaw facing the original gate with exact disabled door and available lock diagnostics; lock selection, held action and escape remain unverified'
result['lock_selection_verified']=False
try:
need(type(profile) is str and profile in ('standard','coarse') and (facing or profile == 'standard'), 'Unknown expected facing profile')
need(type(proof) is dict and proof.get('profile','standard') == profile, 'Facing profile differs from explicit verifier capability')
need(profile != 'coarse' or approach_proof.get('profile') == 'coarse', 'Coarse facing lacks coarse approach prerequisite')
max_pixels, max_angle = (384,35) if profile == 'coarse' else (128,15)
approach=validate_approach_evidence(content,nonce,look_proof,approach_proof)
need(approach['verified'],'prior native approach is unverified: '+str(approach['errors']))
calibration=validate_look_evidence(content,nonce,look_proof)
@@ -28,7 +32,7 @@ def _validate(content, nonce, look_proof, approach_proof, proof, facing=False):
need(.01<=abs(gain)<=.5,'native calibration gain outside alignment range')
need(type(proof) is dict and not proof.get('events') and proof.get('requested') is True and proof.get('completed') is True and proof.get('nonce')==nonce and not proof.get('error'),'alignment did not complete under this nonce')
if facing:
need(set(proof)=={'requested','completed','nonce','geometry','started_monotonic','finished_monotonic','deadline_monotonic','initial_sample','final_sample','facing_samples','actions','motions','samples'},'unexpected facing proof fields or lock-selection claim')
need(set(proof)==({'requested','completed','nonce','geometry','started_monotonic','finished_monotonic','deadline_monotonic','initial_sample','final_sample','facing_samples','actions','motions','samples'} | ({'profile'} if 'profile' in proof else set())),'unexpected facing proof fields or lock-selection claim')
start=number(proof['started_monotonic']);finish=number(proof['finished_monotonic']);deadline=number(proof['deadline_monotonic'])
need(approach_proof['finished_monotonic']<=start<finish<=deadline<=start+8,'alignment helper interval outside original stage bound')
if facing:
@@ -80,15 +84,15 @@ def _validate(content, nonce, look_proof, approach_proof, proof, facing=False):
old_index=first;old_time=start;pixel_sum=0
for motion in motions:
dx=motion['dx'];at=number(motion['monotonic']);before=motion['after_sample'];after=motion['response_sample']
need(type(dx) is int and 1<=abs(dx)<=128 and type(motion['dy']) is int and motion['dy']==0,'alignment motion is not bounded horizontal input')
need(type(dx) is int and 1<=abs(dx)<=max_pixels and type(motion['dy']) is int and motion['dy']==0,'alignment motion is not bounded horizontal input')
need(type(before) is int and type(after) is int and old_index<=before<after<=last,'alignment motion references reversed')
need(old_time<=at<=finish and before in receipts and after in receipts and receipts[before]<=at<=receipts[after] and at-receipts[before]<=.5 and receipts[after]-at<=1.5,'alignment input timestamps contradict native samples')
baseline=yaw(samples[before]['look']['direction']);wanted=angle(heading(samples[before]),baseline)
change=angle(yaw(samples[after]['look']['direction']),baseline)
need(abs(wanted)>3 and dx*gain*wanted>0 and .05<=abs(change)<=15 and change*dx*gain>0,'native turn did not follow same-run signed calibration toward handle')
need(abs(wanted)>3 and dx*gain*wanted>0 and .05<=abs(change)<=max_angle and change*dx*gain>0,'native turn did not follow same-run signed calibration toward handle')
for i in range(before,after+1):
d=angle(yaw(samples[i]['look']['direction']),baseline)
need(abs(d)<=15 and (abs(d)<.05 or d*dx*gain>0),'intermediate native turn reversed or exceeded bound')
need(abs(d)<=max_angle and (abs(d)<.05 or d*dx*gain>0),'intermediate native turn reversed or exceeded bound')
need(after-1>=before and 100<=samples[after]['real_ms']-samples[after-1]['real_ms']<=500 and abs(angle(yaw(samples[after]['look']['direction']),yaw(samples[after-1]['look']['direction'])))<=.2,'native turn response did not settle over consecutive samples')
need(samples[after]['real_ms']-samples[before]['real_ms']<=2500,'native turn response interval is unbounded')
old_index=after;old_time=at;pixel_sum+=abs(dx)