fix(streaming): no false gate on digs, no see-through at tile handoffs; density volume off

- Dig near the pawn: a same-tile collision recook withdrew readiness although the old body was
  still installed, so the gate held a standing pawn (957 of 1,931 frames over 8 near digs).
  A tile now stays ready during a recook while collision is still wanted and its existing body is
  valid. After: 0 gate frames, 0 falling frames over 2,604 frames. Dig directly under the pawn
  still falls (~127 cm, max ~502 cm/s). The reported "accelerating toward the ground" was not
  reproduced; the false hold is the measured part.
- See-through: the retire logic only waited for replacements that overlapped the old tile in
  volume and missed desired neighbours touching at a face/edge/corner. Handoff now includes
  contact. New surface-witness gap audit (24 surface points per tile, skirts excluded, catches an
  injected early hide). 6000 cm/s walk, 75 s: 3 gaps / 51 frames / longest 603 ms -> 0.
  Dig session: 0 -> 0. Overlap audit and edit ghost stay at 0.
- bEnableDensityVolume defaults to false; when off: no volume, no fill thread, uploads or tick
  work, no volume-dependent proof bypass; terrain MIDs get VolP5.z = 0 (enable off), other VolP*
  black, VolTex* null, so M_Test1's volume nodes return their neutral result.

Gate: deep gate-on passes (79.9 m, 3 holds, -0.101 cm), gate-off penetrates (-5.1 cm).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-09-29 04:53:57 +02:00
1 parent 0bcd67a016
commit ce6812dbeb
7 files changed
+1111 -76

No files matched your search

+115 -4
View File
@@ -1,6 +1,6 @@
[CmdletBinding()]
param(
[ValidateSet('canonical', 'owner', 'probe', 'perf', 'visual-edit', 'visual-lod', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'parity', 'horizon', 'horizon-render', 'determinism')]
[ValidateSet('canonical', 'owner', 'probe', 'perf', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'parity', 'horizon', 'horizon-render', 'determinism')]
[string]$Scenario = 'canonical',
[switch]$Build,
[ValidateSet('owner', 'default')]
@@ -64,9 +64,11 @@ $SurfaceFallMetrics = [ordered]@{
}
$StrateCrossingMetrics = [ordered]@{ requested = $Scenario -eq 'crossing'; status = 'not_run' }
$VisualStalenessMetrics = [ordered]@{
requested = $Scenario -in @('visual-edit', 'visual-lod')
requested = $Scenario -in @('visual-edit', 'visual-lod', 'visual-gap-walk')
status = 'not_run'
}
$VisualGapMetrics = [ordered]@{ requested = $Scenario -in @('dig-motion', 'visual-gap-walk', 'visual-gap-inject'); status = 'not_run' }
$DigMotionMetrics = [ordered]@{ requested = $Scenario -eq 'dig-motion'; status = 'not_run' }
$CollisionGateStressMetrics = [ordered]@{
requested = $Scenario -eq 'gate-stress' -or
($Scenario -eq 'tests' -and [string]::IsNullOrWhiteSpace($TestFilter))
@@ -540,7 +542,7 @@ function Sync-OwnerAssets {
$null = Copy-Item -LiteralPath $source -Destination $target -Force -PassThru
[void]$rows.Add([ordered]@{
name = $assetName
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'horizon', 'horizon-render', 'determinism')
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'horizon', 'horizon-render', 'determinism')
source_path = $source
source_sha256 = Get-Sha256 $source
staged_path = $target
@@ -588,7 +590,7 @@ function Get-AssetEvidence {
$target = Join-Path $HostRoot "Content\VoxelForge\$assetName.uasset"
[void]$rows.Add([ordered]@{
name = $assetName
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'horizon', 'horizon-render', 'determinism')
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'horizon', 'horizon-render', 'determinism')
source_path = $source
source_sha256 = Get-Sha256 $source
staged_path = $target
@@ -1066,6 +1068,53 @@ function Get-VisualStalenessMetrics([string]$LogPath) {
return $metrics
}
function Get-VisualGapMetrics([string]$LogPath) {
$lineMatch = @(Select-String -LiteralPath $LogPath -Pattern '\[VoxelForgeVisualGapAudit\] result=' -ErrorAction SilentlyContinue |
Select-Object -Last 1)
if ($lineMatch.Count -eq 0) { return [ordered]@{ status = 'missing'; log = $LogPath } }
$line = [string]$lineMatch[0].Line
$metrics = [ordered]@{ status = 'failed'; log = $LogPath; raw = $line }
$result = [regex]::Match($line, 'result=(?<v>PASS|FAIL)')
if ($result.Success -and $result.Groups['v'].Value -eq 'PASS') { $metrics.status = 'passed' }
foreach ($key in @('window_s', 'window_frames', 'camera_view_frames', 'surface_point_frames', 'gap_count', 'gap_frames',
'gap_point_frames', 'max_missing_points', 'longest_gap_ms',
'longest_gap_frames', 'injected_early_hide', 'injection_caught')) {
$match = [regex]::Match($line, ('{0}=(?<v>[^ ]+)' -f $key))
if (-not $match.Success) { continue }
if ($key -in @('window_frames', 'camera_view_frames', 'surface_point_frames', 'gap_count', 'gap_frames', 'gap_point_frames',
'longest_gap_frames',
'max_missing_points', 'injected_early_hide', 'injection_caught')) {
$metrics[$key] = [int]$match.Groups['v'].Value
} else {
$metrics[$key] = [double]$match.Groups['v'].Value
}
}
return $metrics
}
function Get-DigMotionMetrics([string]$LogPath) {
$lineMatch = @(Select-String -LiteralPath $LogPath -Pattern '\[VoxelForgeDigMotion\] result=' -ErrorAction SilentlyContinue |
Select-Object -Last 1)
if ($lineMatch.Count -eq 0) { return [ordered]@{ status = 'missing'; log = $LogPath } }
$line = [string]$lineMatch[0].Line
$metrics = [ordered]@{ status = 'failed'; log = $LogPath; raw = $line }
$result = [regex]::Match($line, 'result=(?<v>PASS|FAIL)')
if ($result.Success -and $result.Groups['v'].Value -eq 'PASS') { $metrics.status = 'passed' }
foreach ($key in @('near_digs', 'near_frames', 'near_gate_frames', 'near_falling_frames',
'near_vertical_motion_frames', 'under_saw_falling', 'under_gate_frames',
'under_fall_cm', 'under_max_downward_velocity_cm_s')) {
$match = [regex]::Match($line, ('{0}=(?<v>[^ ]+)' -f $key))
if (-not $match.Success) { continue }
if ($key -in @('near_digs', 'near_frames', 'near_gate_frames', 'near_falling_frames',
'near_vertical_motion_frames', 'under_saw_falling', 'under_gate_frames')) {
$metrics[$key] = [int]$match.Groups['v'].Value
} else {
$metrics[$key] = [double]$match.Groups['v'].Value
}
}
return $metrics
}
function Get-TestMetrics($Ledger) {
if ($null -eq $Ledger) { return @() }
$logPaths = @($Ledger.log, $Ledger.stdout, $Ledger.stderr) | Where-Object {
@@ -1455,6 +1504,64 @@ try {
Add-Failure "visual LOD repro did not pass: $($VisualStalenessMetrics.status)"
}
}
'visual-gap-walk' {
$baseCvars['voxel.TestVisualGapAudit'] = 1
$baseCvars['voxel.TestVisualStaleness'] = 2
$baseCvars['voxel.TestMove'] = 1
$baseCvars['voxel.TestMoveSpeedCmPerSecond'] = 6000
$baseCvars['voxel.TestMoveStartSeconds'] = 15
$baseCvars['voxel.TestMoveDirection'] = '1, 0, 0.15'
$baseCvars['voxel.TestExitSeconds'] = 90
$baseCvars['voxel.TestMaxClipLevel'] = 6
$baseCvars['voxel.OuterClassifierMode'] = 0
$visualLog = Join-Path $RunRoot 'Logs\visual-gap-walk.log'
$args = New-CommonArguments 'game' $visualLog (Merge-Cvars $baseCvars)
$gameLedger = Invoke-UnrealLaunch 'visual-gap-walk-game' $args `
$visualLog (Join-Path $RunRoot 'Logs\visual-gap-walk.stdout.log') (Join-Path $RunRoot 'Logs\visual-gap-walk.stderr.log')
$VisualGapMetrics = Get-VisualGapMetrics $visualLog
$VisualStalenessMetrics = Get-VisualStalenessMetrics $visualLog
if ($VisualGapMetrics.status -ne 'passed') {
Add-Failure "visual gap walk audit did not pass: $($VisualGapMetrics.status)"
}
if ($VisualStalenessMetrics.status -ne 'passed') {
Add-Failure "visual LOD overlap audit did not pass: $($VisualStalenessMetrics.status)"
}
}
'visual-gap-inject' {
$baseCvars['voxel.TestVisualGapAudit'] = 1
$baseCvars['voxel.TestVisualGapInjectEarlyHide'] = 1
$baseCvars['voxel.TestExitSeconds'] = 45
$baseCvars['voxel.TestMaxClipLevel'] = 6
$baseCvars['voxel.OuterClassifierMode'] = 0
$visualLog = Join-Path $RunRoot 'Logs\visual-gap-inject.log'
$args = New-CommonArguments 'game' $visualLog (Merge-Cvars $baseCvars)
$gameLedger = Invoke-UnrealLaunch 'visual-gap-inject-game' $args `
$visualLog (Join-Path $RunRoot 'Logs\visual-gap-inject.stdout.log') (Join-Path $RunRoot 'Logs\visual-gap-inject.stderr.log')
$VisualGapMetrics = Get-VisualGapMetrics $visualLog
if ($VisualGapMetrics.status -ne 'passed' -or $VisualGapMetrics.injection_caught -ne 1) {
Add-Failure "visual gap audit failed its injected early-hide sensitivity check: $($VisualGapMetrics.status)"
}
}
'dig-motion' {
$baseCvars['voxel.TestDigMotion'] = 1
$baseCvars['voxel.TestDigMotionNearDigCount'] = 8
$baseCvars['voxel.TestDigMotionIntervalSeconds'] = 0.35
$baseCvars['voxel.TestVisualGapAudit'] = 1
$baseCvars['voxel.TestMaxClipLevel'] = 6
$baseCvars['voxel.OuterClassifierMode'] = 0
$digLog = Join-Path $RunRoot 'Logs\dig-motion.log'
$args = New-CommonArguments 'game' $digLog (Merge-Cvars $baseCvars)
$gameLedger = Invoke-UnrealLaunch 'dig-motion-game' $args `
$digLog (Join-Path $RunRoot 'Logs\dig-motion.stdout.log') (Join-Path $RunRoot 'Logs\dig-motion.stderr.log')
$DigMotionMetrics = Get-DigMotionMetrics $digLog
$VisualGapMetrics = Get-VisualGapMetrics $digLog
if ($DigMotionMetrics.status -ne 'passed') {
Add-Failure "dig-motion repro did not pass: $($DigMotionMetrics.status)"
}
if ($VisualGapMetrics.status -ne 'passed') {
Add-Failure "dig-session visual gap audit did not pass: $($VisualGapMetrics.status)"
}
}
'surface-fall' {
$baseCvars['voxel.TestSurfaceFall'] = 1
$baseCvars['voxel.TestSurfaceFallSpawnHeightVoxels'] = 20
@@ -1652,6 +1759,8 @@ $result = [ordered]@{
surface_fall = $SurfaceFallMetrics
strate_crossing = $StrateCrossingMetrics
visual_staleness = $VisualStalenessMetrics
visual_gap = $VisualGapMetrics
dig_motion = $DigMotionMetrics
collision_gate_stress = $CollisionGateStressMetrics
worker_seconds = [ordered]@{
commandlet = if ($CommandletMetrics.Contains('worker_seconds')) { $CommandletMetrics.worker_seconds } else { $null }
@@ -1686,6 +1795,8 @@ try {
[void]$summaryLines.Add("surface_fall=$(ConvertTo-CompactJson $result.surface_fall)")
[void]$summaryLines.Add("strate_crossing=$(ConvertTo-CompactJson $result.strate_crossing)")
[void]$summaryLines.Add("visual_staleness=$(ConvertTo-CompactJson $result.visual_staleness)")
[void]$summaryLines.Add("visual_gap=$(ConvertTo-CompactJson $result.visual_gap)")
[void]$summaryLines.Add("dig_motion=$(ConvertTo-CompactJson $result.dig_motion)")
[void]$summaryLines.Add("collision_gate_stress=$(ConvertTo-CompactJson $result.collision_gate_stress)")
[void]$summaryLines.Add("probe_amplitudes=$(ConvertTo-CompactJson $result.probe_amplitudes)")
[void]$summaryLines.Add("worker_seconds=$(ConvertTo-CompactJson $result.worker_seconds)")