Add project documentation (README.md) and AI agent guidelines (AGENTS.md)

This commit is contained in:
Brian Fertig 2026-03-07 19:50:32 -07:00
parent e0a6e6d116
commit d0b7b79af0
2 changed files with 340 additions and 0 deletions

199
AGENTS.md Normal file
View File

@ -0,0 +1,199 @@
# 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

141
README.md Normal file
View File

@ -0,0 +1,141 @@
# Overrun
A Smash TV-style top-down arena shooter built with Phaser 3.
## Overview
Overrun is a fast-paced twin-stick shooter where you battle waves of enemies across multiple zones. Kill enemies to earn XP, level up, and unlock powerful skills from a branching skill tree.
## How to Play
### Running the Game
Since the game uses ES6 modules, it must be served over HTTP (not `file://`):
```bash
# Option 1: Using npx
npx serve .
# Option 2: Using Python
python3 -m http.server 8080
# Option 3: Using the provided script
./start_web.sh
```
Then open `http://localhost:8080` in your browser.
### Controls
| Key | Action |
|-----|--------|
| **W / A / S / D** | Move player |
| **Mouse** | Aim direction |
| **Left Click** | Fire weapon |
| **R** | Restart (on game over) |
### Gameplay
- **Lives**: Start with 3 lives, 100 HP per life
- **XP & Leveling**: Earn XP by killing enemies. When you level up, the game pauses and you can pick a skill
- **Zones**: Progress through multiple zones, each with increasingly difficult enemy waves
- **Victory**: Complete all zones to win
### Skill Tree
The skill tree branches into two main paths:
**Defense**
- Take 10% less damage (and additional upgrades)
**Offense**
- Increase damage by 20%
- Increase fire rate by 40%
New skills can be added by editing `js/data/skillTree.json`.
## Project Structure
```
overrun/
├── index.html # Entry HTML file
├── main.js # Game entry point, Phaser config
├── phaser.min.js # Phaser 3 library (minified)
├── start_web.sh # Convenience script to start server
│
├── js/
│ ├── main.js # Phaser game configuration
│ ├── scenes/ # Game scenes
│ │ ├── IntroScene.js
│ │ ├── GameScene.js
│ │ └── GameOverScene.js
│ │
│ ├── entities/ # Game entities
│ │ ├── Player.js
│ │ └── enemies/
│ │ ├── BaseEnemy.js
│ │ ├── ChaseEnemy.js
│ │ ├── BomberEnemy.js
│ │ ├── SprayerEnemy.js
│ │ ├── ShooterEnemy.js
│ │ └── SwarmerEnemy.js
│ │
│ ├── systems/ # Game systems
│ │ ├── WaveManager.js
│ │ ├── SkillTree.js
│ │ ├── XPSystem.js
│ │ └── BarrierManager.js
│ │
│ ├── ui/ # UI components
│ │ ├── HUD.js
│ │ ├── SkillTreeUI.js
│ │ └── Reticle.js
│ │
│ └── data/ # JSON data files
│ ├── zones.json
│ └── skillTree.json
│
└── assets/
└── sprites/ # Game sprites (player, enemies)
```
## Enemy Types
| Enemy | Behavior |
|-------|----------|
| **Chaser** | Directly pursues the player |
| **Swarmer** | Fast, erratic movement in groups |
| **Shooter** | Fires projectiles at the player |
| **Sprayer** | Fires multiple projectiles in a spread |
| **Bomber** | Explodes on contact or when near player |
## Development
### Adding New Enemies
1. Create a new file in `js/entities/enemies/`
2. Extend `BaseEnemy` or create a new class
3. Implement `update()`, `takeDamage()`, and `attack()` methods
4. Register the enemy in `js/data/zones.json`
### Adding New Skills
1. Edit `js/data/skillTree.json`
2. Add a new node with:
- `id`: Unique identifier
- `parent`: ID of the parent node (or `null` for root)
- `effect`: Object with `stat`, `add`, and/or `multiply` values
### Adding New Zones
Edit `js/data/zones.json` to define new zones with increasing difficulty.
## Tech Stack
- **Phaser 3** - Game framework
- **Vanilla JavaScript** - No bundlers, ES6 modules
- **No build tools** - Runs directly in browser
## License
MIT License