Conversation
Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/e7dc0226-fa25-488a-a713-47a2399e85cd Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
…plit) Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/e7dc0226-fa25-488a-a713-47a2399e85cd Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
…, and safe tile iteration Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/ad42dcb0-9f21-4451-bc76-4eae16616da5 Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/bb692ff9-eb4b-4e04-9a86-1f0552306666 Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/bc6011cc-b6dd-4d83-8400-f901f06940fd Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
|
/gemini review |
…toggle Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/bc6011cc-b6dd-4d83-8400-f901f06940fd Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive mini-game system called "Arcade," featuring three games: Space Invaders, Code Breaker, and Developer Duel. It includes a centralized GameManager for lifecycle and state management, an XP and achievement system integrated with the existing site, and a dedicated Arcade page. The review feedback focuses on improving performance and maintainability, specifically by dynamically loading game scripts, avoiding global namespace pollution, and replacing inline styles with Tailwind classes. There are also suggestions to optimize game loops by caching DOM queries and reducing event listeners, as well as standardizing variable declarations and error handling.
| <script src="/assets/js/games/config.js"></script> | ||
| <script src="/assets/js/games/game-manager.js"></script> | ||
| <script src="/assets/js/games/space-invaders.js"></script> | ||
| <script src="/assets/js/games/code-breaker.js"></script> | ||
| <script src="/assets/js/games/dev-duel.js"></script> |
| var instance = new Phaser.Game(config); | ||
| GameManager.instances[GAME_ID] = instance; |
| closeBtn.style.cssText = | ||
| "position:absolute;top:1rem;right:1rem;padding:0.5rem 1rem;" + | ||
| "background:rgba(255,255,255,0.1);color:#fff;border:1px solid rgba(255,255,255,0.2);" + | ||
| "border-radius:0.5rem;cursor:pointer;font-weight:bold;font-size:0.75rem;z-index:1;"; |
There was a problem hiding this comment.
Instead of using style.cssText, apply styles using Tailwind utility classes via the className property to maintain consistency.
| closeBtn.style.cssText = | |
| "position:absolute;top:1rem;right:1rem;padding:0.5rem 1rem;" + | |
| "background:rgba(255,255,255,0.1);color:#fff;border:1px solid rgba(255,255,255,0.2);" + | |
| "border-radius:0.5rem;cursor:pointer;font-weight:bold;font-size:0.75rem;z-index:1;"; | |
| closeBtn.className = "absolute top-4 right-4 py-2 px-4 bg-white/10 text-white border border-white/20 rounded-lg cursor-pointer font-bold text-xs z-10"; |
| var icons = { first_blood: "🩸", code_wizard: "🧙", duelist: "⚔️" }; | ||
| var labels = { first_blood: "First Blood", code_wizard: "Code Wizard", duelist: "Duelist" }; |
| (function refreshGameStats() { | ||
| // High scores | ||
| var hs = { | ||
| "hs-si": localStorage.getItem("hs_space-invaders"), | ||
| "hs-cb": localStorage.getItem("hs_code-breaker"), | ||
| "hs-dd": localStorage.getItem("hs_dev-duel"), | ||
| }; | ||
| Object.keys(hs).forEach(function (id) { | ||
| var el = document.getElementById(id); | ||
| if (el && hs[id]) el.textContent = hs[id]; | ||
| }); | ||
|
|
||
| // Achievement badges | ||
| var badgeContainer = document.getElementById("achievement-badges"); | ||
| if (!badgeContainer) return; | ||
| var earned = {}; | ||
| try { earned = JSON.parse(localStorage.getItem("gameAchievements") || "{}"); } catch (_) {} | ||
| var icons = { first_blood: "🩸", code_wizard: "🧙", duelist: "⚔️" }; | ||
| var labels = { first_blood: "First Blood", code_wizard: "Code Wizard", duelist: "Duelist" }; | ||
| Object.keys(icons).forEach(function (id) { | ||
| if (earned[id]) { | ||
| var badge = document.createElement("span"); | ||
| badge.title = labels[id]; | ||
| badge.className = "text-sm cursor-help"; | ||
| badge.textContent = icons[id]; | ||
| badgeContainer.appendChild(badge); | ||
| } | ||
| }); | ||
| })(); |
| window.PROFILE_NAME = "{{ name }}"; | ||
| window.PROFILE_SKILLS = "{{ languages | default('') }}".trim().split(/\s+/).filter(Boolean); |
There was a problem hiding this comment.
Attaching multiple properties directly to the window object can lead to global namespace pollution and potential naming conflicts. It's a better practice to group these properties under a single, namespaced object. For example: window.PROFILE_DATA = { ... };. You would then need to update the onclick handler on line 100 to use this new object.
| Object.assign(canvas.style, { | ||
| position: "fixed", | ||
| top: "0", | ||
| left: "0", | ||
| width: "100vw", | ||
| height: "100vh", | ||
| zIndex: "10000", | ||
| pointerEvents: "none", // non-interactive until explosion is done | ||
| }); |
| const XP_SPACE_INVADERS_WIN = 200; // Defeat all Space Invaders | ||
| const XP_CODE_BREAKER_WIN = 100; // Win a Code Breaker round | ||
| const XP_DEV_DUEL_PLAY = 25; // Play a Developer Duel | ||
| const XP_DEV_DUEL_WIN = 50; // Win a Developer Duel |
| document.addEventListener("DOMContentLoaded", function () { | ||
| // Populate high scores | ||
| var scores = { | ||
| "space-invaders": document.getElementById("hs-space-invaders"), | ||
| "code-breaker": document.getElementById("hs-code-breaker"), | ||
| "dev-duel": document.getElementById("hs-dev-duel"), | ||
| }; | ||
| Object.keys(scores).forEach(function (id) { | ||
| var val = parseInt(localStorage.getItem("hs_" + id)) || 0; | ||
| if (scores[id]) scores[id].textContent = val > 0 ? val : "—"; | ||
| }); | ||
|
|
||
| // Populate achievements | ||
| var achievements = {}; | ||
| try { | ||
| achievements = JSON.parse(localStorage.getItem("gameAchievements") || "{}"); | ||
| } catch (_) {} | ||
|
|
||
| document.querySelectorAll(".achievement-card").forEach(function (card) { | ||
| var id = card.dataset.id; | ||
| var statusEl = card.querySelector(".achievement-status"); | ||
| if (achievements[id]) { | ||
| card.classList.add("border-accent"); | ||
| card.style.opacity = "1"; | ||
| if (statusEl) { | ||
| statusEl.textContent = "Earned ✓"; | ||
| statusEl.style.color = "var(--accent)"; | ||
| } | ||
| } else { | ||
| card.style.opacity = "0.5"; | ||
| } | ||
| }); | ||
| }); |
| // Populate achievements | ||
| var achievements = {}; | ||
| try { | ||
| achievements = JSON.parse(localStorage.getItem("gameAchievements") || "{}"); |
There was a problem hiding this comment.
script.jsline 659):!isOpening→isOpening— the stored value was inverted so panel visibility was never correctly persisted across page loadsif (!systemDash) return) to prevent crash on pages without#dev-tools