# Coding Conventions **Analysis Date:** 2026-02-04 ## Naming Patterns **Files:** - PascalCase for scene classes: `IntroScene.js`, `MapScene.js`, `HuntingScene.js`, `ShipDeckScene.js`, `TransitionScene.js` - kebab-case for test files: `game-logic.test.js`, `game-flow.spec.js` - camelCase for configuration files: `vitest.config.js`, `playwright.config.js` **Functions:** - camelCase for all methods: `drawWaves()`, `createLocation()`, `updateInventoryDisplay()`, `spawnWhale()`, `hitWhale()` - Method names are descriptive and indicate action: `create*` for initialization, `update*` for state changes, `draw*` for graphics - Private-like pattern: methods starting with event handlers (`on*` callbacks) or utility methods **Variables:** - camelCase for local variables and object properties: `whaleOil`, `currentWhale`, `inventory`, `crosshairX`, `swimSpeedX` - PascalCase for class names: `IntroScene`, `MapScene`, `HuntingScene` - SCREAMING_SNAKE_CASE for constants is not used; magic numbers are inline or stored as camelCase object properties - Abbreviated names in loops: `i`, `x`, `y` for coordinates **Types:** - No TypeScript; vanilla JavaScript with JSDoc comments for complex logic - Object literals for data structures (e.g., inventory: `{ whaleOil: 0, fuel: 100, penguins: 0 }`) - No explicit type annotations; types inferred from usage context ## Code Style **Formatting:** - No explicit formatter configured (no .prettierrc or similar found) - 4 spaces for indentation (observed consistently across all files) - Single statements per line; no cramping of expressions - Line length varies; some lines exceed 100 characters **Linting:** - No ESLint or similar linting tool configured - No explicit style guide enforced; conventions followed naturally ## Import Organization **Order:** 1. Phaser framework imports: `import Phaser from 'phaser'` 2. Scene exports: `export default class SceneName extends Phaser.Scene` 3. Test framework imports: `import { describe, it, expect } from 'vitest'` and `import { test, expect } from '@playwright/test'` **Path Aliases:** - No path aliases configured - Relative imports with `.js` extension explicit: `import IntroScene from './scenes/IntroScene.js'` ## Error Handling **Patterns:** - Defensive checks before operations: `if (this.currentWhale && this.currentWhale.getData('alive'))` - Boundary checking for game state: `if (this.inventory.fuel < 2)` before processing whale - No explicit error throwing; invalid states default to safe fallbacks - Scene transitions use `this.scene.start()` with null coalescing: `this.inventory = data.inventory || { whaleOil: 0, fuel: 100, penguins: 0 }` - Array bounds checking: loop guards with `.length` checks, array splice after removal ## Logging **Framework:** console (implicit; not found in code) **Patterns:** - No logging statements observed in source code - Game messaging via `showMessage()` method: text display in game UI - Debug output would likely use console.log if needed (not observed) ## Comments **When to Comment:** - Method-level comments for non-obvious logic: `// Ocean blue background`, `// Draw decorative waves` - Inline comments for complex calculations: `// Can't hit whale while diving`, `// Keep within bounds` - Comment frequency is moderate; most code is self-documenting through naming **JSDoc/TSDoc:** - No JSDoc comments found - Vanilla JavaScript with method names that describe intent ## Function Design **Size:** - Methods range from 10-70 lines - Larger methods like `create()` (30+ lines) perform initialization with calls to smaller helper methods - Complex game logic broken into focused methods: `updateWhale()`, `updateHarpoons()`, `checkCollisions()` **Parameters:** - Methods accept 0-3 parameters typically - Event handlers use single parameter (e.g., `pointerdown` callbacks) - Data passed through scene initialization: `this.scene.start('NextScene', { inventory: data })` **Return Values:** - Mostly void/no return (Phaser scene lifecycle methods) - Some utility functions return boolean: `hasOwnProperty()` checks - Game state propagated through `this` context, not function returns ## Module Design **Exports:** - Each scene file exports default class: `export default class SceneName extends Phaser.Scene` - All scenes imported into `src/main.js` as class references - Scene registration in Phaser config array: `scene: [IntroScene, ShipDeckScene, MapScene, TransitionScene, HuntingScene]` **Barrel Files:** - No index.js or barrel files found - Each scene is independent; imports are explicit by filename ## Data Structures **Object Literals:** - Inventory object: `{ whaleOil: 0, fuel: 100, penguins: 0 }` - Configuration objects: Phaser game config in `src/main.js` - Destination mapping in `TransitionScene.js`: `destinations` object with title, description, backgroundColor, visualType **Phaser-Specific Patterns:** - `setData(key, value)` / `getData(key)` for storing state on game objects - Container objects with `add([children])` for grouping (e.g., whale body with parts) - Scene transitions with inventory passed as data parameter ## Common Patterns Observed **Scene Lifecycle:** 1. `constructor()`: Set scene key 2. `init(data)`: Receive data from previous scene 3. `create()`: Initialize scene graphics and setup 4. `update()`: Game loop updates (only used in HuntingScene) **UI Element Creation:** - Rectangle/circle/text created with `.add.rectangle()`, `.add.circle()`, `.add.text()` - Interactive zones created with `setInteractive()` and `.on('pointerX', callback)` - Hover/click feedback with `setScale()`, `setFillStyle()` updates **Animation:** - Phaser tweens for smooth transitions: `this.tweens.add({ targets: obj, property: value, duration: ms })` - Sine/cosine wave patterns for natural movement: `Math.sin()`, `Math.cos()` for bobbing/sway --- *Convention analysis: 2026-02-04*