feat(arena): add deterministic headless RL environments
This commit is contained in:
+16
-1
@@ -67,6 +67,8 @@ export interface WalkerController {
|
||||
tick(elapsedSeconds: number, action: WalkerAction): WalkerState;
|
||||
/** Return to the original spawn, or atomically adopt another valid spawn. */
|
||||
reset(spawn?: WalkerSpawn): WalkerState;
|
||||
/** Restore a trusted JSON snapshot without changing the configured spawn. */
|
||||
restore(snapshot: WalkerState): WalkerState;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +140,20 @@ export function createWalker(plan: WalkerPlan, options: WalkerOptions): WalkerCo
|
||||
return snapshot();
|
||||
}
|
||||
|
||||
return { state: snapshot, tick, reset };
|
||||
function restore(next: WalkerState): WalkerState {
|
||||
if (
|
||||
next.levelId !== spawn.levelId || !finitePoint(next.position) || !finitePoint(next.facing) ||
|
||||
!Number.isFinite(next.distance) || next.distance < 0 ||
|
||||
!validPosition(plan, next.levelId, next.position, radius)
|
||||
) throw new RangeError("walker snapshot is incompatible or invalid");
|
||||
position = copy(next.position);
|
||||
facing = normalizedFacing(next.facing);
|
||||
distance = next.distance;
|
||||
accumulator = 0;
|
||||
return snapshot();
|
||||
}
|
||||
|
||||
return { state: snapshot, tick, reset, restore };
|
||||
}
|
||||
|
||||
function normalizedFacing(value: Point2 | undefined): Point2 {
|
||||
|
||||
Reference in New Issue
Block a user