9.4 KiB
REVIEW.md
This document provides a systematic checklist for conducting periodic code reviews of the hockey-manager-2 codebase. Use this to maintain code quality, consistency, and adherence to best practices.
Review Frequency
- Minor Review: After completing each phase (see PLAN.md)
- Major Review: Every 2-3 phases or when accumulating significant technical debt
- Pre-Release Review: Before any major release or milestone
Review Checklist
1. Code Organization & Architecture
File Structure
- Files are in correct directories according to their responsibility
- No circular dependencies between modules
- Clear separation of concerns (entities, systems, config, scenes)
- Phaser-specific code isolated from game logic where possible
Naming Conventions
- Classes use PascalCase (
Player,BehaviorTree) - Files match class names (
Player.ts,GameScene.ts) - Constants use SCREAMING_SNAKE_CASE (
RINK_WIDTH,TARGET_FPS) - Variables and functions use camelCase (
currentPosition,calculateDistance()) - Meaningful, descriptive names (avoid
temp,data,handlerwithout context)
2. DRY (Don't Repeat Yourself)
Code Duplication
- No duplicate logic across files (extract to shared utilities)
- No duplicate constants (all magic numbers in constants.ts)
- No duplicate type definitions (centralize in types file)
- Similar entity behaviors extracted to base classes or systems
Common Patterns to Extract
- Distance calculations → utility function
- Position validation/clamping → utility function
- Phaser object creation → factory functions
- Coordinate conversions (meters ↔ pixels) → utility functions
3. KISS (Keep It Simple, Stupid)
Simplicity Checks
- Functions do one thing and do it well
- No overly clever solutions that sacrifice readability
- Complex algorithms have explanatory comments
- Prefer explicit over implicit behavior
- Avoid premature optimization
Function Complexity
- Functions < 50 lines (guideline, not hard rule)
- Nested conditionals < 3 levels deep
- Function parameters < 5 (consider config objects for more)
- No "god functions" that do too much
4. Type Safety
TypeScript Usage
- No
anytypes (useunknownif truly needed) - Interfaces defined for complex objects
- Return types explicitly declared on public methods
- Proper null/undefined handling with optional chaining
- Enums or union types for fixed sets of values
Type Definitions
- Shared types in dedicated types file
- No inline type definitions used multiple times
- Entity state properly typed (position, velocity, attributes)
5. Performance
Hot Path Optimization
update()loops avoid unnecessary allocations- Object pooling for frequently created/destroyed objects (bullets, particles)
- Minimize garbage collection pressure (reuse objects where possible)
- Expensive calculations cached when appropriate
Phaser Best Practices
- Sprites reused via object pools
- Physics bodies properly cleaned up
- Textures loaded once, referenced many times
- Update loops only process active entities
6. Constants & Configuration
Centralization
- All magic numbers extracted to constants.ts
- Related constants grouped logically (RINK_, PLAYER_, PUCK_*)
- Constants documented with units (meters, pixels, seconds)
- Derived constants calculated from base constants
Tunable Values
- Game balance values clearly marked for tuning
- Physics values (speed, acceleration) easy to adjust
- AI behavior probabilities configurable
- Debug flags for visualization toggles
7. Error Handling
Robustness
- Invalid positions clamped/validated
- Division by zero checks
- Null/undefined guards on external data
- Graceful degradation for missing resources
Debugging
- Meaningful console warnings for unexpected states
- Debug visualization available (toggle in constants)
- Assert-like checks in development builds
8. Comments & Documentation
Code Comments
- Complex algorithms explained
- Non-obvious decisions justified
- Public APIs documented (JSDoc style)
- TODOs tracked and dated
Project Documentation
- CLAUDE.md reflects current architecture
- PLAN.md updated with completion status
- NOTES.md captures important design decisions
- README accurate for development setup
9. Testing Readiness
Testability
- Pure functions separated from side effects
- Game logic decoupled from Phaser where possible
- Dependency injection for systems (not hardcoded singletons)
- State machines/behavior trees unit-testable
Manual Testing
- Visual debug modes available
- Hot reload works correctly
- No console errors in normal operation
- Performance profiling points identified
10. Git Hygiene
Commit Quality
- Logical, atomic commits
- Clear commit messages
- No commented-out code blocks committed
- No debug console.logs in production code
Branch Management
- Dead branches cleaned up
- Feature branches merged or rebased
- Master/main branch stable
Review Process
Before Starting Review
-
Create a review branch (optional but recommended)
git checkout -b review/phase-N -
Run the build
pnpm run buildEnsure no errors before starting review.
-
Document findings in a
REVIEW_NOTES.mdor GitHub issues
During Review
-
Scan each section systematically using checklist above
-
Note issues with file path and line number
-
Categorize by priority:
- Critical: Bugs, type safety issues, performance problems
- Important: DRY violations, architectural issues
- Nice-to-have: Better names, additional comments
-
Create refactor tasks for important findings
After Review
- Prioritize fixes (critical → important → nice-to-have)
- Refactor incrementally (small, testable changes)
- Update documentation if architecture changed
- Commit refactors separately from feature work
Specific Code Smells to Watch For
Hockey Manager Specific
- Hardcoded positions: All positions should derive from constants
- Pixel/meter confusion: Ensure conversions are correct and consistent
- Missing coordinate validation: Positions should stay within rink bounds
- Attribute magic numbers: Player attributes (0-20 scale) should be typed
- Decision probabilities: AI chances should be in constants, not inline
Phaser Specific
- Memory leaks: Sprites/physics bodies not destroyed
- Update loop bloat: Too much computation in GameScene.update()
- Texture management: Multiple loads of same texture
- Scale confusion: Mixing world coordinates with screen coordinates
TypeScript Specific
- Type assertions: Excessive use of
askeyword - Implicit any: Missing type annotations
- Non-null assertions: Overuse of
!operator - Enum misuse: Strings where enums would be clearer
Refactoring Patterns
Extract Utility Function
Before:
const dist = Math.sqrt(
Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)
);
After:
// In utils/math.ts
export function distance(x1: number, y1: number, x2: number, y2: number): number {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
Extract Constants
Before:
if (player.speed > 8.5) { // max skating speed
After:
// In constants.ts
export const MAX_SKATING_SPEED = 8.5; // m/s
// In code
if (player.speed > MAX_SKATING_SPEED) {
Extract Type
Before:
function updatePlayer(data: { x: number; y: number; team: string }) {
After:
// In types.ts
interface Position {
x: number;
y: number;
}
type Team = 'home' | 'away';
interface PlayerData {
position: Position;
team: Team;
}
function updatePlayer(data: PlayerData) {
Simplify Nested Conditionals
Before:
if (hasPuck) {
if (inShootingRange) {
if (skill > 15) {
shoot();
}
}
}
After:
const canShoot = hasPuck && inShootingRange && skill > 15;
if (canShoot) {
shoot();
}
Tools & Commands
Find Duplicated Code
# Search for duplicate function patterns
grep -r "function calculateDistance" src/
# Find magic numbers (numbers not in constants)
grep -rE "\b[0-9]+\.?[0-9]*\b" src/ --exclude-dir=config
Count Lines Per File
# Find large files that might need splitting
find src -name "*.ts" -exec wc -l {} + | sort -rn
TypeScript Strict Checks
Ensure tsconfig.json has:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}
Success Criteria
A successful review results in:
- ✅ All critical issues resolved
- ✅ No obvious code duplication
- ✅ Constants properly centralized
- ✅ Type safety throughout
- ✅ Documentation reflects current state
- ✅ Build passes without warnings
- ✅ Code runs smoothly in dev mode
Remember: The goal is maintainable, readable, and performant code. Don't sacrifice clarity for cleverness. When in doubt, be explicit.