From 82781c272b8459546040664e0b4e3ec93745d4a6 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 25 May 2026 12:43:51 +0200 Subject: [PATCH] =?UTF-8?q?test(phys):=20A6.P5=20fixture=20=E2=80=94=203?= =?UTF-8?q?=20ticks=20from=20live=20door-stuck=20capture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit over-penetration-capture.jsonl is 3 records extracted from door-stuck-capture.jsonl: the cell-crossing over-penetration tick (0xA9B4013F -> 0xA9B40150, sphere committed 0.27m INTO slab), a stuck-position hit=yes tick, and a stuck-position hit=no tick. Drives the A6.P5 replay tests that prove the cellSet gate removal closes both the over-penetration and the intermittent-visibility bugs. extract-records.ps1 is a one-shot extractor; reusable if we capture more. Source captures (door-stuck-*.jsonl, door-stuck-*.launch.log) gitignored. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 10 +++ .../door-bug/over-penetration-capture.jsonl | 3 + tools/jsonl/extract-records.ps1 | 64 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tests/AcDream.Core.Tests/Fixtures/door-bug/over-penetration-capture.jsonl create mode 100644 tools/jsonl/extract-records.ps1 diff --git a/.gitignore b/.gitignore index b6004f5..4e26865 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,16 @@ launch-*.log launch.utf8.log n4-verify*.log +# A6.P5 (2026-05-25) — door-stuck reproduction captures (multi-MB); +# the 3-record fixture extracted from these lives at +# tests/AcDream.Core.Tests/Fixtures/door-bug/over-penetration-capture.jsonl +door-stuck-capture.jsonl +door-stuck-*.launch.log +door-stuck-*.launch.utf8.log +door-fix-*.launch.log +door-fix-*.jsonl +door-walkthrough.* + # ImGui auto-saved window/docking state (per-user, not source) imgui.ini diff --git a/tests/AcDream.Core.Tests/Fixtures/door-bug/over-penetration-capture.jsonl b/tests/AcDream.Core.Tests/Fixtures/door-bug/over-penetration-capture.jsonl new file mode 100644 index 0000000..3d05baa --- /dev/null +++ b/tests/AcDream.Core.Tests/Fixtures/door-bug/over-penetration-capture.jsonl @@ -0,0 +1,3 @@ +{"tick":3630,"timestampMs":15362446,"input":{"currentPos":{"x":132.5935,"y":16.350428,"z":94},"targetPos":{"x":132.4014,"y":16.761757,"z":94},"cellId":2847146303,"sphereRadius":0.48,"sphereHeight":1.2,"stepUpHeight":0.6,"stepDownHeight":1.5,"isOnGround":true,"moverFlags":768,"movingEntityId":1000000},"bodyBefore":{"position":{"x":132.4014,"y":16.761757,"z":94},"orientation":{"isIdentity":false,"x":0,"y":0,"z":0.21672896,"w":0.9762318},"velocity":{"x":-5.0136037,"y":10.735089,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":0,"z":1},"d":-94},"contactPlaneCellId":2847146303,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":0,"z":1},"d":-94},"walkableVertices":[{"x":124.52,"y":16.5,"z":94},{"x":126.9,"y":14.3,"z":94},{"x":133.9,"y":14.299999,"z":94},{"x":136.3,"y":16.5,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0},"result":{"position":{"x":132.4014,"y":16.761757,"z":94},"cellId":2847146320,"isOnGround":true,"collisionNormalValid":false,"collisionNormal":{"x":0,"y":0,"z":0}},"bodyAfter":{"position":{"x":132.4014,"y":16.761757,"z":94},"orientation":{"isIdentity":false,"x":0,"y":0,"z":0.21672896,"w":0.9762318},"velocity":{"x":-5.0136037,"y":10.735089,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0}} +{"tick":3636,"timestampMs":15362481,"input":{"currentPos":{"x":132.4014,"y":16.761757,"z":94},"targetPos":{"x":132.19926,"y":17.116356,"z":94},"cellId":2847146320,"sphereRadius":0.48,"sphereHeight":1.2,"stepUpHeight":0.6,"stepDownHeight":1.5,"isOnGround":true,"moverFlags":768,"movingEntityId":1000000},"bodyBefore":{"position":{"x":132.19926,"y":17.116356,"z":94},"orientation":{"isIdentity":false,"x":0,"y":0,"z":0.25616026,"w":0.96663433},"velocity":{"x":-5.867513,"y":10.293234,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0},"result":{"position":{"x":132.4014,"y":16.761757,"z":94},"cellId":2847146320,"isOnGround":true,"collisionNormalValid":true,"collisionNormal":{"x":-0.9999022,"y":0.013985067,"z":0}},"bodyAfter":{"position":{"x":132.19926,"y":17.116356,"z":94},"orientation":{"isIdentity":false,"x":0,"y":0,"z":0.25616026,"w":0.96663433},"velocity":{"x":-5.867513,"y":10.293234,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":-0.99990225,"y":0.013985068,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":135,"lastUpdateTime":0}} +{"tick":3631,"timestampMs":15362452,"input":{"currentPos":{"x":132.4014,"y":16.761757,"z":94},"targetPos":{"x":132.4014,"y":16.761757,"z":94},"cellId":2847146320,"sphereRadius":0.48,"sphereHeight":1.2,"stepUpHeight":0.6,"stepDownHeight":1.5,"isOnGround":true,"moverFlags":768,"movingEntityId":1000000},"bodyBefore":{"position":{"x":132.4014,"y":16.761757,"z":94},"orientation":{"isIdentity":false,"x":0,"y":0,"z":0.22556531,"w":0.974228},"velocity":{"x":-5.207305,"y":10.642477,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0},"result":{"position":{"x":132.4014,"y":16.761757,"z":94},"cellId":2847146320,"isOnGround":true,"collisionNormalValid":false,"collisionNormal":{"x":0,"y":0,"z":0}},"bodyAfter":{"position":{"x":132.4014,"y":16.761757,"z":94},"orientation":{"isIdentity":false,"x":0,"y":0,"z":0.22556531,"w":0.974228},"velocity":{"x":-5.207305,"y":10.642477,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0}} diff --git a/tools/jsonl/extract-records.ps1 b/tools/jsonl/extract-records.ps1 new file mode 100644 index 0000000..6458bf4 --- /dev/null +++ b/tools/jsonl/extract-records.ps1 @@ -0,0 +1,64 @@ +# A6.P5 fixture builder — pull the 3 representative records from the live +# capture into the test fixture. One-shot; gitignored fixture path. +param( + [string]$Source = 'door-stuck-capture.jsonl', + [string]$Out = 'tests/AcDream.Core.Tests/Fixtures/door-bug/over-penetration-capture.jsonl' +) + +$ErrorActionPreference = 'Stop' +$outDir = Split-Path -Parent $Out +if (-not (Test-Path $outDir)) { New-Item -ItemType Directory -Force -Path $outDir | Out-Null } + +# We need exactly three records: +# A) The over-penetration tick: cellId 2847146303, currentPos.Y ~16.35, +# targetPos.Y ~16.76 — the resolve that committed the over-penetration. +# B) A stuck-position hit=yes tick: cellId 2847146320, currentPos at +# (132.401, 16.762, 94), resultCollisionNormalValid=true. +# C) A stuck-position hit=no tick: cellId 2847146320, same currentPos, +# resultCollisionNormalValid=false. + +$records = Get-Content -LiteralPath $Source -Encoding UTF8 | + ForEach-Object { + if ([string]::IsNullOrWhiteSpace($_)) { return } + $obj = $_ | ConvertFrom-Json + $obj | Add-Member -NotePropertyName _raw -NotePropertyValue $_ + $obj + } + +# A — over-penetration tick: input cell 2847146303, output cell 2847146320, +# target Y >~16.7, result position approx == target (not blocked). +$overpen = $records | + Where-Object { + $_.input.cellId -eq 2847146303 -and + $_.result.cellId -eq 2847146320 -and + $_.input.targetPos.y -gt 16.7 -and + [Math]::Abs($_.result.position.y - $_.input.targetPos.y) -lt 0.01 + } | + Select-Object -First 1 + +# B — stuck-position hit=yes +$stuckHit = $records | + Where-Object { + $_.input.cellId -eq 2847146320 -and + [Math]::Abs($_.input.currentPos.x - 132.401) -lt 0.001 -and + [Math]::Abs($_.input.currentPos.y - 16.762) -lt 0.001 -and + $_.result.collisionNormalValid + } | + Select-Object -First 1 + +# C — stuck-position hit=no +$stuckMiss = $records | + Where-Object { + $_.input.cellId -eq 2847146320 -and + [Math]::Abs($_.input.currentPos.x - 132.401) -lt 0.001 -and + [Math]::Abs($_.input.currentPos.y - 16.762) -lt 0.001 -and + -not $_.result.collisionNormalValid + } | + Select-Object -First 1 + +if ($null -eq $overpen) { throw 'over-penetration tick not found' } +if ($null -eq $stuckHit) { throw 'stuck hit=yes tick not found' } +if ($null -eq $stuckMiss) { throw 'stuck hit=no tick not found' } + +@($overpen._raw, $stuckHit._raw, $stuckMiss._raw) | Set-Content -Encoding utf8 -Path $Out +"Wrote $Out with 3 records (over-penetration + stuck hit + stuck miss)."