Skip to content

fix(audit): resolve P2 world and RHI issues - #856

Merged
github-actions[bot] merged 3 commits into
devfrom
fix/p2-audit-issues-843-846-848-850
Jul 7, 2026
Merged

fix(audit): resolve P2 world and RHI issues#856
github-actions[bot] merged 3 commits into
devfrom
fix/p2-audit-issues-843-846-848-850

Conversation

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator

Summary

  • Bundle updateGlobalUniforms inputs into rhi.GlobalUniforms and update RHI/Vulkan/call sites
  • Propagate worldgen lighting allocation failures instead of using catch unreachable
  • Move chunk/world telemetry POD structs into world-core and remove world-runtime -> engine-ui dependency
  • Surface world-list save operation failures, log block mutation failures, and track save failures

Verification

  • nix develop --command zig fmt src/ modules/ build.zig
  • nix develop --command zig build test
  • nix develop --command zig build -Dskip-present
  • nix develop --command zig build test-integration
  • Issue-specific greps for 13-arg updateGlobalUniforms, world-runtime engine-ui imports, and targeted silent/unsafe catches

Note: bounded offscreen run command nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=5 timed out before runtime diagnostics at 30s, 60s, and 120s after shader validation output; no crash output was emitted.

Closes #846
Closes #848
Closes #850
Closes #843

@github-actions github-actions Bot added documentation Improvements or additions to documentation engine game build labels Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

PR #856 closes #843, #846, #848, and #850. #846 (bundle updateGlobalUniforms into GlobalUniforms), #848 (propagate lighting allocation failures in flat/shadow-test generators), and #850 (move telemetry POD structs from engine-ui to world-core) are fully implemented. #843 is partially addressed: world-list delete/clear/rename failures now surface an in-screen error banner, and player block mutations are logged, but save-manager failures are only counted/logged in-session and are not persisted or surfaced to the player on next world load as requested by the issue. The diff is a clean, mechanical refactor with good memory hygiene. I verified nix develop --command zig build test passes and zig fmt --check src/ modules/ build.zig is clean; test-integration compiles but skips due to no display.

📌 Review Metadata

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified.

⚠️ High Priority Issues (Should Fix)

None identified.

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM] modules/world-runtime/src/world.zig:649 - Save failures not surfaced to user on world load
Confidence: High
Description: Issue #843 Tier 1 requested a SaveFailureCounter that is checked on next save-session startup and surfaced to the player on world load. The PR adds failed_save_count and logs it inside flush() and autoSave(), but it is never persisted or checked when the world loads. Because takeFailedSaveCount() resets the counter during flush/auto-save, a failure that occurs shortly before exit is invisible in the next session.
Impact: Disk-full / level.dat corruption events remain invisible to the player across sessions, undermining the data-loss observability goal of #843.
Suggested Fix: Either persist the failure count to the save directory and surface a warning badge/dialog on world load, or surface the in-session count via WorldScreen.update() before the player exits (e.g., a non-blocking "N chunks failed to save" badge).

ℹ️ Low Priority Suggestions (Optional)

[LOW] PR verification note — offscreen runtime diagnostic timed out
Confidence: Medium
Description: The author notes that the bounded offscreen run command timed out after shader validation. Issue #846 explicitly requires a headless screenshot baseline before/after to confirm byte-exact visual parity.
Impact: Cannot empirically confirm that bundling uniforms into GlobalUniforms preserved shader uniform layout, although the underlying extern struct in rhi_render_state.zig is unchanged.
Suggested Fix: Run a -Dskip-present headless screenshot comparison against the dev baseline before merging.

[LOW] Missing unit tests for new error paths
Confidence: High
Description: Issue #843 verification requests injected-failure tests for world_list.zig, save_manager.zig, and player.zig; issue #848 requests a std.testing.FailingAllocator test for FlatWorldGenerator / ShadowTestWorldGenerator. No new tests are added.
Impact: The new error-propagation paths are not automatically protected against regression.
Suggested Fix: Add focused tests using a failing allocator or mocked filesystem call to exercise the new catch branches.

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 7 One PR bundles four issues, but each change is focused and coherent.
Open/Closed 8 GlobalUniforms struct eliminates signature churn when adding uniforms.
Liskov Substitution 8 Generator interface change propagated consistently to all implementations.
Interface Segregation 8 No bloated interfaces; telemetry structs relocated cleanly.
Dependency Inversion 9 Fixes the world-runtimeengine-ui leak by moving POD types to world-core.
Average 8.0

🎯 Final Assessment

Overall Confidence Score: 85%

Confidence Breakdown:

  • Code Quality: 85% (clean, idiomatic Zig; proper try/errdefer; atomic counter)
  • Completeness: 80% (three issues fully resolved; [R2-8][P2] Surface silent save/mutation errors to user and log #843 save-failure surfacing partially complete)
  • Risk Level: 20% (mechanical refactor with unchanged GPU extern struct; low regression risk)
  • Test Coverage: 70% (existing tests updated and pass; new error paths lack targeted tests)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0
  • Overall confidence >= 60%
  • No security concerns
  • Tests present and passing (if applicable)

Verdict:

MERGE WITH FIXES

One-sentence explanation: The PR is a high-quality refactor that resolves most of the audit findings, but it should either persist/surface save failures on world load or explicitly scope that follow-up work before merging.

{
  "reviewed_sha": "7f4406145e39324527ed3b5d59b32616ebfed602",
  "critical_issues": 0,
  "high_priority_issues": 0,
  "medium_priority_issues": 1,
  "overall_confidence_score": 85,
  "recommendation": "MERGE_WITH_FIXES"
}

New%20session%20-%202026-07-07T04%3A10%3A41.191Z
opencode session  |  github run

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator Author

Review follow-up addressed in e649c6f.

Changes:

  • Persist save failure counts to save_failures.dat in the save directory.
  • Consume persisted failures through World/WorldScreen and show a non-blocking in-game save warning banner on world load or in-session failure.
  • Added regression tests for SaveManager persisted failure consumption, world-list delete error propagation, FlatWorldGenerator/ShadowTestWorldGenerator failing allocator propagation, and player block mutation error handling.

Verification:

  • nix develop --command zig fmt
  • nix develop --command zig build -Dskip-present
  • nix develop --command zig build test
  • nix develop --command zig build test-integration
  • pre-push hook: formatting + full test suite passed
  • issue-specific greps remained clean

Screenshot verification:

  • Attempted detached dev baseline and PR screenshots with: nix develop --command zig build run -Dskip-present -Dshadow-test-scene -Dscreenshot-path=... -Dscreenshot-frame=180
  • Attempted minimal PR screenshot with: nix develop --command zig build run -Dskip-present -Dshadow-test-scene -Dscreenshot-path=screenshots/pr-shadow-frame1.png -Dscreenshot-frame=1
  • All screenshot/runtime runs timed out after shader validation before producing a screenshot artifact. No screenshot files were created. This matches the earlier offscreen runtime diagnostic timeout behavior in this environment.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

PR #856 closes #843, #846, #848, and #850. The implementation now fully addresses #843 (persisted save-failure counter surfaced on world load via a UI banner), #846 (bundles updateGlobalUniforms into rhi.GlobalUniforms), and #850 (telemetry POD structs moved to world-core). However, #848 is not fully resolved: the flat and shadow-test generators correctly propagate lighting allocation failures with try, but the overworld and overworld-v2 generators still silently swallow lighting failures with catch return; / catch |err| { log; return; }, which in a WorldgenError!void function returns the success value void and leaves chunks marked generated = true with incomplete lighting.

The diff is a clean mechanical refactor with good memory hygiene, atomic counters for failures, and new tests for the fixed error paths. nix develop --command zig build test passes and zig fmt --check is clean.

📌 Review Metadata

[FIXED] Previous issue: Save failures were not persisted or surfaced to the player on next world load; now the save-failure count is persisted to save_failures.dat, consumed on WorldScreen.init, and rendered as a warning banner.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified.

⚠️ High Priority Issues (Should Fix)

[HIGH] modules/worldgen-overworld/src/overworld_generator.zig:231 and modules/worldgen-overworld-v2/src/root.zig:159 - Overworld generators still swallow lighting allocation failures
Confidence: High
Description: The generate signature was changed to WorldgenError!void, but LightingComputer.computeSkylight (and computeBlockLight in overworld) is wrapped in catch return; / catch |err| { log; return; }. In a function returning WorldgenError!void, a bare return; returns the success payload void, so the error is discarded and execution continues to set chunk.generated = true with incomplete lighting data.
Impact: The default overworld generator can produce chunks that are marked generated but have missing/corrupt sky and block lighting, leading to visible artifacts and inconsistent world state.
Suggested Fix: Replace the catch blocks with try (or catch |err| { log.log.errWithTrace(...); return err; } to preserve the existing log) so that lighting allocation failures propagate as WorldgenError.OutOfMemory.

[HIGH] modules/worldgen-overworld/src/overworld_generator.zig:189 - Overworld generator swallows phase_data allocation failure
Confidence: High
Description: const phase_data = self.allocator.create(...) catch return; also returns void (success) on OOM, so the caller sees a successful generation even though the chunk was never filled with terrain.
Impact: Misleading success status; callers may leave a chunk in a half-initialized state.
Suggested Fix: Change to const phase_data = try self.allocator.create(terrain_shape_mod.ChunkPhaseData);.

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM] modules/world-persistence/src/save_manager.zig:258-264 - recordSaveFailure performs unsynchronized file I/O from multiple threads
Confidence: Medium
Description: recordSaveFailure is invoked from the main thread (enqueueSave, deinit) and the save thread (saveThreadFn, processSaveQueue). It writes to the shared save_failures.dat without holding a mutex, so concurrent failure events can race on createFile/writeAll.
Impact: The persisted counter file can become stale or temporarily lost; the in-memory atomic counters remain correct, so the UI warning in the current session is fine, but cross-session persistence may be inaccurate.
Suggested Fix: Add a dedicated mutex to SaveManager to protect save_failures.dat writes, or route all failure recordings through the save thread.

ℹ️ Low Priority Suggestions (Optional)

[LOW] PR verification note — offscreen runtime diagnostic timed out
Confidence: Medium
Description: The author notes that the bounded offscreen run command timed out after shader validation. Issue #846 explicitly requires a headless screenshot baseline before/after to confirm byte-exact visual parity.
Impact: Cannot empirically confirm that bundling uniforms into GlobalUniforms preserved shader uniform layout, although the underlying extern struct in rhi_render_state.zig is unchanged.
Suggested Fix: Run a -Dskip-present headless screenshot comparison against the dev baseline before merging.

[LOW] Missing unit tests for overworld generator error paths
Confidence: High
Description: The PR added std.testing.FailingAllocator tests for FlatWorldGenerator and ShadowTestWorldGenerator, but there are no equivalent tests for OverworldGenerator or OverworldV2Generator despite the high-priority issue above.
Impact: The silent failure paths in the default generator are not automatically protected against regression.
Suggested Fix: Add focused tests using a FailingAllocator against OverworldGenerator.generate and OverworldV2Generator.generate to assert that lighting allocation failures are propagated.

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 7 One PR bundles four issues, but each change is focused and coherent.
Open/Closed 8 GlobalUniforms struct eliminates signature churn when adding uniforms.
Liskov Substitution 7 Generator interface change propagated consistently, but implementations differ in error handling.
Interface Segregation 8 No bloated interfaces; telemetry structs relocated cleanly.
Dependency Inversion 9 Fixes the world-runtimeengine-ui leak by moving POD types to world-core.
Average 7.8

🎯 Final Assessment

Overall Confidence Score: 75%

Confidence Breakdown:

  • Code Quality: 80% (clean, idiomatic Zig; proper try/errdefer; atomic counter)
  • Completeness: 70% (three issues fully resolved; Debug code behind compile-time flag #48 error propagation incomplete for overworld generators)
  • Risk Level: 40% (mechanical refactor with unchanged GPU extern struct, but silent default-generator failure is a data-integrity risk)
  • Test Coverage: 70% (existing tests updated and pass; new tests added for flat/shadow-test, but overworld paths lack coverage)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0
  • Overall confidence >= 60%
  • No security concerns
  • Tests present and passing (if applicable)

Verdict:

MERGE WITH FIXES

One-sentence explanation: The PR is a high-quality refactor that resolves most audit findings, but it must propagate lighting and allocation failures in the overworld generators before merging.

{
  "reviewed_sha": "e649c6fcc08ec8a8b79005bfa67f01bbc9ac54f9",
  "critical_issues": 0,
  "high_priority_issues": 2,
  "medium_priority_issues": 1,
  "overall_confidence_score": 75,
  "recommendation": "MERGE_WITH_FIXES"
}

New%20session%20-%202026-07-07T05%3A00%3A30.076Z
opencode session  |  github run

@MichaelFisher1997

Copy link
Copy Markdown
Collaborator Author

Second review follow-up addressed in b2f5ae1.

Changes:

  • OverworldGenerator now propagates phase_data allocation failure with try.
  • OverworldGenerator now preserves lighting error logs but returns the lighting error instead of success.
  • OverworldV2Generator now propagates skylight allocation failure with try.
  • save_failures.dat persistence is protected by persisted_failed_save_mutex so concurrent main/save-thread failure recordings cannot stale-overwrite the counter.
  • Added focused failing-allocator tests for OverworldGenerator phase allocation, OverworldGenerator lighting allocation, and OverworldV2 lighting allocation.

Verification:

  • nix develop --command zig fmt modules/worldgen-overworld/src/overworld_generator.zig modules/worldgen-overworld-v2/src/root.zig modules/world-persistence/src/save_manager.zig
  • nix develop --command zig build test -- --test-filter "OverworldGenerator propagates"
  • nix develop --command zig build test -- --test-filter "overworld-v2 propagates"
  • nix develop --command zig build test
  • nix develop --command zig build -Dskip-present
  • pre-push hook: formatting + full test suite passed
  • targeted greps for allocation/lighting catch-return patterns are clean

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

PR #856 closes #843, #846, #848, and #850. All four issues are fully addressed in the reviewed commit: GlobalUniforms bundles the RHI uniform inputs (#846), worldgen lighting allocation failures are propagated via WorldgenError in every generator (#848), telemetry POD structs live in world-core removing the world-runtimeengine-ui dependency (#850), and save failures are persisted to save_failures.dat, consumed on world load, and surfaced as a UI banner while world-list operations and block mutations now report errors (#843). The diff is a mechanical, well-tested refactor with no remaining unresolved issues from prior reviews.

📌 Review Metadata

[FIXED] Previous issue: Save failures were not persisted or surfaced to the player on next world load; now persisted via save_failures.dat and consumed in WorldScreen.init/WorldScreen.update.

[FIXED] Previous issue: OverworldGenerator and OverworldV2Generator silently swallowed LightingComputer allocation failures; now both propagate the error with try/return err.

[FIXED] Previous issue: OverworldGenerator swallowed phase_data allocation failure; now uses try.

[FIXED] Previous issue: recordSaveFailure performed unsynchronized file I/O; now protected by persisted_failed_save_mutex.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified.

⚠️ High Priority Issues (Should Fix)

None identified.

💡 Medium Priority Issues (Nice to Fix)

None identified.

ℹ️ Low Priority Suggestions (Optional)

None identified.

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 7 One PR bundles four issues, but each change is focused and coherent.
Open/Closed 8 GlobalUniforms struct eliminates signature churn when adding uniforms.
Liskov Substitution 8 Generator interface change propagated consistently; all implementations now handle errors the same way.
Interface Segregation 8 No bloated interfaces; telemetry structs relocated cleanly.
Dependency Inversion 9 Fixes the world-runtimeengine-ui leak by moving POD types to world-core.
Average 8.0

🎯 Final Assessment

Overall Confidence Score: 90%

Confidence Breakdown:

  • Code Quality: 90% (clean, idiomatic Zig; proper try/errdefer; atomic counters; mutex-protected persistence)
  • Completeness: 90% (all four linked issues fully implemented; follow-up fixes address prior review findings)
  • Risk Level: 15% (mechanical refactor with unchanged GPU extern struct; low regression risk)
  • Test Coverage: 85% (existing tests updated; new failing-allocator tests for flat, shadow-test, overworld, and overworld-v2; world-list and player error tests added)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0
  • Overall confidence >= 60%
  • No security concerns
  • Tests present and passing (if applicable)

Verdict:

MERGE

One-sentence explanation: The PR resolves all four audit issues, fixes every finding from prior automated reviews, and passes formatting, unit tests, and headless build verification.

{
  "reviewed_sha": "b2f5ae1e0550b06b99187ac161c216efbb8612b2",
  "critical_issues": 0,
  "high_priority_issues": 0,
  "medium_priority_issues": 0,
  "overall_confidence_score": 90,
  "recommendation": "MERGE"
}

New%20session%20-%202026-07-07T05%3A23%3A37.418Z
opencode session  |  github run

@github-actions
github-actions Bot merged commit 7f7ff7d into dev Jul 7, 2026
8 checks passed
@MichaelFisher1997
MichaelFisher1997 deleted the fix/p2-audit-issues-843-846-848-850 branch July 7, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build documentation Improvements or additions to documentation engine game

Projects

None yet

1 participant