tooling(test): one command to test VoxelForge, with a commandlet-vs-game parity check

Tools/VoxelForgeTest.ps1 runs scenarios (canonical, owner, probe, perf, tests, parity) with the known-good flag sets, isolated user/config dirs, serialized launches, an owner-process guard, and a compact result.json + summary.txt instead of 300 MB logs that Codex has to stream. Answers the owner's question 'can the commandlet reflect in-game behaviour': -gameconfig=1 makes the commandlet use the authored settings, and the parity scenario compares per-tile geometry hashes between the commandlet export and the game's streaming path. Parity PASS: 64 commandlet tiles vs 810 game records, no differing tile.

First run of the tests scenario: 44 tests, 28 pass, 16 fail (8 composer, 6 op-stack equivalence, PassageLandsInOpenSpace, StrateParamBlendCoverage). Triage is the next round: stale expectations from the floor removal and the degrees change, versus real defects, especially the legacy-vs-op-stack equivalence ones.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-18 05:13:16 +02:00
1 parent 1c642fd182
commit a7b8d10de6
10 files changed
+1484 -52

No files matched your search

+27
View File
@@ -5,6 +5,7 @@
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "HAL/CriticalSection.h"
#include <atomic>
#include "VoxelTypes.h"
#include "VoxelGenerator.h"
@@ -137,6 +138,21 @@ struct FChunkResult
TArray<uint8> CaptureGrid;
};
/** One worker-produced mesh identity emitted only by the explicit parity harness. */
struct FVoxelTileHashDumpRecord
{
FVoxelTileKey Tile;
FIntVector OriginVoxels = FIntVector::ZeroValue;
int32 Step = 1;
int32 Cells = 0;
int32 BandChunkLo = MIN_int32;
int32 BandChunkHi = MAX_int32;
bool bSheetTile = false;
bool bEmpty = true;
int32 NumTriangles = 0;
FString GeometryHash;
};
UCLASS()
class VOXELFORGE_API AVoxelWorld : public AActor
{
@@ -512,6 +528,10 @@ private:
void ObserveHeadlessStrateCrossingTest(const FVector& PlayerPosition, APawn* PlayerPawn);
void MaybeFinishHeadlessStrateCrossingTest();
void MaybeFinishHeadlessStreamingTest();
void RecordTileHash(const FVoxelTileKey& Tile, const FIntVector& OriginVoxels,
int32 Step, int32 Cells, int32 BandChunkLo, int32 BandChunkHi,
bool bSheetTile, const FVoxelMeshData& MeshData);
void WriteTileHashDump();
// Packed shader params, recomputed each Tick. ALL meaningful data is in .xyz — a material Vector
// Parameter only delivers float3 (RGB) into a Custom node (the alpha is dropped), so we never use .w.
@@ -977,6 +997,13 @@ public:
double HeadlessStreamingTestBeginSeconds = 0.0;
double HeadlessStreamingTestLastElapsedSeconds = 0.0;
// Explicit parity evidence. Workers append under the lock; EndPlay writes the compact JSON
// after ActiveTaskCount has reached zero, so the dump is a complete worker-side snapshot.
bool bTileHashDumpEnabled = false;
FString TileHashDumpPath;
FCriticalSection TileHashDumpMutex;
TArray<FVoxelTileHashDumpRecord> TileHashDumpRecords;
// Real inter-strate crossing validation. This is enabled only by -voxel.TestStrateCrossing=1;
// the route is copied from UVoxelStrateManager's generated passage and movement is supplied to
// the ordinary pawn movement component. The initial placement onto the upper landing is test