Skip to content

Conversation

zardoy
Copy link
Owner

@zardoy zardoy commented Jun 5, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a heads-up display (HUD) for VR mode, showing real-time player information such as FPS, ping, velocity, coordinates, health, and game mode within the VR environment.
    • The VR HUD automatically appears when entering VR and hides when exiting VR.
  • Bug Fixes

    • Improved management of VR HUD visibility and resource cleanup during VR session changes.

Copy link

codesandbox bot commented Jun 5, 2025

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

Copy link

coderabbitai bot commented Jun 5, 2025

Walkthrough

A new VR heads-up display (HUD) system is added to the VR rendering workflow. The VRHud class is introduced to render player information in VR, and its lifecycle is managed within the VR initialization logic. The HUD is attached, updated, shown, hidden, and disposed of according to the VR session state.

Changes

File(s) Change Summary
renderer/viewer/three/world/vrHud.ts Added new VRHud class for displaying a dynamic HUD in VR, with methods for lifecycle and rendering.
renderer/viewer/three/world/vr.ts Integrated VRHud into VR session lifecycle: creation, attachment, updating, visibility, and disposal.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant VRSystem
    participant VRHud
    participant VRCameraGroup

    User->>VRSystem: Enable VR
    VRSystem->>VRHud: Create VRHud instance
    VRSystem->>VRCameraGroup: Attach VRHud
    VRSystem->>VRHud: Set visible (true)
    loop On each frame
        VRSystem->>VRHud: update()
    end
    User->>VRSystem: End/Disable VR
    VRSystem->>VRHud: Set visible (false)
    VRSystem->>VRCameraGroup: Detach VRHud
    VRSystem->>VRHud: dispose()
Loading

Poem

In VR’s embrace, a HUD appears,
Showing stats as the world steers.
FPS and health in glowing light,
Floating gently, always in sight.
With every frame, the numbers gleam—
VR’s new HUD, a coder’s dream!
🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
renderer/viewer/three/world/vrHud.ts (2)

87-87: Use modern Math.hypot API for velocity calculation.

Math.hypot is more accurate and performant for calculating magnitudes.

-    const vel = Math.sqrt(velocity.x ** 2 + velocity.z ** 2).toFixed(2)
+    const vel = Math.hypot(velocity.x, velocity.z).toFixed(2)
🧰 Tools
🪛 ESLint

[error] 87-87: Prefer Math.hypot(…) over Math.sqrt(…).

(unicorn/prefer-modern-math-apis)


1-129: Fix formatting issues throughout the file.

Multiple trailing spaces and missing spaces before function parentheses need to be addressed for code consistency.

The static analysis tool identified numerous formatting issues. Run your linter/formatter to address:

  • Trailing spaces on multiple lines
  • Missing spaces before function parentheses
  • Missing newline at end of file
+
🧰 Tools
🪛 ESLint

[error] 10-10: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 11-11: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 16-16: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 18-18: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 23-23: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 35-35: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 38-38: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 42-42: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 46-46: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 50-50: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 51-51: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 55-55: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 56-56: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 59-59: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 60-60: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 62-62: Use object destructuring.

(prefer-destructuring)


[error] 63-63: Use object destructuring.

(prefer-destructuring)


[error] 64-64: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 67-67: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 75-75: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 79-79: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 82-82: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 87-87: Prefer Math.hypot(…) over Math.sqrt(…).

(unicorn/prefer-modern-math-apis)


[error] 88-88: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 93-93: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 101-101: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 103-103: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 108-108: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 112-112: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 113-113: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 118-118: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 119-119: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 122-122: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 123-123: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 129-129: Newline required at end of file but not found.

(@stylistic/eol-last)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2e9404 and b9a9dfc.

📒 Files selected for processing (2)
  • renderer/viewer/three/world/vr.ts (4 hunks)
  • renderer/viewer/three/world/vrHud.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
renderer/viewer/three/world/vr.ts (1)
renderer/viewer/three/world/vrHud.ts (1)
  • VRHud (4-129)
🪛 ESLint
renderer/viewer/three/world/vrHud.ts

[error] 10-10: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 11-11: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 16-16: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 18-18: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 23-23: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 35-35: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 38-38: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 42-42: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 46-46: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 50-50: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 51-51: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 55-55: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 56-56: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 59-59: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 60-60: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 62-62: Use object destructuring.

(prefer-destructuring)


[error] 63-63: Use object destructuring.

(prefer-destructuring)


[error] 64-64: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 67-67: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 75-75: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 79-79: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 82-82: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 87-87: Prefer Math.hypot(…) over Math.sqrt(…).

(unicorn/prefer-modern-math-apis)


[error] 88-88: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 93-93: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 101-101: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 103-103: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 108-108: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 112-112: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 113-113: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 118-118: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 119-119: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 122-122: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)


[error] 123-123: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 129-129: Newline required at end of file but not found.

(@stylistic/eol-last)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-deploy
🔇 Additional comments (8)
renderer/viewer/three/world/vr.ts (7)

8-8: LGTM: Clean import addition.

The VRHud import is properly added and will be used consistently throughout the file.


19-20: LGTM: VR HUD instantiation is well-placed.

The HUD is created early in the VR initialization process, which allows it to be used throughout the VR session lifecycle.


44-46: LGTM: Proper HUD cleanup when VR is disabled.

The HUD is correctly detached and hidden when VR is disabled, ensuring proper state management.


209-210: LGTM: HUD updated in the render loop.

The HUD update is correctly placed in the animation loop, ensuring real-time information display during VR sessions.


216-218: LGTM: HUD properly attached when XR session starts.

The HUD is correctly attached to the VR camera and made visible when the XR session begins.


222-224: LGTM: HUD properly detached when XR session ends.

The HUD is correctly detached and hidden when the XR session ends, maintaining proper state consistency.


227-230: LGTM: Proper resource cleanup on abort.

The HUD disposal is correctly handled when the abort signal is triggered, preventing memory leaks.

renderer/viewer/three/world/vrHud.ts (1)

123-128:

❓ Verification inconclusive

Verify complete resource cleanup in dispose method.

Ensure all Three.js resources are properly disposed to prevent memory leaks.

The dispose method looks comprehensive, but let's verify that all resources are properly cleaned up:


🏁 Script executed:

#!/bin/bash
# Description: Check Three.js disposal patterns in the codebase for completeness

# Search for other disposal patterns to ensure consistency
ast-grep --pattern $'dispose() {
  $$$
}'

# Check for canvas cleanup patterns
rg -A 5 "canvas.*remove"

Length of output: 1084


#!/bin/bash
# Locate the vrHud.ts file and print its key sections for review

file=$(fd vrHud.ts)
echo "Inspecting file: $file"

echo -e "\n--- Class Declaration & Constructor ---"
sed -n '1,80p' "$file"

echo -e "\n--- Dispose Method Snippet ---"
sed -n '100,150p' "$file"

#!/bin/bash
# Locate vrHud.ts and inspect resource setup & disposal, plus any event listeners

file=$(fd --basename vrHud.ts)
echo "Inspecting file: $file"

echo -e "\n--- Full dispose() method ---"
sed -n '115,140p' "$file"

echo -e "\n--- Search for event listeners on hudCanvas ---"
rg -n "hudCanvas.*addEventListener" -A2 "$file"

echo -e "\n--- hudCanvas creation & usage ---"
grep -R "hudCanvas" -n "$file"

🏁 Script executed:

#!/bin/bash
# Locate and inspect vrHud.ts for event listeners and animation loops

file=$(fd --exact-name vrHud.ts)
echo "File located at: $file"

echo -e "\n--- dispose() method context (lines 100–160) ---"
sed -n '100,160p' "$file"

echo -e "\n--- Event listener registrations/removals ---"
rg -n 'addEventListener|removeEventListener' "$file"

echo -e "\n--- Animation loop (requestAnimationFrame/cancelAnimationFrame) usage ---"
rg -n 'requestAnimationFrame|cancelAnimationFrame' "$file"

Length of output: 928


Verify event listeners & animation-loop cleanup in vrHud.dispose
Although you’re disposing the texture, geometry, material, and removing the canvas element, please confirm that any of the following are also cleaned up to avoid leaks:

• Cancelling any running requestAnimationFrame loops
• Clearing any setInterval/setTimeout timers
• Removing all hudCanvas (or window/document) event listeners
• Disposing of any additional render targets or helper objects created by vrHud

🧰 Tools
🪛 ESLint

[error] 123-123: Missing space before function parentheses.

(@stylistic/space-before-function-paren)

Comment on lines +97 to +98
const health = bot?.health || 10
const maxHealth = 20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Make health configuration dynamic.

The hard-coded maxHealth = 20 should be retrieved from the game state or configuration.

-    const health = bot?.health || 10
-    const maxHealth = 20
+    const health = bot?.health || 0
+    const maxHealth = bot?.maxHealth || 20
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const health = bot?.health || 10
const maxHealth = 20
const health = bot?.health || 0
const maxHealth = bot?.maxHealth || 20
🤖 Prompt for AI Agents
In renderer/viewer/three/world/vrHud.ts around lines 97 to 98, replace the
hard-coded maxHealth value of 20 with a dynamic value fetched from the game
state or configuration. Identify where the game state or configuration stores
the maximum health value and update the code to retrieve maxHealth from that
source instead of using a fixed number.

Comment on lines +62 to +63
const bot = (window as any).bot
const playerState = this.worldRenderer.playerState
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve type safety for global bot access.

Accessing (window as any).bot bypasses type safety and could lead to runtime errors if bot is undefined or doesn't have expected properties.

-    const bot = (window as any).bot
-    const playerState = this.worldRenderer.playerState
+    const bot = (globalThis as any).bot
+    const playerState = this.worldRenderer.playerState
+    
+    // Add safety checks for bot existence
+    if (!bot) {
+      return // Skip update if bot is not available
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const bot = (window as any).bot
const playerState = this.worldRenderer.playerState
const bot = (globalThis as any).bot
const playerState = this.worldRenderer.playerState
// Add safety checks for bot existence
if (!bot) {
return // Skip update if bot is not available
}
🧰 Tools
🪛 ESLint

[error] 62-62: Use object destructuring.

(prefer-destructuring)


[error] 63-63: Use object destructuring.

(prefer-destructuring)

🤖 Prompt for AI Agents
In renderer/viewer/three/world/vrHud.ts around lines 62 to 63, the code accesses
the global bot object using (window as any).bot, which bypasses type safety and
risks runtime errors if bot is undefined or malformed. To fix this, define a
proper TypeScript interface for the bot object with expected properties, extend
the Window interface to include this bot type, and then access bot via
window.bot with type safety. Additionally, add a runtime check to ensure bot is
defined before using it to prevent potential errors.

Comment on lines +11 to +17
constructor(private worldRenderer: WorldRendererThree) {
// Create canvas for HUD
this.hudCanvas = document.createElement('canvas')
this.hudCanvas.width = 1024
this.hudCanvas.height = 512

this.hudContext = this.hudCanvas.getContext('2d')!
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for canvas context creation.

The non-null assertion on getContext('2d')! could fail if the context cannot be created, leading to runtime errors.

-    this.hudContext = this.hudCanvas.getContext('2d')!
+    const context = this.hudCanvas.getContext('2d')
+    if (!context) {
+      throw new Error('Failed to create 2D canvas context for VR HUD')
+    }
+    this.hudContext = context
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
constructor(private worldRenderer: WorldRendererThree) {
// Create canvas for HUD
this.hudCanvas = document.createElement('canvas')
this.hudCanvas.width = 1024
this.hudCanvas.height = 512
this.hudContext = this.hudCanvas.getContext('2d')!
constructor(private worldRenderer: WorldRendererThree) {
// Create canvas for HUD
this.hudCanvas = document.createElement('canvas')
this.hudCanvas.width = 1024
this.hudCanvas.height = 512
const context = this.hudCanvas.getContext('2d')
if (!context) {
throw new Error('Failed to create 2D canvas context for VR HUD')
}
this.hudContext = context
🧰 Tools
🪛 ESLint

[error] 11-11: Missing space before function parentheses.

(@stylistic/space-before-function-paren)


[error] 16-16: Trailing spaces not allowed.

(@stylistic/no-trailing-spaces)

🤖 Prompt for AI Agents
In renderer/viewer/three/world/vrHud.ts around lines 11 to 17, the code uses a
non-null assertion when getting the 2D context from the canvas, which can cause
runtime errors if the context creation fails. Modify the constructor to check if
the context is null after calling getContext('2d'), and handle the error
appropriately, such as throwing an error or logging a message, to prevent
unexpected failures.

Comment on lines +77 to +78
const fps = Math.round(1000 / this.worldRenderer.renderTimeAvg) || 0
const ping = bot?._client?.latency || 0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add fallback handling for undefined renderTimeAvg.

The FPS calculation could fail if renderTimeAvg is zero or undefined, leading to division by zero or NaN values.

-    const fps = Math.round(1000 / this.worldRenderer.renderTimeAvg) || 0
+    const fps = this.worldRenderer.renderTimeAvg > 0 
+      ? Math.round(1000 / this.worldRenderer.renderTimeAvg) 
+      : 0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fps = Math.round(1000 / this.worldRenderer.renderTimeAvg) || 0
const ping = bot?._client?.latency || 0
const fps = this.worldRenderer.renderTimeAvg > 0
? Math.round(1000 / this.worldRenderer.renderTimeAvg)
: 0
const ping = bot?._client?.latency || 0
🤖 Prompt for AI Agents
In renderer/viewer/three/world/vrHud.ts around lines 77 to 78, the FPS
calculation does not handle cases where renderTimeAvg is zero or undefined,
which can cause division by zero or result in NaN. Add a fallback check to
ensure renderTimeAvg is a positive number before performing the division; if it
is zero or undefined, set FPS to zero to avoid invalid calculations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants