# AGENTS.md - Agent Coding Guidelines

This file provides guidance for AI agents working on this codebase.

## Project Overview

This is a Phaser 3 HTML game (Smash TV-style top-down arena shooter) built with vanilla JavaScript and ES6 modules. No build tools or bundlers are used — the game runs directly in the browser.

## Running the Game

Since there is no bundler, serve the files with a local HTTP server (ES6 modules require HTTP, not `file://`):

```bash
npx serve .
# or
python3 -m http.server 8080
# or
./start_web.sh
```

Then open `http://localhost:8080` (or whatever port) in a browser.

## Build/Lint/Test Commands

This project has **no build tools, no linting, and no test framework**. It uses vanilla JavaScript with ES6 modules.

- **Run game**: `npx serve .` or `python3 -m http.server 8080` or `./start_web.sh`
- **No lint command**: Manually review code for style consistency
- **No test command**: No tests exist; manually verify functionality in browser

## Code Style Guidelines

### General Principles
- Keep code modular — each major concern in its own file/class
- Use ES6 `import`/`export` for all inter-module dependencies
- No TypeScript — plain JavaScript only
- No bundlers (Webpack, Vite, etc.)

### File Organization
```
js/
├── main.js              # Entry point, game config
├── scenes/              # Phaser scenes (IntroScene, GameScene, GameOverScene)
├── entities/            # Game entities (Player, enemies)
│   └── enemies/         # Enemy classes (BaseEnemy, ChaseEnemy, etc.)
├── systems/             # Game systems (WaveManager, SkillTree, XPSystem)
├── ui/                  # UI components (HUD, SkillTreeUI, Reticle)
└── data/                # JSON data files (zones.json, skillTree.json)
```

### Naming Conventions
- **Classes**: PascalCase (e.g., `Player`, `WaveManager`, `GameScene`)
- **Files**: PascalCase with .js extension (e.g., `Player.js`, `WaveManager.js`)
- **Constants**: UPPER_SNAKE_CASE (e.g., `BULLET_SPEED`, `TURN_RATE_DEG`)
- **Private methods**: underscore prefix (e.g., `_createAnims`, `_move`)
- **Private fields**: underscore prefix (e.g., `_fireCooldown`, `_isMoving`)

### Imports/Exports
- Use absolute paths from project root: `import { Player } from '../entities/Player.js';`
- Group imports at top of file
- Export classes as named exports: `export class Player { ... }`

### Formatting
- 2 spaces for indentation
- No semicolons at statement end (optional in JS)
- Use template literals for string interpolation: `` `Player at ${x}, ${y}` ``
- Use const for all variables that don't change
- Use let for mutable variables, avoid var

### Code Structure

#### Class Structure Example
```javascript
const CONSTANT_VALUE = 100;

export class MyClass {
  constructor(scene, x, y) {
    this.scene = scene;
    this.x = x;
    this.y = y;
    this._privateField = 0;
    this._setup();
  }

  _setup() {
    // initialization
  }

  update(delta) {
    this._updatePhysics(delta);
    this._updateAnimation();
  }

  _updatePhysics(delta) {
    // physics logic
  }

  _updateAnimation() {
    // animation logic
  }

  publicMethod() {
    // public API
  }

  destroy() {
    // cleanup
  }
}
```

### Error Handling
- No try/catch blocks required for simple operations
- Use Phaser's built-in error handling where applicable
- Log errors to console for debugging: `console.warn('message')` or `console.error('message')`
- Validate inputs at function entry points when needed

### Phaser-Specific Patterns
- Extend Phaser classes: `export class GameScene extends Phaser.Scene`
- Use `this.scene` reference to access scene in entity classes
- Use `this.add.*` for creating game objects
- Use `this.physics.add.*` for physics objects
- Use `this.events.emit()` and `this.events.on()` for event-driven communication
- Use Phaser's built-in groups: `this.add.group()`, `this.physics.add.group()`

### Data Files (JSON)
- Store game data in `js/data/` directory
- Examples: `zones.json`, `skillTree.json`
- Load via: `this.load.json('key', 'path')` then `this.cache.json.get('key')`

### Adding New Features

#### Adding a New Enemy Type
1. Create new file in `js/entities/enemies/`
2. Extend `BaseEnemy` or create new class
3. Implement required methods: `update()`, `takeDamage()`, `attack()`
4. Register in wave definitions (zones.json)

#### Adding a New Skill
1. Add skill definition to `js/data/skillTree.json`
2. Define node id, parent, effect (stat, add/multiply values)
3. Implement effect logic in `SkillTree.applyNode()`

#### Adding a New Scene
1. Create new file in `js/scenes/`
2. Extend `Phaser.Scene`
3. Implement `preload()`, `create()`, `update()` methods
4. Add to scene array in `js/main.js` config

### Important Patterns

#### Player Stats Object
```javascript
this.stats = {
  speed: 200,
  damage: 20,
  fireRate: 1,
  damageReduction: 0,
  maxHp: 100,
};
```
- Stats are modified by skill tree
- Use getters/setters for x, y position from sprite

#### Event Communication
```javascript
// Emitting events
this.events.emit('enemy-killed', { xp: 10 });
this.events.emit('level-up', newLevel);

// Listening events
this.events.on('enemy-killed', ({ xp }) => { ... });
```

#### Physics Collisions
```javascript
this.physics.add.collider(playerSprite, enemyGroup);
```

### Browser Testing
- Open browser devtools (F12)
- Use Console for logging and debugging
- Use Network tab to verify asset loading
- Use Elements tab to inspect game canvas

### Common Issues
- **Modules not loading**: Ensure running via HTTP server, not file://
- **Assets not loading**: Check paths are relative to web root
- **Physics not working**: Ensure physics config in game config and physics added to objects

### Code Review Checklist
- [ ] ES6 imports/exports used correctly
- [ ] File naming follows PascalCase convention
- [ ] Constants use UPPER_SNAKE_CASE
- [ ] Private methods/fields use underscore prefix
- [ ] No console.log in production code (use console.warn for warnings)
- [ ] Code follows existing patterns in similar files
- [ ] New files added to appropriate directory structure
- [ ] JSON data files are valid
