200 lines
6.0 KiB
Markdown
200 lines
6.0 KiB
Markdown
# 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
|