From 8858edde054b62581ceec697b89724317c3f3454 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 12 Mar 2026 07:10:45 -0700 Subject: [PATCH] fix: correct chat bubble Y-coordinate projection The camera bakes the Vulkan Y-flip into the projection matrix, so no extra Y-inversion is needed when converting NDC to screen pixels. This matches the convention used by the nameplate and minimap marker code. The old formula double-flipped Y, causing chat bubbles to appear at mirrored positions (e.g. below characters instead of above their heads). --- src/ui/game_screen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 014e719e..9295f71a 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -13748,7 +13748,9 @@ void GameScreen::renderChatBubbles(game::GameHandler& gameHandler) { glm::vec2 ndc(clipPos.x / clipPos.w, clipPos.y / clipPos.w); float screenX = (ndc.x * 0.5f + 0.5f) * screenW; - float screenY = (1.0f - (ndc.y * 0.5f + 0.5f)) * screenH; // Flip Y + // Camera bakes the Vulkan Y-flip into the projection matrix: + // NDC y=-1 is top, y=1 is bottom — same convention as nameplate/minimap projection. + float screenY = (ndc.y * 0.5f + 0.5f) * screenH; // Skip if off-screen if (screenX < -200.0f || screenX > screenW + 200.0f ||