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

5.7 KiB

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