From f3268f18a4166ab015fbdcc97740c82e10c216a5 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Sat, 21 Feb 2026 02:00:18 +0000 Subject: [PATCH] fix: update combat configurations and debug visuals for improved gameplay and debugging experience --- .../break_escape/js/config/combat-config.js | 4 +- public/break_escape/js/core/game.js | 2 +- public/break_escape/js/core/player.js | 120 ++++++++++-------- public/break_escape/js/main.js | 4 +- public/break_escape/js/systems/debug.js | 16 ++- .../break_escape/js/systems/npc-behavior.js | 9 +- .../break_escape/js/systems/player-combat.js | 8 +- public/break_escape/js/utils/constants.js | 13 +- 8 files changed, 106 insertions(+), 70 deletions(-) diff --git a/public/break_escape/js/config/combat-config.js b/public/break_escape/js/config/combat-config.js index 0c25e92..4f804bf 100644 --- a/public/break_escape/js/config/combat-config.js +++ b/public/break_escape/js/config/combat-config.js @@ -43,12 +43,12 @@ export const COMBAT_CONFIG = { npc: { defaultMaxHP: 100, defaultPunchDamage: 10, - defaultPunchRange: 50, + defaultPunchRange: 32, defaultAttackCooldown: 2000, attackWindupDuration: 500, chaseSpeed: 120, chaseRange: 400, - attackStopDistance: 45 + attackStopDistance: 32 }, ui: { maxHearts: 5, diff --git a/public/break_escape/js/core/game.js b/public/break_escape/js/core/game.js index d669e11..9459ba0 100644 --- a/public/break_escape/js/core/game.js +++ b/public/break_escape/js/core/game.js @@ -707,7 +707,7 @@ export async function create() { // Initialize NPC Behavior Manager (async lazy loading) if (window.npcManager) { - import('../systems/npc-behavior.js?v=6') + import('../systems/npc-behavior.js?v=7') .then(module => { window.npcBehaviorManager = new module.NPCBehaviorManager(this, window.npcManager); console.log('✅ NPC Behavior Manager initialized'); diff --git a/public/break_escape/js/core/player.js b/public/break_escape/js/core/player.js index cb5bca9..404315c 100644 --- a/public/break_escape/js/core/player.js +++ b/public/break_escape/js/core/player.js @@ -12,7 +12,7 @@ import { CLICK_INDICATOR_DURATION, SPRITE_PADDING_BOTTOM_ATLAS, SPRITE_PADDING_BOTTOM_LEGACY -} from '../utils/constants.js?v=8'; +} from '../utils/constants.js?v=9'; export let player = null; export let targetPoint = null; @@ -763,67 +763,77 @@ function drawPathDebug(fromX, fromY, smoothed, raw) { } if (!gameRef || !smoothed || smoothed.length === 0) return; + const debugMode = !!window.breakEscapeDebug; const g = gameRef.add.graphics(); g.setDepth(900); // above most objects, below UI pathDebugGraphics = g; - // --- Raw path nodes (small grey circles) --- - if (raw && raw.length > 0) { - g.fillStyle(0x888888, 0.55); - for (const p of raw) { - g.fillCircle(p.x, p.y, 3); - } - } - - // Helper: all points including player origin const allPoints = [{ x: fromX, y: fromY }, ...smoothed]; - // --- Smoothed path line --- - g.lineStyle(2, 0x00ffff, 0.9); - g.beginPath(); - g.moveTo(allPoints[0].x, allPoints[0].y); - for (let i = 1; i < allPoints.length; i++) { - g.lineTo(allPoints[i].x, allPoints[i].y); - } - g.strokePath(); - - // --- Waypoint circles + index labels --- - for (let i = 0; i < smoothed.length; i++) { - const p = smoothed[i]; - // Outer ring - g.lineStyle(2, 0x00ffff, 1); - g.fillStyle(0x003333, 0.7); - g.fillCircle(p.x, p.y, 7); - g.strokeCircle(p.x, p.y, 7); - // Index text in scene (not part of graphics object) - const label = gameRef.add.text(p.x + 9, p.y - 7, String(i + 1), { - fontSize: '10px', color: '#00ffff', stroke: '#000000', strokeThickness: 2 - }).setDepth(901).setAlpha(0.9); - // Track labels so they can be cleared with the graphics - if (!g._debugLabels) g._debugLabels = []; - g._debugLabels.push(label); - } - - // --- Fade-out tween (3 s) --- - gameRef.tweens.add({ - targets: g, - alpha: { from: 1, to: 0 }, - duration: 3000, - ease: 'Linear', - onUpdate: () => { - // Keep labels in sync with graphics alpha - if (g._debugLabels) { - for (const lbl of g._debugLabels) lbl.setAlpha(g.alpha); - } - }, - onComplete: () => { - if (g._debugLabels) { - for (const lbl of g._debugLabels) lbl.destroy(); - } - g.destroy(); - if (pathDebugGraphics === g) pathDebugGraphics = null; + if (debugMode) { + // ── FULL DEBUG VIEW ────────────────────────────────────────────────── + // Raw path nodes (small grey circles) + if (raw && raw.length > 0) { + g.fillStyle(0x888888, 0.55); + for (const p of raw) g.fillCircle(p.x, p.y, 3); } - }); + + // Smoothed path — cyan line + g.lineStyle(2, 0x00ffff, 0.9); + g.beginPath(); + g.moveTo(allPoints[0].x, allPoints[0].y); + for (let i = 1; i < allPoints.length; i++) g.lineTo(allPoints[i].x, allPoints[i].y); + g.strokePath(); + + // Waypoint circles + index labels + for (let i = 0; i < smoothed.length; i++) { + const p = smoothed[i]; + g.lineStyle(2, 0x00ffff, 1); + g.fillStyle(0x003333, 0.7); + g.fillCircle(p.x, p.y, 7); + g.strokeCircle(p.x, p.y, 7); + const label = gameRef.add.text(p.x + 9, p.y - 7, String(i + 1), { + fontSize: '10px', color: '#00ffff', stroke: '#000000', strokeThickness: 2 + }).setDepth(901).setAlpha(0.9); + if (!g._debugLabels) g._debugLabels = []; + g._debugLabels.push(label); + } + + // 3 s fade + gameRef.tweens.add({ + targets: g, + alpha: { from: 1, to: 0 }, + duration: 3000, + ease: 'Linear', + onUpdate: () => { + if (g._debugLabels) for (const lbl of g._debugLabels) lbl.setAlpha(g.alpha); + }, + onComplete: () => { + if (g._debugLabels) for (const lbl of g._debugLabels) lbl.destroy(); + g.destroy(); + if (pathDebugGraphics === g) pathDebugGraphics = null; + } + }); + } else { + // ── NORMAL VIEW — thin white line, same color/duration as click indicator ── + g.lineStyle(1.5, 0xffffff, 0.6); + g.beginPath(); + g.moveTo(allPoints[0].x, allPoints[0].y); + for (let i = 1; i < allPoints.length; i++) g.lineTo(allPoints[i].x, allPoints[i].y); + g.strokePath(); + + // Match click-indicator fade duration (CLICK_INDICATOR_DURATION = 800 ms) + gameRef.tweens.add({ + targets: g, + alpha: { from: 0.7, to: 0 }, + duration: CLICK_INDICATOR_DURATION, + ease: 'Sine.easeOut', + onComplete: () => { + g.destroy(); + if (pathDebugGraphics === g) pathDebugGraphics = null; + } + }); + } } export function movePlayerToPoint(x, y) { diff --git a/public/break_escape/js/main.js b/public/break_escape/js/main.js index 24b9fb3..01a5192 100644 --- a/public/break_escape/js/main.js +++ b/public/break_escape/js/main.js @@ -1,10 +1,10 @@ -import { GAME_CONFIG } from './utils/constants.js?v=8'; +import { GAME_CONFIG } from './utils/constants.js?v=9'; import { preload, create, update } from './core/game.js?v=41'; import { initializeNotifications } from './systems/notifications.js?v=7'; // Bluetooth scanner is now handled as a minigame // Biometrics is now handled as a minigame import { startLockpickingMinigame } from './systems/minigame-starters.js?v=1'; -import { initializeDebugSystem } from './systems/debug.js?v=7'; +import { initializeDebugSystem } from './systems/debug.js?v=8'; import { initializeUI } from './ui/panels.js?v=9'; import { initializeModals } from './ui/modals.js?v=7'; diff --git a/public/break_escape/js/systems/debug.js b/public/break_escape/js/systems/debug.js index 5f292de..d525a90 100644 --- a/public/break_escape/js/systems/debug.js +++ b/public/break_escape/js/systems/debug.js @@ -4,7 +4,12 @@ // Debug system variables let debugMode = false; let debugLevel = 1; // 1 = basic, 2 = detailed, 3 = verbose -let visualDebugMode = true; // TEMPORARY: Visual debug (collision boxes, movement vectors) - on for testing +let visualDebugMode = false; // Off by default; toggle with backtick key at runtime + +// Expose current visual-debug state globally so other modules (player.js, +// npc-behavior.js) can read it without an import. +window.breakEscapeDebug = visualDebugMode; +window.pathfindingDebug = visualDebugMode; // Initialize the debug system export function initializeDebugSystem() { @@ -25,10 +30,15 @@ export function initializeDebugSystem() { `color: #0077FF; font-weight: bold;`); } } else { - // Regular backtick toggles visual debug mode (collision boxes, movement vectors) + // Regular backtick toggles visual debug mode (collision boxes, NPC/player paths) visualDebugMode = !visualDebugMode; + // Keep global flags in sync so player.js and npc-behavior.js pick up the change + window.breakEscapeDebug = visualDebugMode; + window.pathfindingDebug = visualDebugMode; console.log(`%c[DEBUG] === VISUAL DEBUG MODE ${visualDebugMode ? 'ENABLED' : 'DISABLED'} ===`, `color: ${visualDebugMode ? '#00AA00' : '#DD0000'}; font-weight: bold;`); + console.log('%c Backtick → visual debug (paths, collision boxes)', 'color:#888'); + console.log('%c Shift+` → console debug mode', 'color:#888'); // Update physics debug display if game exists updatePhysicsDebugDisplay(); @@ -36,7 +46,7 @@ export function initializeDebugSystem() { } }); - console.log('Debug system initialized'); + console.log('Debug system initialized (visual debug OFF — press ` to toggle)'); } // Function to update physics debug display diff --git a/public/break_escape/js/systems/npc-behavior.js b/public/break_escape/js/systems/npc-behavior.js index 713e713..ea97975 100644 --- a/public/break_escape/js/systems/npc-behavior.js +++ b/public/break_escape/js/systems/npc-behavior.js @@ -1108,7 +1108,7 @@ class NPCBehavior { // Get attack range from hostile system const attackRange = window.npcHostileSystem ? - window.npcHostileSystem.getState(this.npcId)?.attackRange || 50 : 50; + window.npcHostileSystem.getState(this.npcId)?.attackRange || 32 : 32; // If in attack range, try to attack if (distance <= attackRange) { @@ -1244,7 +1244,8 @@ class NPCBehavior { ); this.chasePath = smoothed; this.chasePathIndex = 0; - this._drawChasePathDebug(smoothed); + if (window.breakEscapeDebug) this._drawChasePathDebug(smoothed); + else this._clearChasePathDebug(); } else { // No path found (unreachable or grid not ready) this.chasePath = []; @@ -1255,10 +1256,10 @@ class NPCBehavior { ); } - /** Draw the current chase path as a red overlay for debugging. */ + /** Draw the current chase path as a red overlay for debugging (debug mode only). */ _drawChasePathDebug(path) { this._clearChasePathDebug(); - if (!path || path.length === 0) return; + if (!window.breakEscapeDebug || !path || path.length === 0) return; const scene = this.scene || window.game?.scene?.scenes[0]; if (!scene) return; diff --git a/public/break_escape/js/systems/player-combat.js b/public/break_escape/js/systems/player-combat.js index 4f907fe..86a8ef8 100644 --- a/public/break_escape/js/systems/player-combat.js +++ b/public/break_escape/js/systems/player-combat.js @@ -259,8 +259,12 @@ export class PlayerCombat { // Get player facing direction const direction = window.player.lastDirection || 'down'; - // Draw debug hit area - this.drawPunchHitbox(playerX, playerY, punchRange, direction); + // Draw debug hit area (only when debug mode is on) + if (window.breakEscapeDebug) { + this.drawPunchHitbox(playerX, playerY, punchRange, direction); + } else if (this.hitboxGraphics) { + this.hitboxGraphics.clear(); // ensure no stale overlay if debug was just toggled off + } // Get all NPCs from rooms let hitCount = 0; diff --git a/public/break_escape/js/utils/constants.js b/public/break_escape/js/utils/constants.js index 3a596c7..5fd7029 100644 --- a/public/break_escape/js/utils/constants.js +++ b/public/break_escape/js/utils/constants.js @@ -1,3 +1,14 @@ +// ───────────────────────────────────────────────────────────────────────────── +// DEBUG FLAG — flip this single constant to true to enable all debug visuals: +// • Phaser physics collision-box overlay +// • Player path-finding line with waypoint circles and index labels +// • NPC hostile chase-path overlay +// • Console pathfinding spam (window.pathfindingDebug) +// You can also toggle at runtime with the backtick key (visual) or +// Shift+backtick (console), or set window.breakEscapeDebug = true in DevTools. +// ───────────────────────────────────────────────────────────────────────────── +export const BREAK_ESCAPE_DEBUG = false; + // Game constants export const TILE_SIZE = 32; export const DOOR_ALIGN_OVERLAP = 32 * 3; @@ -86,7 +97,7 @@ export const GAME_CONFIG = typeof Phaser !== 'undefined' ? { default: 'arcade', arcade: { gravity: { y: 0 }, - debug: true // TEMPORARY: enable physics collision box visualisation + debug: BREAK_ESCAPE_DEBUG // Toggle via BREAK_ESCAPE_DEBUG constant above } } } : null; \ No newline at end of file