Nokia Snake Game - Service Layer Design
Service layer design
Nokia Snake Game - Service Layer Design
Service Overview
The service layer provides orchestration and coordination between components, implementing business logic and managing cross-cutting concerns. Services follow a centralized pattern with clear responsibilities and interfaces.
Core Services
1. Game Orchestration Service
Purpose: Coordinate game components and manage the overall game flow
Responsibilities:
- Orchestrate game loop execution
- Coordinate component interactions
- Manage game state transitions
- Handle game events and routing
- Ensure component synchronization
Service Interface:
/**
* Game Orchestration Service
* Manages overall game flow and component coordination
*/
class GameOrchestrationService {
/**
* Initialize service with component dependencies
* @param {Object} dependencies - Component dependencies
*/
constructor(dependencies) {
this.gameEngine = dependencies.gameEngine;
this.rendering = dependencies.rendering;
this.inputHandler = dependencies.inputHandler;
this.stateManager = dependencies.stateManager;
this.ui = dependencies.ui;
this.scoreService = dependencies.scoreService;
}
/**
* Start the game with initial configuration
* @param {Object} config - Game configuration
* @returns {Promise<void>}
*/
async startGame(config) {
// 1. Initialize all components
// 2. Set up game state
// 3. Start game loop
// 4. Begin rendering
}
/**
* Pause the game
* @returns {void}
*/
pauseGame() {
// 1. Stop game loop
// 2. Update game state
// 3. Show pause UI
}
/**
* Resume paused game
* @returns {void}
*/
resumeGame() {
// 1. Restart game loop
// 2. Update game state
// 3. Hide pause UI
}
/**
* Handle game over condition
* @param {Object} gameOverData - Game over information
* @returns {void}
*/
handleGameOver(gameOverData) {
// 1. Stop game loop
// 2. Update scores
// 3. Show game over UI
// 4. Save game state
}
/**
* Restart the game
* @returns {void}
*/
restartGame() {
// 1. Reset game state
// 2. Reinitialize components
// 3. Start new game
}
/**
* Process game frame
* @param {number} deltaTime - Time since last frame
* @returns {void}
*/
processFrame(deltaTime) {
// 1. Process input
// 2. Update game state
// 3. Check collisions
// 4. Apply game rules
// 5. Update rendering
}
}
Orchestration Patterns:
- Command Pattern: Input events translated to game commands
- Observer Pattern: State changes propagate to observers
- Mediator Pattern: Service mediates component interactions
- Strategy Pattern: Different game modes as strategies
2. Score Service
Purpose: Manage scoring, high scores, and game progress tracking
Responsibilities:
- Calculate and track scores
- Manage high score persistence
- Track game progress and achievements
- Provide score-related analytics
- Handle score validation
Service Interface:
/**
* Score Service
* Manages scoring, high scores, and game progress
*/
class ScoreService {
/**
* Initialize score service
* @param {Object} storage - Storage adapter (localStorage, IndexedDB, etc.)
*/
constructor(storage) {
this.storage = storage;
this.currentScore = 0;
this.highScores = [];
}
/**
* Calculate score for game event
* @param {string} eventType - Type of game event
* @param {Object} eventData - Event data
* @returns {number} Score points
*/
calculateEventScore(eventType, eventData) {
// Scoring rules:
// - Food collection: 10 points
// - Power-up collection: 25 points
// - Special food: 50 points
// - Combo multiplier: based on consecutive collections
}
/**
* Update current score
* @param {number} delta - Score change
* @returns {number} New score
*/
updateScore(delta) {
this.currentScore += delta;
return this.currentScore;
}
/**
* Check and update high score
* @param {number} score - Current score
* @returns {boolean} True if high score beaten
*/
updateHighScore(score) {
if (score > this.getHighestScore()) {
this.highScores.unshift({
score: score,
date: new Date().toISOString(),
level: this.getCurrentLevel()
});
// Keep only top 10 scores
this.highScores = this.highScores.slice(0, 10);
// Persist to storage
this.saveHighScores();
return true;
}
return false;
}
/**
* Get highest score
* @returns {number} Highest score
*/
getHighestScore() {
return this.highScores.length > 0 ? this.highScores[0].score : 0;
}
/**
* Load high scores from storage
* @returns {Promise<Array>} High scores
*/
async loadHighScores() {
const scores = await this.storage.get('highScores');
this.highScores = scores || [];
return this.highScores;
}
/**
* Save high scores to storage
* @returns {Promise<void>}
*/
async saveHighScores() {
await this.storage.set('highScores', this.highScores);
}
/**
* Reset current score
* @returns {void}
*/
resetCurrentScore() {
this.currentScore = 0;
}
/**
* Get game statistics
* @returns {Object} Game statistics
*/
getGameStatistics() {
return {
totalGamesPlayed: this.getTotalGamesPlayed(),
totalScore: this.getTotalScore(),
averageScore: this.getAverageScore(),
bestCombo: this.getBestCombo(),
achievements: this.getAchievements()
};
}
}
Scoring Rules:
Base Scoring:
- Regular food: 10 points
- Special food: 50 points
- Power-ups: 25 points
Combo System:
- Consecutive food collection without dying: 1.5x multiplier
- Max combo: 5x multiplier
- Combo resets on death or missed food
Difficulty Multipliers:
- Easy: 1x
- Medium: 1.5x
- Hard: 2x
- Expert: 3x
3. Event Bus Service (Implicit)
Purpose: Decoupled event communication between components
Responsibilities:
- Publish/subscribe event system
- Event routing and filtering
- Event validation and transformation
- Error handling for events
Event Types:
const GameEvents = {
// Input Events
INPUT_KEY_DOWN: 'input:keydown',
INPUT_KEY_UP: 'input:keyup',
// Game State Events
GAME_STARTED: 'game:started',
GAME_PAUSED: 'game:paused',
GAME_RESUMED: 'game:resumed',
GAME_OVER: 'game:over',
GAME_RESTARTED: 'game:restarted',
// Gameplay Events
FOOD_COLLECTED: 'gameplay:food:collected',
POWERUP_COLLECTED: 'gameplay:powerup:collected',
COLLISION_DETECTED: 'gameplay:collision:detected',
SCORE_UPDATED: 'gameplay:score:updated',
// UI Events
UI_MENU_OPENED: 'ui:menu:opened',
UI_MENU_CLOSED: 'ui:menu:closed',
UI_BUTTON_CLICKED: 'ui:button:clicked',
// System Events
SYSTEM_INITIALIZED: 'system:initialized',
SYSTEM_ERROR: 'system:error',
SYSTEM_WARNING: 'system:warning'
};
4. Plugin Manager Service
Purpose: Manage extensible plugin system
Responsibilities:
- Plugin registration and discovery
- Plugin lifecycle management
- Plugin dependency resolution
- Plugin configuration management
Plugin Types:
- Power-up Plugins: Additional power-up types
- Visual Theme Plugins: Alternative visual styles
- Game Mode Plugins: Additional game modes
- Analytics Plugins: Game analytics and telemetry
- Social Plugins: Social features and sharing
Service Interaction Patterns
1. Request-Response Pattern
Component → Service → Component
Example: UI requests score → Score Service → Returns score
2. Publish-Subscribe Pattern
Component → Event Bus → Multiple Components
Example: Food collected → Score updates, UI updates, Analytics tracks
3. Orchestration Pattern
Orchestration Service → Multiple Components
Example: Game start → Initialize all components, start game loop
4. Choreography Pattern
Component → Event → Component → Event → Component
Example: Input → Game Engine → Rendering → UI
Service Dependencies
Game Orchestration Service
├── depends on: All core components
└── provides: Game flow coordination
Score Service
├── depends on: Storage adapter, State Manager
└── provides: Scoring and progress tracking
Event Bus Service
├── depends on: None (standalone)
└── provides: Decoupled communication
Plugin Manager Service
├── depends on: Configuration, Event Bus
└── provides: Plugin lifecycle management
Service Configuration
const serviceConfig = {
gameOrchestration: {
frameRate: 60, // FPS
fixedTimeStep: 16.67, // ms (60 FPS)
maxFrameSkip: 5
},
scoreService: {
storageType: 'localStorage',
maxHighScores: 10,
scoreDecay: false, // Whether scores decay over time
comboEnabled: true,
comboMultiplier: {
base: 1.0,
max: 5.0,
increment: 0.5
}
},
eventBus: {
maxListeners: 50,
enableLogging: false,
errorHandling: 'strict' // 'strict' | 'lenient' | 'silent'
},
pluginManager: {
pluginDirectory: '/plugins/',
autoLoad: true,
sandboxed: true, // Run plugins in sandboxed environment
versionCheck: true
}
};
Security Considerations for Services
- Input Validation: All service methods validate inputs
- Error Handling: Services handle errors gracefully
- Data Sanitization: Output data is sanitized
- Access Control: Service methods have appropriate access levels
- Audit Logging: Service actions are logged for security auditing