wip(assembler): M3 round 3 -- separated islands + Unreal island route (owner build 18:46)

Islands read as separate (91.89% open sky at mid-height), underside cavity closed,
rim teeth were capture shading. Island manifest import + BuildHost proof passed on the
pre-cache tree; M1 SurfaceWorld and M2 V1/V2 gates passed.

Known open: final XY-column cache compiled in the owner build but is unverified;
island LOD0 p95 ~155 ms misses the 133 ms sprint deadline (legacy ~43 ms); the island
manifest only fits the BuildHost fixture layout (owner's world: Core init fails,
empty world) -> round 4 builds plans inside Unreal.

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-10 20:53:03 +02:00
1 parent 4afea7c802
commit 48fa028086
37 files changed
+3788 -107

No files matched your search

@@ -128,6 +128,110 @@ struct FCoreSurfaceSnapshot
}
};
struct FCoreFloatingIslandFieldSnapshot
{
VoxelForgeCore::FloatingIslandRecipeV1 Recipe;
VoxelForgeCore::FloatingIslandPlanV1 Plan;
TUniquePtr<VoxelForgeCore::FloatingIslandFieldV1> Field;
};
struct FCoreFloatingIslandSnapshot
{
TMap<int32, TSharedPtr<const FCoreFloatingIslandFieldSnapshot, ESPMode::ThreadSafe>> Fields;
const FCoreFloatingIslandFieldSnapshot* FindField(int32 StrateIndex) const
{
const auto* Found = Fields.Find(StrateIndex);
return Found != nullptr && Found->IsValid() ? Found->Get() : nullptr;
}
bool GetDensity(int32 StrateIndex, float LegacyVoxelX, float LegacyVoxelY,
float LegacyVoxelZ, float& OutDensity) const
{
OutDensity = 1.0f;
const FCoreFloatingIslandFieldSnapshot* Entry = FindField(StrateIndex);
if (Entry == nullptr || !Entry->Field.IsValid()
|| !FMath::IsFinite(LegacyVoxelX) || !FMath::IsFinite(LegacyVoxelY)
|| !FMath::IsFinite(LegacyVoxelZ))
{
return false;
}
// A legacy voxel is 128 subvoxels at 12.5 cm; Core field distances are converted back to legacy units.
// Un voxel historique vaut 128 sous-voxels a 12,5 cm ; la distance Core revient en unites historiques.
constexpr double LegacyVoxelSubvoxels = 128.0;
constexpr double MaximumInput = static_cast<double>(MAX_int64) / LegacyVoxelSubvoxels;
if (FMath::Abs(static_cast<double>(LegacyVoxelX)) > MaximumInput
|| FMath::Abs(static_cast<double>(LegacyVoxelY)) > MaximumInput
|| FMath::Abs(static_cast<double>(LegacyVoxelZ)) > MaximumInput)
{
return false;
}
const int64 Density = Entry->Field->densitySubvoxels(
static_cast<int64>(std::llround(static_cast<double>(LegacyVoxelX) * LegacyVoxelSubvoxels)),
static_cast<int64>(std::llround(static_cast<double>(LegacyVoxelY) * LegacyVoxelSubvoxels)),
static_cast<int64>(std::llround(static_cast<double>(LegacyVoxelZ) * LegacyVoxelSubvoxels)));
OutDensity = static_cast<float>(static_cast<double>(Density) / LegacyVoxelSubvoxels);
return FMath::IsFinite(OutDensity);
}
bool GetTopAnchor(int32 StrateIndex, const FVector2D& LocalXYCm,
float& OutGroundLocalZCm) const
{
OutGroundLocalZCm = 0.0f;
const FCoreFloatingIslandFieldSnapshot* Entry = FindField(StrateIndex);
if (Entry == nullptr || !Entry->Field.IsValid()
|| Entry->Plan.islands.empty()
|| !FMath::IsFinite(LocalXYCm.X) || !FMath::IsFinite(LocalXYCm.Y))
{
return false;
}
constexpr double SubvoxelsPerCoreVoxel = 256.0;
constexpr double CentimetersPerCoreVoxel = 25.0;
const double XSubvoxels = static_cast<double>(LocalXYCm.X)
* SubvoxelsPerCoreVoxel / CentimetersPerCoreVoxel;
const double YSubvoxels = static_cast<double>(LocalXYCm.Y)
* SubvoxelsPerCoreVoxel / CentimetersPerCoreVoxel;
constexpr double MaximumInput = static_cast<double>(MAX_int64) - 1024.0;
if (FMath::Abs(XSubvoxels) > MaximumInput || FMath::Abs(YSubvoxels) > MaximumInput)
{
return false;
}
const int64 X = static_cast<int64>(std::llround(XSubvoxels));
const int64 Y = static_cast<int64>(std::llround(YSubvoxels));
int64 SearchTop = Entry->Plan.islands.front().topZSubvoxels;
int64 SearchBottom = Entry->Plan.islands.front().bottomZSubvoxels;
for (const auto& Island : Entry->Plan.islands)
{
SearchTop = FMath::Max(SearchTop, Island.topZSubvoxels);
SearchBottom = FMath::Min(SearchBottom, Island.bottomZSubvoxels);
}
SearchTop += 4 * 256;
SearchBottom -= 4 * 256;
constexpr int64 ScanStepSubvoxels = 128;
int64 PreviousZ = SearchTop;
int64 PreviousDensity = Entry->Field->densitySubvoxels(X, Y, PreviousZ);
if (PreviousDensity < 0) return false;
for (int64 Z = SearchTop - ScanStepSubvoxels; Z >= SearchBottom; Z -= ScanStepSubvoxels)
{
const int64 Density = Entry->Field->densitySubvoxels(X, Y, Z);
if (PreviousDensity >= 0 && Density < 0)
{
const double Denominator = static_cast<double>(PreviousDensity - Density);
const double Alpha = Denominator > 0.0
? static_cast<double>(PreviousDensity) / Denominator : 0.5;
const double SurfaceSubvoxels = static_cast<double>(PreviousZ)
+ static_cast<double>(Z - PreviousZ) * Alpha;
OutGroundLocalZCm = static_cast<float>(SurfaceSubvoxels
* CentimetersPerCoreVoxel / SubvoxelsPerCoreVoxel);
return FMath::IsFinite(OutGroundLocalZCm);
}
PreviousZ = Z;
PreviousDensity = Density;
}
return false;
}
};
// Global safety cap on spawned decoration ACTORS per cell (across all entries).
// HISM instances are exempt — they're batched render data, capped per entry by MaxPerChunk.
static constexpr int32 GMaxDecorationActorsPerCell = 400;
@@ -174,6 +278,7 @@ void UVoxelContentManager::Initialize(AActor* InOwner, UVoxelStrateManager* InSt
Settings = InSettings;
Seed = InSeed;
NativeSurfaceSnapshot.Reset();
NativeFloatingIslandSnapshot.Reset();
if (Settings)
{
@@ -196,6 +301,33 @@ void UVoxelContentManager::Initialize(AActor* InOwner, UVoxelStrateManager* InSt
Snapshot->Plans.Add(Plan.strateIndex, Plan);
}
NativeSurfaceSnapshot = Snapshot;
if (!Manifest->floatingIslands.empty())
{
TSharedPtr<FCoreFloatingIslandSnapshot, ESPMode::ThreadSafe> IslandSnapshot =
MakeShared<FCoreFloatingIslandSnapshot, ESPMode::ThreadSafe>();
for (const auto& IslandPlan : Manifest->floatingIslands)
{
TSharedPtr<FCoreFloatingIslandFieldSnapshot, ESPMode::ThreadSafe> Entry =
MakeShared<FCoreFloatingIslandFieldSnapshot, ESPMode::ThreadSafe>();
Entry->Recipe = IslandPlan.manifest.recipe;
Entry->Plan = IslandPlan.manifest.plan;
Entry->Field = MakeUnique<VoxelForgeCore::FloatingIslandFieldV1>(
Entry->Recipe, Entry->Plan);
if (!Entry->Field->isValid())
{
UE_LOG(LogTemp, Warning,
TEXT("[VoxelContentManager] Core floating-island field rejected strate %d."),
IslandPlan.strateIndex);
continue;
}
IslandSnapshot->Fields.Add(IslandPlan.strateIndex, Entry);
}
if (!IslandSnapshot->Fields.IsEmpty())
{
NativeFloatingIslandSnapshot = IslandSnapshot;
}
}
}
else
{
@@ -244,6 +376,66 @@ bool UVoxelContentManager::QueryNativeSurfaceAnchors(
return true;
}
bool UVoxelContentManager::QueryNativeFloatingIslandAnchor(
int32 StrateIndex, const FVector2D& LocalXYCm, float& OutGroundLocalZCm) const
{
OutGroundLocalZCm = 0.0f;
const AVoxelWorld* VoxelWorld = Cast<AVoxelWorld>(Owner.Get());
if (VoxelWorld == nullptr || !VoxelWorld->bUseVoxelForgeCore
|| !NativeFloatingIslandSnapshot.IsValid())
{
return false;
}
return NativeFloatingIslandSnapshot->GetTopAnchor(
StrateIndex, LocalXYCm, OutGroundLocalZCm);
}
bool UVoxelContentManager::QueryStrateWaterAnchor(
int32 StrateIndex, bool& bOutHasWater, float& OutWaterLocalZCm) const
{
bOutHasWater = false;
OutWaterLocalZCm = -FLT_MAX;
const AVoxelWorld* VoxelWorld = Cast<AVoxelWorld>(Owner.Get());
if (VoxelWorld == nullptr || StrateManager == nullptr)
{
return false;
}
if (VoxelWorld->bUseVoxelForgeCore && NativeSurfaceSnapshot.IsValid())
{
bool bHasPlan = false;
bool bEnabled = false;
float NativeWaterLocalZCm = -FLT_MAX;
if (NativeSurfaceSnapshot->GetWater(
StrateIndex, bHasPlan, bEnabled, NativeWaterLocalZCm) && bHasPlan)
{
bOutHasWater = bEnabled;
OutWaterLocalZCm = bEnabled ? NativeWaterLocalZCm : -FLT_MAX;
return true;
}
}
for (const FStrateSlot& Slot : StrateManager->GetLayout())
{
if (Slot.StrateIndex != StrateIndex)
{
continue;
}
const int32 MidChunkZ = Slot.BottomChunkZ
+ (Slot.TopChunkZ - Slot.BottomChunkZ) / 2;
const float ManagerWaterVoxelZ = StrateManager->GetWaterLevelWorldZForChunk(
FIntVector(0, 0, MidChunkZ));
if (ManagerWaterVoxelZ != -FLT_MAX)
{
bOutHasWater = true;
const float ManagerWaterLocalZCm = ManagerWaterVoxelZ * VOXEL_SIZE;
OutWaterLocalZCm = VoxelWorld->FromStrateManagerLocalZ(ManagerWaterLocalZCm);
}
return true;
}
return false;
}
void UVoxelContentManager::BeginDestroy()
{
// Backstop: stop any worker from touching us. EndPlay → NotifyShutdown should have already drained.
@@ -395,6 +587,11 @@ void UVoxelContentManager::UpdateDecorations(const FVector& PlayerWorldPos)
&& CurrentCtx.bSurfaceWorld
&& CurrentCtx.NativeSurface.IsValid()
&& CurrentCtx.NativeSurface->FindPlan(StrateIndex) != nullptr;
CurrentCtx.NativeIslands = NativeFloatingIslandSnapshot;
CurrentCtx.bNativeFloatingIslands = VoxelWorld != nullptr && VoxelWorld->bUseVoxelForgeCore
&& StrateManager->GetGeneratorTypeForChunk(RepChunk) == ECaveGeneratorType::FloatingIslands
&& CurrentCtx.NativeIslands.IsValid()
&& CurrentCtx.NativeIslands->FindField(StrateIndex) != nullptr;
{
bool bHasNativePlan = false;
bool bNativeWaterEnabled = false;
@@ -710,7 +907,17 @@ void UVoxelContentManager::BuildCellSpawns(const UVoxelGenerator* Gen, const FTr
FChunkBiomeCache BiomeCache;
const bool bHasBiomes = Ctx.BiomeCtx.IsValid();
auto D = [&](float VX, float VY, float VZ) { return Gen->GetDensityAt(VX, VY, VZ); };
auto D = [&](float VX, float VY, float VZ)
{
if (Ctx.bNativeFloatingIslands && Ctx.NativeIslands.IsValid())
{
float NativeDensity = 1.0f;
if (Ctx.NativeIslands->GetDensity(Ctx.StrateIndex, VX, VY, VZ, NativeDensity))
return NativeDensity;
return 1.0f;
}
return Gen->GetDensityAt(VX, VY, VZ);
};
auto GetSurface = [&](float VX, float VY, float& OutGround, float& OutCap)
{
if (Ctx.bNativeSurface && Ctx.NativeSurface.IsValid())
@@ -1338,6 +1545,21 @@ bool UVoxelContentManager::FindLandmarkColumn(const UVoxelGenerator* Gen, const
{
if (!Gen) return false;
const auto Density = [&](float SampleX, float SampleY, float SampleZ)
{
if (Ctx.bNativeFloatingIslands && Ctx.NativeIslands.IsValid())
{
float NativeDensity = 1.0f;
if (Ctx.NativeIslands->GetDensity(
Ctx.StrateIndex, SampleX, SampleY, SampleZ, NativeDensity))
{
return NativeDensity;
}
return 1.0f;
}
return Gen->GetDensityAt(SampleX, SampleY, SampleZ);
};
if (Ctx.bSurfaceWorld)
{
float hC, cC;
@@ -1368,7 +1590,7 @@ bool UVoxelContentManager::FindLandmarkColumn(const UVoxelGenerator* Gen, const
}
// Floor / Wall / Any → the terrain top.
if (!(hC >= Ctx.BottomVoxelZ && hC <= Ctx.TopVoxelZ)) return false;
if (!Ctx.bNativeSurface && Gen->GetDensityAt(VX, VY, hC) > 0.5f) return false;
if (!Ctx.bNativeSurface && Density(VX, VY, hC) > 0.5f) return false;
float d, hXp, hXm, hYp, hYm;
GetSurface(VX + 1.0f, VY, hXp, d);
GetSurface(VX - 1.0f, VY, hXm, d);
@@ -1384,19 +1606,19 @@ bool UVoxelContentManager::FindLandmarkColumn(const UVoxelGenerator* Gen, const
// Bounded by ColDepth like the decoration march (this runs SYNCHRONOUSLY on the game thread):
// once past open air, a solid run longer than ColDepth means bedrock down to the strate floor —
// stop instead of paying GetDensityAt across the whole remaining band.
float PrevD = Gen->GetDensityAt(VX, VY, Ctx.TopVoxelZ);
float PrevD = Density(VX, VY, Ctx.TopVoxelZ);
bool bSeenAir = (PrevD >= 0.0f);
float SolidRun = 0.0f;
for (float Z = Ctx.TopVoxelZ - Step; Z >= Ctx.BottomVoxelZ; Z -= Step)
{
const float Dz = Gen->GetDensityAt(VX, VY, Z);
const float Dz = Density(VX, VY, Z);
if ((PrevD >= 0.0f) != (Dz >= 0.0f)) // air ↔ solid crossing
{
float ZLo = Z, ZHi = Z + Step, DHi = PrevD, DLo = Dz;
for (int32 It = 0; It < 4; ++It)
{
const float ZM = 0.5f * (ZLo + ZHi);
const float DM = Gen->GetDensityAt(VX, VY, ZM);
const float DM = Density(VX, VY, ZM);
if ((DM >= 0.0f) == (DHi >= 0.0f)) { ZHi = ZM; DHi = DM; }
else { ZLo = ZM; DLo = DM; }
}
@@ -1405,9 +1627,9 @@ bool UVoxelContentManager::FindLandmarkColumn(const UVoxelGenerator* Gen, const
const float ZC = ZLo + (ZHi - ZLo) * T;
const FVector LocalGrad(
Gen->GetDensityAt(VX + 1.0f, VY, ZC) - Gen->GetDensityAt(VX - 1.0f, VY, ZC),
Gen->GetDensityAt(VX, VY + 1.0f, ZC) - Gen->GetDensityAt(VX, VY - 1.0f, ZC),
Gen->GetDensityAt(VX, VY, ZC + 1.0f) - Gen->GetDensityAt(VX, VY, ZC - 1.0f));
Density(VX + 1.0f, VY, ZC) - Density(VX - 1.0f, VY, ZC),
Density(VX, VY + 1.0f, ZC) - Density(VX, VY - 1.0f, ZC),
Density(VX, VY, ZC + 1.0f) - Density(VX, VY, ZC - 1.0f));
FVector N = OwnerXf.TransformVectorNoScale(LocalGrad).GetSafeNormal();
if (N.IsNearlyZero()) N = FVector::UpVector;
@@ -18,6 +18,7 @@ namespace
{
using FCoreJsonWriter = TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>;
constexpr double CoreVoxelSizeCm = 25.0;
constexpr double OwnerVoxelSizeCm = 12.5;
TSharedPtr<FJsonValue> SerializeCoreStruct(
const UStruct* Type, const void* Data, TSet<const UObject*>& ActiveObjects,
@@ -309,20 +310,32 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
}
int32 SurfaceSlotCount = 0;
int32 FloatingIslandSlotCount = 0;
for (const FStrateSlot& Slot : StrateManager->GetLayout())
{
if (Slot.Definition != nullptr
&& Slot.Definition->GeneratorType == ECaveGeneratorType::SurfaceWorld)
if (Slot.Definition == nullptr)
{
continue;
}
const ECaveGeneratorType Archetype = StrateManager->GetGeneratorTypeForChunk(
FIntVector(0, 0, Slot.TopChunkZ));
if (Archetype == ECaveGeneratorType::SurfaceWorld)
{
++SurfaceSlotCount;
}
else if (Archetype == ECaveGeneratorType::FloatingIslands)
{
++FloatingIslandSlotCount;
}
}
if (SurfaceSlotCount == 0
|| Manifest->plan.strates.size() != static_cast<std::size_t>(SurfaceSlotCount))
if (Manifest->plan.strates.size() != static_cast<std::size_t>(SurfaceSlotCount)
|| Manifest->floatingIslands.size() != static_cast<std::size_t>(FloatingIslandSlotCount))
{
OutError = FString::Printf(
TEXT("Core world assembly has %d plans for %d resolved SurfaceWorld strates."),
static_cast<int32>(Manifest->plan.strates.size()), SurfaceSlotCount);
TEXT("Core world assembly has %d SurfaceWorld and %d floating-island plans for %d resolved SurfaceWorld and %d FloatingIslands strates."),
static_cast<int32>(Manifest->plan.strates.size()),
static_cast<int32>(Manifest->floatingIslands.size()),
SurfaceSlotCount, FloatingIslandSlotCount);
return false;
}
@@ -332,7 +345,8 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
const FStrateSlot* MatchingSlot = StrateManager->GetLayout().FindByPredicate(
[&Plan](const FStrateSlot& Slot) { return Slot.StrateIndex == Plan.strateIndex; });
if (MatchingSlot == nullptr || MatchingSlot->Definition == nullptr
|| MatchingSlot->Definition->GeneratorType != ECaveGeneratorType::SurfaceWorld
|| StrateManager->GetGeneratorTypeForChunk(FIntVector(0, 0, Plan.topChunkZ))
!= ECaveGeneratorType::SurfaceWorld
|| MatchingSlot->TopChunkZ != Plan.topChunkZ
|| MatchingSlot->BottomChunkZ != Plan.bottomChunkZ
|| MatchedStrateIndices.Contains(Plan.strateIndex))
@@ -345,6 +359,25 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
MatchedStrateIndices.Add(Plan.strateIndex);
}
for (const VoxelForgeCore::WorldAssemblyFloatingIslandPlanV1& Plan : Manifest->floatingIslands)
{
const FStrateSlot* MatchingSlot = StrateManager->GetLayout().FindByPredicate(
[&Plan](const FStrateSlot& Slot) { return Slot.StrateIndex == Plan.strateIndex; });
if (MatchingSlot == nullptr || MatchingSlot->Definition == nullptr
|| StrateManager->GetGeneratorTypeForChunk(FIntVector(0, 0, Plan.topChunkZ))
!= ECaveGeneratorType::FloatingIslands
|| MatchingSlot->TopChunkZ != Plan.topChunkZ
|| MatchingSlot->BottomChunkZ != Plan.bottomChunkZ
|| MatchedStrateIndices.Contains(Plan.strateIndex))
{
OutError = FString::Printf(
TEXT("Core floating-island plan for strate %d does not exactly match a unique resolved FloatingIslands slot."),
Plan.strateIndex);
return false;
}
MatchedStrateIndices.Add(Plan.strateIndex);
}
const std::string CanonicalJson = Manifest->ToJson();
if (CanonicalJson.empty())
{
@@ -403,6 +436,9 @@ bool VoxelForgeCoreAdapter::SerializeResolvedWorld(
Root->SetNumberField(TEXT("schema_version"), 1);
Root->SetStringField(TEXT("source"), TEXT("VoxelForge Runtime Core snapshot"));
Root->SetNumberField(TEXT("voxel_size_cm"), CoreVoxelSizeCm);
Root->SetNumberField(TEXT("owner_voxel_size_cm"), OwnerVoxelSizeCm);
Root->SetNumberField(TEXT("core_voxel_size_cm"), CoreVoxelSizeCm);
Root->SetNumberField(TEXT("owner_to_core_length_scale"), OwnerVoxelSizeCm / CoreVoxelSizeCm);
Root->SetNumberField(TEXT("seed"), Seed);
Root->SetBoolField(TEXT("open_surface_entry"), Settings->bOpenSurfaceEntry);
Root->SetNumberField(TEXT("origin_spine_radius"), OriginSpineRadius);
+4 -2
View File
@@ -96,8 +96,10 @@ bool UVoxelSettings::SetWorldAssemblyManifestJson(const FString& InJson, FString
WorldAssemblyManifestHash = FString::Printf(TEXT("%016llx"),
static_cast<unsigned long long>(Manifest->contentHash));
MarkPackageDirty();
OutReport = FString::Printf(TEXT("imported native world assembly %s (%d stratum plans)"),
*WorldAssemblyManifestHash, static_cast<int32>(Manifest->plan.strates.size()));
OutReport = FString::Printf(
TEXT("imported native world assembly %s (%d SurfaceWorld plans, %d floating-island plans)"),
*WorldAssemblyManifestHash, static_cast<int32>(Manifest->plan.strates.size()),
static_cast<int32>(Manifest->floatingIslands.size()));
return true;
}
+5 -4
View File
@@ -7264,11 +7264,12 @@ bool AVoxelWorld::InitializeVoxelForgeCoreWorld()
if (const VoxelForgeCore::WorldAssemblyManifest* Assembly = Snapshot->worldAssembly())
{
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeCoreRuntime] world_assembly_hash=%016llx recipe_hash=%016llx plan_hash=%016llx strates=%d"),
TEXT("[VoxelForgeCoreRuntime] world_assembly_hash=%016llx recipe_hash=%016llx plan_hash=%016llx surface_strates=%d island_strates=%d"),
static_cast<unsigned long long>(Assembly->contentHash),
static_cast<unsigned long long>(Assembly->recipe.contentHash),
static_cast<unsigned long long>(Assembly->plan.contentHash),
static_cast<int32>(Assembly->plan.strates.size()));
static_cast<int32>(Assembly->plan.strates.size()),
static_cast<int32>(Assembly->floatingIslands.size()));
}
TSharedPtr<FVoxelForgeCoreRuntimeState, ESPMode::ThreadSafe> State =
@@ -13285,8 +13286,8 @@ int32 AVoxelWorld::GetCurrentSeason() const
FString AVoxelWorld::GetCurrentSeasonContentHash() const
{
const FString SeasonHash = StrateManager ? StrateManager->GetSeasonContentHash() : FString();
// Only active Core generation includes the optional native surface manifest in world identity.
// Seul le Core actif inclut le manifeste de surface natif dans l'identite du monde.
// Only active Core generation includes the optional native world assembly in world identity.
// Seul le Core actif inclut l'assemblage natif facultatif dans l'identite du monde.
if (!Settings || !bUseVoxelForgeCore)
{
return SeasonHash;