wip(step3): 12.5 cm voxels, fall-through fixed, brick evaluator in game, organic tunnels -- speed gate FAILS

Stopped by the owner's decision (in-game lit captures were eating the round); he judges the look in
game instead.
1. Fall-through with the research field: fixed. Deep drop, gate on: 2 holds (0.50 s), min foot
   clearance +43 cm; gate off: penetrates (-278 cm). Stress fixture offsets converted to metres.
2. VOXEL_SIZE 25 -> 12.5 cm. Physical sizes kept in metres (player, steps, gate, insets, research
   field sizes, dig radii, test thresholds); class defaults that count chunks/voxels doubled
   (ClipRadius 6, RenderDistanceChunks 1536, ViewDistance*, StrateViewMargin 6,
   PawnCollisionRadius 2, SkirtCells 4, EdgeSealThickness 128, decoration spacings, density volume
   res 256). Asset values override these defaults: the owner must double his own.
   Ring scale, six workers, idle, step-2f field before the look changes: 64 m cube (519^3) 4.55 s;
   32 m cube (259^3) 0.95 s.
3. In game: tiles go through the brick evaluator (proved by a log marker); profile switch rebuilds
   the loaded world (~5,800 tiles); full-detail fill 12.4 s after spawn in the visible-window test.
4. Look: round winding tunnels, per-column ellipsoid/lattice caches. All step-2f geometry gates pass
   at 12.5 cm (0 crumbs, 1 solid component per profile, solid share 69-87%). 259^3 ring, six workers:
   1.08-2.02 s (worst HyperComplex) -- the 600 ms gate FAILS. Lit captures failed (hidden/off-screen
   window, then blank frames); not pursued.

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-10-01 21:21:45 +02:00
1 parent ca78352e43
commit bc0f9ee791
33 files changed
+2691 -803

No files matched your search

+47 -24
View File
@@ -388,22 +388,22 @@ public:
* Applies a spherical brush that subtracts density.
*
* @param Position - World-space center of the carve brush
* @param Radius - Brush radius in voxels (default 3)
* @param Radius - Brush radius in voxels (default 6 voxels / 0.75 m at 12.5 cm per voxel)
* @param Strength - How aggressively to carve (default 10, higher = deeper)
*/
UFUNCTION(BlueprintCallable, Category = "Voxel World|Modification")
void CarveAtPosition(FVector Position, float Radius = 3.0f, float Strength = 10.0f);
void CarveAtPosition(FVector Position, float Radius = 6.0f, float Strength = 10.0f);
/**
* Fill terrain at a world position (add rock, seal holes).
* Applies a spherical brush that adds density.
*
* @param Position - World-space center of the fill brush
* @param Radius - Brush radius in voxels (default 3)
* @param Radius - Brush radius in voxels (default 6 voxels / 0.75 m at 12.5 cm per voxel)
* @param Strength - How aggressively to fill (default 10, higher = more solid)
*/
UFUNCTION(BlueprintCallable, Category = "Voxel World|Modification")
void FillAtPosition(FVector Position, float Radius = 3.0f, float Strength = 10.0f);
void FillAtPosition(FVector Position, float Radius = 6.0f, float Strength = 10.0f);
/**
* Box brush carve/fill. Position is world-space (Unreal units); ExtentVoxels is the
@@ -420,10 +420,10 @@ public:
* tube radius in voxels. Great for boring tunnels or laying solid pillars/walls.
*/
UFUNCTION(BlueprintCallable, Category = "Voxel World|Modification")
void CarveCapsule(FVector WorldA, FVector WorldB, float RadiusVoxels = 3.0f, float Strength = 12.0f);
void CarveCapsule(FVector WorldA, FVector WorldB, float RadiusVoxels = 6.0f, float Strength = 12.0f);
UFUNCTION(BlueprintCallable, Category = "Voxel World|Modification")
void FillCapsule(FVector WorldA, FVector WorldB, float RadiusVoxels = 3.0f, float Strength = 12.0f);
void FillCapsule(FVector WorldA, FVector WorldB, float RadiusVoxels = 6.0f, float Strength = 12.0f);
/**
* Apply a fully-specified modification (any shape). Centers/endpoints are expected
@@ -581,6 +581,12 @@ public:
private:
friend class FScopedGenerationPause;
#if WITH_EDITOR
/** Last editor research-field selection applied to loaded tiles. */
int32 AppliedResearchFieldEnabled = INDEX_NONE;
int32 AppliedResearchFieldProfile = INDEX_NONE;
#endif
/** Get/create the shared MID wrapping a base terrain material (binds volume textures + shadow params).
* Returns Base unchanged-wrapped, or nullptr if Base is null. */
UMaterialInstanceDynamic* GetOrCreateTerrainMID(UMaterialInterface* Base);
@@ -713,7 +719,7 @@ public:
/** Brush radius in voxels for the editor buttons. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Editor Brush", meta = (ClampMin = "0.5"))
float EditorBrushRadius = 6.0f;
float EditorBrushRadius = 1.5f * 100.0f / VOXEL_SIZE;
/** Brush strength for the editor buttons (sign forced by the button). */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Editor Brush", meta = (ClampMin = "0.1"))
@@ -934,10 +940,9 @@ public:
FVoxelTileKey* OutPendingTile = nullptr) const;
void RequestCollisionGateSupportTile(const FVoxelTileKey& SupportTile);
/** Hold vertical character motion in gravity-free MOVE_Flying while a swept pending support tile
* intersects the capsule, preserving horizontal movement until collision is ready. Restore the
* previous mode, gravity, and downward speed on release. The world tick is a prerequisite of the
* pawn and movement component so the gate check runs before movement physics. */
/** Hold pawn movement while a swept pending support tile intersects the capsule. Restore the
* previous mode, gravity, and velocity on release. The world tick is a prerequisite of the pawn
* and movement component so the gate check runs before movement physics. */
void UpdatePawnCollisionGate(APawn* Pawn, const FVector& PlayerPosition, float DeltaTime);
void EngagePawnCollisionGate(APawn* Pawn);
void ReleasePawnCollisionGate();
@@ -1165,15 +1170,31 @@ public:
// the camera and smaller test radius are held in memory and never saved to a package.
bool bTestCeilingViewEnabled = false;
bool bTestCeilingCaptureRequested = false;
bool bTestCeilingSecondCaptureRequested = false;
TWeakObjectPtr<ACameraActor> TestCeilingCamera;
FVector TestCeilingCameraWorldPosition = FVector::ZeroVector;
FRotator TestCeilingCameraRotation = FRotator::ZeroRotator;
double TestCeilingViewBeginSeconds = 0.0;
float TestCeilingCaptureDelaySeconds = 18.0f;
float TestCeilingSecondCaptureDelaySeconds = -1.0f;
float TestCeilingCameraMoveSpeedCmPerSecond = 0.0f;
float TestCeilingCameraMoveStartSeconds = 0.0f;
float TestCeilingCameraMoveDurationSeconds = 0.0f;
FVector TestCeilingCameraMoveDirection = FVector::XAxisVector;
double TestCeilingCameraLastMoveSeconds = 0.0;
bool bResearchGamePerfEnabled = false;
double ResearchGamePerfLastFrameSeconds = 0.0;
double ResearchGamePerfMovingSeconds = 0.0;
TArray<double> ResearchGamePerfMovingFrameTimesMs;
bool bTestResearchProfileSwitchConfigured = false;
bool bTestResearchProfileSwitchApplied = false;
float TestResearchProfileSwitchAfterSeconds = -1.0f;
int32 TestResearchProfileSwitchTo = -1;
double TestResearchProfileSwitchBeginSeconds = 0.0;
// Explicit high-speed collision-gate repro. The streamer stays centred at the launch tile while
// the character uses ordinary swept movement across the still-pending desired set. The test
// distinguishes a gate hold from a full horizontal stop so a fall-only gate can be validated.
// the character uses ordinary swept movement toward pending support tiles. The test checks
// that an unresolved collision holds the pawn in place without letting it enter the tile.
bool bHeadlessCollisionGateStressTest = false;
bool bHeadlessCollisionGateStressTestStartPlaced = false;
bool bHeadlessCollisionGateStressTestStarted = false;
@@ -1181,7 +1202,8 @@ public:
bool bHeadlessCollisionGateStressTestFailed = false;
bool bHeadlessCollisionGateStressTestExitRequested = false;
bool bHeadlessCollisionGateStressTestGateWasEngaged = false;
bool bHeadlessCollisionGateStressTestHorizontalGateProbeApplied = false;
bool bHeadlessCollisionGateStressTestFullStopProbeApplied = false;
bool bHeadlessCollisionGateStressTestFullStopProbeObserved = false;
bool bHeadlessCollisionGateStressTestFullStop = false;
bool bHeadlessCollisionGateStressTestStartHeightCrossed = false;
bool bHeadlessCollisionGateStressTestTerrainViolation = false;
@@ -1194,7 +1216,7 @@ public:
bool bHeadlessCollisionGateStressDeepDropPrewarmReported = false;
bool bHeadlessCollisionGateStressDeepDropSurfaceCached = false;
float HeadlessCollisionGateStressTestSpeedCmPerSecond = 6000.0f;
float HeadlessCollisionGateStressTestSpawnHeightVoxels = 10.0f;
float HeadlessCollisionGateStressTestSpawnHeightVoxels = 2.5f * 100.0f / VOXEL_SIZE;
float HeadlessCollisionGateStressTestDurationSeconds = 2.0f;
float HeadlessCollisionGateStressTestTimeoutSeconds = 15.0f;
double HeadlessCollisionGateStressTestBeginSeconds = 0.0;
@@ -1202,6 +1224,7 @@ public:
double HeadlessCollisionGateStressTestLandedSeconds = 0.0;
double HeadlessCollisionGateStressTestGateStartSeconds = 0.0;
double HeadlessCollisionGateStressTestFullStopStartSeconds = 0.0;
double HeadlessCollisionGateStressTestFullStopProbeStartSeconds = 0.0;
double HeadlessCollisionGateStressTestDistanceCm = 0.0;
double HeadlessCollisionGateStressTestGateDistanceCm = 0.0;
double HeadlessCollisionGateStressTestTotalGateDurationSeconds = 0.0;
@@ -1236,10 +1259,10 @@ public:
bool bHeadlessSurfaceFallTestExitRequested = false;
bool bHeadlessSurfaceFallTestPredictionProbeInjected = false;
bool bHeadlessSurfaceFallTestPredictionProbeCleared = false;
float HeadlessSurfaceFallTestSpawnHeightVoxels = 20.0f;
float HeadlessSurfaceFallTestGroundToleranceVoxels = 4.0f;
float HeadlessSurfaceFallTestSpawnHeightVoxels = 5.0f * 100.0f / VOXEL_SIZE;
float HeadlessSurfaceFallTestGroundToleranceVoxels = 1.0f * 100.0f / VOXEL_SIZE;
float HeadlessSurfaceFallTestTimeoutSeconds = 8.0f;
float HeadlessSurfaceFallTestPlayerHalfHeightVoxels = 3.52f;
float HeadlessSurfaceFallTestPlayerHalfHeightVoxels = 88.0f / VOXEL_SIZE;
float HeadlessSurfaceFallTestTerrainZ = 0.0f;
double HeadlessSurfaceFallTestBeginSeconds = 0.0;
double HeadlessSurfaceFallTestStartSeconds = 0.0;
@@ -1279,8 +1302,8 @@ public:
float HeadlessStrateCrossingTestStartDelaySeconds = 1.0f;
float HeadlessStrateCrossingTestTimeoutSeconds = 120.0f;
float HeadlessStrateCrossingTestMaxGateSeconds = 10.0f;
float HeadlessStrateCrossingTestRouteTargetRadiusVoxels = 2.0f;
float HeadlessStrateCrossingTestPlayerHalfHeightVoxels = 3.52f;
float HeadlessStrateCrossingTestRouteTargetRadiusVoxels = 0.5f * 100.0f / VOXEL_SIZE;
float HeadlessStrateCrossingTestPlayerHalfHeightVoxels = 88.0f / VOXEL_SIZE;
float HeadlessStrateCrossingTestMinFloorClearanceVoxels = 1000000.0f;
double HeadlessStrateCrossingTestBeginSeconds = 0.0;
double HeadlessStrateCrossingTestStartSeconds = 0.0;
@@ -1309,8 +1332,7 @@ public:
int32 VisualAuditLODOverlapEvents = 0;
int32 VisualAuditLODOverlapMaxPairs = 0;
// PLAYER COLLISION GATE — only the downward component is held while the level-0 collision body
// beneath the pawn's feet is unresolved. Horizontal movement and player control remain live.
// PLAYER COLLISION GATE — all movement is held while level-0 support collision is unresolved.
TWeakObjectPtr<APawn> PawnTickPrerequisite;
TWeakObjectPtr<UPawnMovementComponent> PawnMovementTickPrerequisite;
TWeakObjectPtr<APawn> CollisionGatedPawn;
@@ -1322,8 +1344,9 @@ public:
uint8 SavedCharacterMovementMode = 0;
uint8 SavedCharacterCustomMovementMode = 0;
bool bSavedCharacterMovementMode = false;
float SavedGateVerticalVelocity = 0.0f;
bool bSavedGateVerticalVelocity = false;
FVector SavedGateVelocity = FVector::ZeroVector;
bool bSavedGateVelocity = false;
bool bSavedPawnMovementWasActive = false;
bool bPawnCollisionGateEngaged = false;
double PawnGateEngagedAtSeconds = 0.0;
bool bPawnGateUnavailableReported = false;