Files
whalehunting/.planning/codebase/CONVENTIONS.md
Thomas Richter 576799ae0e docs: map existing codebase
- STACK.md - Technologies and dependencies
- ARCHITECTURE.md - System design and patterns
- STRUCTURE.md - Directory layout
- CONVENTIONS.md - Code style and patterns
- TESTING.md - Test structure
- INTEGRATIONS.md - External services
- CONCERNS.md - Technical debt and issues
2026-02-04 23:16:04 +01:00

140 lines
5.7 KiB
Markdown

# 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*