4.8 KiB
4.8 KiB
Code Style
Last Updated: 2026-03-31T00:00:00.000Z
Language & Version
- TypeScript 5.x, strict mode enabled
- Target: ES2020, module: ESNext, module resolution: bundler
noEmit: true— Vite handles transpilation;tscis used for type-checking only
Naming Conventions
| Kind | Convention | Examples |
|---|---|---|
| Types/Interfaces | PascalCase | Card, GameState, PlayerIndex, TeamScore, ScoreBreakdown |
| Type aliases | PascalCase | Suit, PlayerIndex |
| Classes | PascalCase | BootScene, MenuScene, GameScene |
| Functions | camelCase | buildDeck(), findCaptures(), chooseMove(), applyMove() |
| Constants | UPPER_SNAKE | PRIMIERA_VALUES, SUITS, AI_DELAY, SCOREBAR_H |
| Local variables | camelCase | bestMove, capturedCards, isScopa, afterTable |
| Private members | camelCase | this.state, this.cardImages, this.aiThinking |
| Parameters | camelCase | playerIdx, captureChoice, onComplete |
Class & Scene Patterns
Scenes extend Phaser.Scene and follow the Phaser lifecycle:
export class BootScene extends Phaser.Scene {
constructor() {
super({ key: 'BootScene' });
}
preload(): void { /* asset loading */ }
create(): void { /* scene setup */ }
}
Scene registration via Phaser.Types.Core.GameConfig.scene array in main.ts.
Indentation & Formatting
- 2-space indentation
- Single quotes for string literals
- No semicolons omission — semicolons used consistently
- Trailing commas in multi-line objects/arrays
constpreferred;letwhen reassignment is needed; novar
Import Patterns
Named imports from local modules:
import { Card, GameState, PlayerIndex } from './types';
import { findCaptures, canCapture, calcPrimiera, teamOf } from './engine';
import { chooseMove } from '../game/ai';
Default import for Phaser:
import Phaser from 'phaser';
Type-only import for Capacitor config:
import type { CapacitorConfig } from '@capacitor/cli';
Relative paths only (./, ../). No path aliases configured.
Export Patterns
- Named exports for all public symbols (
export function,export class,export interface,export type,export const) - No default exports except
vite.config.tsandcapacitor.config.ts(framework convention) - Private/internal functions are not exported (
getSubsets,calculateScores,scoreRound,deepClone)
Type Annotations
- Explicit return types on exported functions:
(): Card[],(): GameState,(): boolean - Union types for constrained values:
PlayerIndex = 0 | 1 | 2 | 3 - String literal unions:
Suit = 'bastoni' | 'coppe' | 'denara' | 'spade' - Tuple types for fixed-length arrays:
[Player, Player, Player, Player],[TeamScore, TeamScore] Record<K, V>for maps:PRIMIERA_VALUES: Record<number, number>
Comments & Documentation
- JSDoc comments on key exported functions (
findCaptures,applyMove) - Section separators using dashed lines:
// --------------------------------------------------------------------------- // Deck // --------------------------------------------------------------------------- [trueref]annotations documenting Phaser API provenance- Inline comments for non-obvious logic (capture rules, AI heuristic weights)
- No auto-generated docs or separate documentation tooling
Code Examples (from codebase)
Immutable state update pattern
export function applyMove(
state: GameState,
playerIdx: PlayerIndex,
card: Card,
captureChoice?: Card[]
): { nextState: GameState; capture: Capture | null; isScopa: boolean } {
const state2 = deepClone(state);
// ... mutations on state2 ...
return { nextState: state2, capture: ..., isScopa };
}
AI heuristic weighted scoring
function scoreCapture(...): number {
let score = 100; // base for capturing anything
if (isScopa) score += 500;
if (settebello) score += 300;
score += denariCount * 50;
score += captured.length * 20;
// ...
return score;
}
Phaser particle effect
const e1 = this.add.particles(x, y, 'particle_glow', {
lifespan: { min: 350, max: 700 },
speed: { min: 80, max: 280 },
scale: { start: 0.9, end: 0 },
tint: color, gravityY: 100, emitting: false,
}).setDepth(25);
e1.explode(count);
Linting & Formatting
No ESLint or Prettier configuration detected. Code style is maintained manually.
TypeScript strict mode provides type-level linting (strict: true in tsconfig.json).