Initialization System
Purpose: Phased initialization after deployment/restart to prevent CPU bucket drain.
Status: Active (v0.188.0+)
Manager: InitializationManager
Last Updated: 2025-11-29
Table of Contents
- Overview
- How It Works
- Initialization Phases
- Memory State Tracking
- Configuration
- CPU Protection
- Troubleshooting
- Monitoring
Overview
The initialization system spreads startup workload across multiple ticks to prevent CPU bucket drain after deployment or server restart. This protects the bot from immediate timeout cascades during the critical post-restart period.
Why Phased Initialization Exists
When the Screeps server restarts or new code is deployed, all global variables are cleared, requiring full re-initialization. Without protection, this can cause:
- Immediate CPU bucket drain: All initialization executes in one tick
- Timeout cascades: Low bucket leads to more timeouts, creating a death spiral
- Emergency mode activation: System becomes unstable during recovery
- Lost operational time: Bot non-functional during restart recovery
Key Features
- Phased execution: Initialization spread across 1-5 ticks
- CPU budget protection: Each phase respects CPU limits
- Bucket monitoring: Defers initialization when bucket is critically low
- Graceful degradation: Force-completes after maximum tick limit
- State persistence: Progress tracked in Memory.init
How It Works
1 | Tick 1: Memory validation, basic structures |
The InitializationManager maintains a queue of phases, each with:
- Priority: Execution order (lower = earlier)
- CPU estimate: Expected CPU cost
- Execute function: The initialization logic
Each tick, phases execute within the available CPU budget. When budget exhausted, remaining phases defer to next tick.
Initialization Phases
| Phase | Priority | CPU Est | Description |
|---|---|---|---|
memory-validation |
0 | 1 | Ensure Memory structures exist |
profiler-setup |
10 | 2 | Initialize profiler if enabled |
event-subscriptions |
20 | 1 | Confirm event bus ready |
console-diagnostics |
30 | 1 | Expose global utilities |
Phase 0: Memory Validation (Priority 0)
Ensures critical Memory structures exist:
Memory.stats- Telemetry data structureMemory.profiler- Profiler data collection
This runs first because all other systems depend on Memory availability.
Phase 1: Profiler Setup (Priority 10)
Initializes the profiler if enabled at build time (__PROFILER_ENABLED__):
- Creates
Memory.profilerstructure - Auto-starts data collection
- Sets profilerInitialized flag
Phase 2: Event Subscriptions (Priority 20)
Confirms event bus is ready for runtime events:
- Hostile detection events
- Energy depletion events
- Energy restoration events
Note: Event subscriptions are registered at module load, this phase confirms readiness.
Phase 3: Console Diagnostics (Priority 30)
Exposes global utilities for console access:
global.Profiler- Profiler CLIglobal.Diagnostics- Runtime diagnosticsglobal.EventBus- Event bus instance
Memory State Tracking
Initialization state is persisted in Memory.init:
1 | Memory.init = { |
State Transitions
- Init Not Started:
Memory.initundefined - Init In Progress:
Memory.init.complete === false - Init Complete:
Memory.init.complete === true
Once complete, the initialization system is bypassed until the next code reload or server restart.
Configuration
The InitializationManager accepts configuration options:
1 | const initManager = new InitializationManager({ |
Configuration Options
| Option | Default | Description |
|---|---|---|
minBucketLevel |
500 | Minimum CPU bucket to proceed with initialization |
cpuSafetyMargin |
0.8 | Fraction of CPU limit to use for init phases |
maxInitTicks |
10 | Maximum ticks before force-completing init |
CPU Protection
The initialization system includes multiple CPU protection mechanisms:
1. Budget-Based Execution
Each phase has a CPU estimate. Before executing, the system checks:
1 | cpuRemaining = (limit * safetyMargin) - getUsed() |
2. Bucket Deferral
If CPU bucket falls below minBucketLevel (default 500), initialization is deferred entirely:
1 | [InitializationManager] CPU bucket (100) below threshold (500), deferring initialization |
This allows bucket to recover before attempting CPU-intensive initialization.
3. Force Completion
If initialization hasn’t completed within maxInitTicks, it force-completes:
1 | [InitializationManager] Max init ticks (10) exceeded, force-completing initialization |
This prevents indefinite initialization loops if phases continuously fail to fit in budget.
Troubleshooting
Initialization Not Completing
Symptoms: Memory.init.complete stays false for many ticks
Causes:
- CPU bucket critically low (< 500)
- Phase CPU estimates too high for limit
- High background CPU usage
Solutions:
- Wait for bucket to recover (check
Game.cpu.bucket) - Review phase CPU estimates
- Check for CPU-heavy external processes
Phases Skipping Repeatedly
Symptoms: Same phases skip every tick
Causes:
- CPU usage consistently high
- Phase estimates higher than available budget
Solutions:
- Reduce phase CPU estimates
- Increase
cpuSafetyMargin - Split large phases into smaller ones
Force Completion Warning
Log: Max init ticks exceeded, force-completing initialization
Impact: Some phases may not have executed
Recovery:
- Monitor for missing functionality
- Phases will work on subsequent normal ticks
- Consider increasing
maxInitTicksif needed
Monitoring
Console Commands
1 | // Check initialization status |
Log Messages
Normal initialization:
1 | [InitializationManager] Starting phased initialization (tick 12345) |
CPU-constrained initialization:
1 | [InitializationManager] CPU budget exhausted (15.00/16.00), skipping 2 phases until next tick |
Metrics
Track initialization performance in Memory.stats:
init.ticksRequired- Ticks to complete initializationinit.phasesExecuted- Total phases executedinit.lastStartTick- When initialization last started
Related Documentation
- Bootstrap Phase System - Room bootstrap phases
- CPU Management - CPU optimization strategies
- Memory Management - Memory structure overview
- Deployment Procedure - Post-deployment checks
API Reference
InitializationManager
1 | class InitializationManager { |