We’re excited to announce Release 0.133.1, which marks a significant architectural milestone in the Screeps GPT project. This release introduces a comprehensive migration to a declarative state machine architecture for all creep behaviors, fundamentally transforming how our autonomous AI manages unit behavior in Screeps.
Key Features
- Complete State Machine Migration: All 12 creep roles now use declarative finite state machines via the
@ralphschuler/screeps-xstatepackage - StateMachineManager: New lifecycle management system for initializing, persisting, and cleaning up state machines across game ticks
- Reference Implementation: Full harvester executor demonstrating integration patterns for state machine-based behaviors
- Comprehensive Documentation: 150+ lines of architectural documentation with usage examples and integration guides
- Zero Breaking Changes: Existing imperative behavior system remains functional alongside new state machines
Technical Details
Why State Machines?
The decision to migrate from imperative role logic to declarative state machines was driven by several key challenges in the existing codebase:
Complexity Management: As creep behaviors grew more sophisticated, imperative if/else chains became increasingly difficult to reason about and modify safely.
Testing Challenges: Testing complex branching logic required extensive mocking and state setup, making tests brittle and time-consuming to maintain.
State Visibility: In the imperative model, a creep’s current operational state was implicit—you had to read through the code execution path to understand what a creep was doing.
Debugging Difficulty: When a creep misbehaved, there was no easy way to inspect its current state or understand why a particular transition occurred.
Architectural Design
The new state machine architecture consists of three core components:
1. State Machine Definitions (packages/bot/src/runtime/behavior/stateMachines/)
Each creep role has its own state machine file defining:
- States: Distinct operational modes (e.g., “harvesting”, “delivering”, “idle”)
- Events: Triggers for state transitions (e.g., “ENERGY_FULL”, “TARGET_REACHED”)
- Guards: Conditional logic determining when transitions should fire
- Actions: Side effects executed during transitions (e.g., updating context)
For example, the harvester state machine defines a clear progression:
1 | idle → harvesting → delivering → upgrading → idle |
Each state transition is explicit and declarative, making the behavior flow immediately apparent.
2. StateMachineManager (packages/bot/src/runtime/behavior/StateMachineManager.ts)
This 268-line manager class handles the lifecycle of all state machines:
- Initialization: Creates new state machines for spawned creeps
- Restoration: Deserializes machine state from Memory between ticks
- Persistence: Serializes machine state back to Memory for next tick
- Cleanup: Removes machines for dead or despawned creeps
The manager ensures that state machines maintain their state across the asynchronous, tick-based Screeps execution model—a critical requirement for proper behavior continuity.
3. Role Executors (packages/bot/src/runtime/behavior/roleExecutors/)
Executors bridge state machines with actual game actions. The harvester executor demonstrates the pattern:
- Queries the state machine for current state
- Sends events based on game conditions (energy full, target reached, etc.)
- Executes appropriate game actions based on current state
- Handles error conditions and edge cases
Implementation Patterns
Several key patterns emerged during development:
Guard Extraction: Initial implementations duplicated guard logic across multiple state machines. Through code review, we extracted common guards like hasEnergy(), isEnergyFull(), and hasTarget() into shared utilities, improving consistency and reducing duplication.
Single Responsibility for Cleanup: Early iterations included redundant cleanup actions in multiple transition events. The final design centralizes cleanup in state onEntry handlers, ensuring cleanup logic has a single source of truth.
Event Pruning: We removed unused events like START_HARVEST and START_GATHER that were defined but never sent, reducing cognitive overhead when reading state machine definitions.
State Loop Prevention: The claimer state machine initially had an infinite self-loop where CLAIM_COMPLETE transitioned back to the claim state. This was corrected to transition to idle, preventing potential stuck states.
All Roles Covered
The migration includes state machines for every creep role in the bot:
- Economic Roles: Harvester, Upgrader, Builder, Hauler, Stationary Harvester, Repairer
- Expansion Roles: Remote Miner, Remote Hauler, Claimer
- Combat Roles: Attacker, Healer, Dismantler
Each state machine is tailored to its role’s specific responsibilities while following consistent architectural patterns.
Integration Status
While state machines are fully defined and tested, they are not yet integrated into the main BehaviorController. This phased approach was intentional:
- Phase 1 (This Release): Define all state machines, create manager, build reference implementation
- Phase 2 (Future): Gradual migration of BehaviorController to use state machines
- Phase 3 (Future): Deprecation of old imperative logic once state machines prove stable
This approach minimizes risk—the existing imperative behavior system continues to work exactly as before, providing a safety net during the transition.
Bug Fixes
This release focused on establishing infrastructure rather than fixing bugs, but several code quality issues were addressed:
- Fixed infinite state loop in claimer state machine
- Removed unused events from multiple state machines (START_HARVEST, START_GATHER)
- Extracted duplicated guard logic into shared utilities
- Centralized cleanup logic to prevent redundant actions
Impact
Immediate Benefits
- Improved Maintainability: State machines are significantly easier to understand and modify than imperative logic
- Better Debuggability: Current state is always visible in Memory, making behavior issues easier to diagnose
- Enhanced Testability: State machines can be tested in isolation without requiring full game context
- Type Safety: Full TypeScript support with strict typing catches errors at compile time
Performance Characteristics
The screeps-xstate library is optimized specifically for Screeps’ constraints:
- Minimal bundle size: <5KB minified
- Low CPU overhead: ~0.01 CPU per transition, ~0.02 CPU for serialization
- Efficient memory usage: Compact state representation in Memory
- Tick-based persistence: Designed for Screeps’ asynchronous execution model
A typical creep with 5 states and 2 transitions per tick uses approximately 0.05 CPU total—well within acceptable overhead for the maintainability benefits.
Long-term Strategic Value
This migration establishes a foundation for more sophisticated AI behaviors:
- Behavior Trees: State machines can serve as leaf nodes in hierarchical behavior trees
- Learning Systems: State transition patterns can be analyzed to identify optimization opportunities
- Dynamic Adaptation: State machines can be modified at runtime based on changing game conditions
- Emergent Complexity: Complex behaviors emerge from simple state compositions
What’s Next
The immediate next steps for state machine integration:
- Create Executors: Implement executors for all remaining roles (currently only harvester is complete)
- Integration Testing: Validate state machines work correctly in live game conditions
- BehaviorController Migration: Gradually switch BehaviorController to use state machine executors
- Performance Validation: Measure actual CPU overhead in production and optimize if needed
- Deprecation Planning: Plan timeline for removing old imperative logic once state machines prove stable
The state machine architecture also opens doors for future enhancements:
- Visual Debugging: Generate state machine diagrams from definitions
- Behavior Analytics: Track state transition patterns to identify inefficiencies
- Dynamic Reconfiguration: Modify state machines based on room conditions
- Behavior Composition: Combine simple state machines into complex behaviors
Technical Notes
This work was completed through PR #1229, with contributions from the Copilot automation agent and manual review. The migration spanned 20 files with 1,352 additions, representing a substantial investment in architectural improvement.
All 50 unit tests pass, the build is successful at 804KB, and linting passes with strict TypeScript checks enabled. The changes are fully backward compatible—existing functionality continues to work without modification.
For developers interested in the implementation details, the complete state machine definitions are available in packages/bot/src/runtime/behavior/stateMachines/, with comprehensive documentation in the README.md file within that directory.
Word Count: ~1,320 words
This release represents a significant step forward in code quality and architectural maturity for the Screeps GPT project. By embracing declarative state machines, we’ve established a solid foundation for building increasingly sophisticated autonomous behaviors while maintaining code that’s easier to understand, test, and modify.
Full Changelog: 0.133.1 on GitHub