Introduction
Screeps GPT 0.197.11 delivers a major leap forward in runtime type safety by introducing a comprehensive type guard system that dramatically reduces unsafe type assertions across the codebase. This release eliminates 40+ instances of unsafe as type casts in behavior controllers—replacing them with validated type guards and centralized helper functions. The result is a more maintainable, reliable runtime that catches type errors early and provides clear failure modes when objects don’t match expected types.
Key Features
Type Guards Module
New file: packages/bot/src/runtime/types/typeGuards.ts
This release introduces a complete suite of runtime type validation utilities that replace scattered, unsafe type assertions throughout the codebase. The new type guards module includes:
- Predicate-based type guards: Functions like
isCreep(),isSource(),isStructure(),isSpawn(),isContainer(), andisTower()that return boolean values and narrow TypeScript types - Validation helpers: Functions like
asCreep()that throwTypeErrorwith descriptive messages instead of silently passing invalid objects through the system - Type-safe
room.find()wrappers: Convenience functions likefindActiveSources(),findAllSources(),findMySpawns(),findHostileCreeps(),findMyCreeps(),findDroppedResources(),findContainers(), andfindTowers()that combine room queries with type validation in a single call
All type guards follow a consistent pattern:
1 | // Predicate-based guard |
This approach provides three levels of safety:
- Zero-overhead checks when types are statically known
- Runtime validation when types are uncertain
- Clear error messages when validation fails
Behavior Controller Refactoring
Reduced unsafe type assertions from 50+ to ~10 instances (#1565)
The introduction of the type guards module enabled a systematic cleanup of unsafe type assertions across 14 role controllers. This refactoring addresses a long-standing technical debt issue where type safety was sacrificed for convenience.
Before (unsafe):
1 | const creep = Game.creeps[creepName] as Creep; |
After (type-safe):
1 | const creep = asCreep(Game.creeps[creepName], `role controller ${role}`); |
The refactoring focused on:
- HarvesterController, HaulerController, UpgraderController, BuilderController, RepairerController: Replaced
creep as Creepwith validatedasCreep()helper - helpers.ts: Consolidated scattered type assertions into centralized, reusable type-safe helpers
- All role controllers: Replaced array type assertions (
as Source[],as StructureSpawn[]) with type-safe find wrappers
Test Coverage
24 unit tests added for type guards functionality
The type guards module includes comprehensive test coverage validating:
- All predicate-based type guards return correct boolean values
- All validation helpers throw
TypeErrorwith descriptive messages for invalid inputs - All type-safe find wrappers correctly filter and validate results
- Edge cases like
null,undefined, and incorrect object types
Technical Details
Design Rationale
The type guard system was designed to solve a specific problem in the Screeps GPT codebase: unsafe type assertions that masked runtime errors. Prior to this release, the codebase relied heavily on TypeScript’s as operator to cast game objects to specific types. While this satisfied the type checker at compile time, it provided zero runtime safety—if the object wasn’t actually the expected type, the code would fail silently or crash with cryptic errors.
This pattern was particularly problematic in behavior controllers, where:
- Creep lookup failures (
Game.creeps[name]returningundefined) would pass through unchecked - Room queries could return unexpected object types when structures were destroyed or replaced
- Error messages were unhelpful because the failure occurred deep in the call stack, far from the type assertion
The type guard system addresses these issues by:
- Centralizing type validation in a single module with consistent patterns
- Providing explicit validation points where objects enter the system
- Generating clear error messages that include context about where validation failed
- Enabling incremental adoption through both predicate and validation helper patterns
Implementation Choices
Why Not Use Zod or Other Runtime Validation Libraries?
While libraries like Zod provide powerful runtime validation, they come with significant overhead in bundle size and CPU usage—critical concerns in the Screeps environment where every byte and CPU tick matters. The type guard system provides the essential validation needed for game objects without the cost of a full validation framework.
Why Both Predicates and Validation Helpers?
The dual approach (predicates like isCreep() + validation helpers like asCreep()) serves different use cases:
- Predicates are used in filtering and conditional logic where you want to handle both valid and invalid cases
- Validation helpers are used at system boundaries where an invalid object indicates a bug that should halt execution immediately
This gives developers flexibility to choose the appropriate validation strategy for their specific context.
Why Type-Safe Find Wrappers?
Screeps’ room.find() API returns arrays of game objects, but TypeScript’s type system can’t guarantee those objects are actually the expected type at runtime. The type-safe wrappers combine the query with validation in a single call, reducing boilerplate and ensuring type safety at the query boundary.
Architectural Improvements
This release establishes several architectural patterns that improve code quality across the repository:
- Centralized type validation: All type checks now flow through a single module, making it easy to audit and enhance validation logic
- Consistent error handling: All validation failures throw
TypeErrorwith descriptive messages, making debugging easier - Testable validation: Type guards are pure functions that can be tested in isolation without mocking the Screeps API
- Progressive migration: The existing unsafe type assertions remain in place (reduced to ~10 instances) until they can be safely migrated to type guards
Files Changed
- New file:
packages/bot/src/runtime/types/typeGuards.ts- Type guard utilities (24 unit tests) - Modified: 14 role controller files - Replaced unsafe type assertions with validated helpers
- Modified:
packages/bot/src/runtime/behavior/helpers.ts- Migrated to type guard utilities
Impact
Code Maintainability
The type guard system dramatically improves code maintainability by:
- Reducing cognitive load: Developers no longer need to mentally track whether objects have been validated
- Preventing silent failures: Invalid objects now fail fast with clear error messages instead of causing cryptic errors downstream
- Centralizing validation logic: All type checking happens in one module, making it easy to enhance or audit
Runtime Reliability
By catching type errors early at system boundaries, the type guard system prevents entire classes of bugs:
- Undefined creep lookups:
asCreep()throws immediately if a creep doesn’t exist, instead of lettingundefinedpropagate - Invalid room queries: Type-safe find wrappers filter out unexpected objects before they enter business logic
- Clear failure modes: When validation fails, the error message includes context about where and why
Development Velocity
The type guard system accelerates development by:
- Reducing debugging time: Clear error messages point directly to the source of type mismatches
- Enabling safer refactoring: Type guards provide guardrails when restructuring code
- Improving test coverage: Type guards are easy to test in isolation, improving overall test quality
What’s Next
This release establishes the foundation for further type safety improvements:
- Complete migration: The remaining ~10 unsafe type assertions will be migrated to type guards in future releases
- Enhanced validation: Additional type guards can be added for other game object types (links, labs, observers, etc.)
- Performance optimization: Type guard overhead can be measured and optimized if needed
- Broader adoption: Type-safe patterns established here can be applied to other parts of the codebase
The type guard system also unblocks work on the state machine migration (#1267) by providing reliable type validation for state machine inputs and outputs.
Release Date: 2025-11-30
Commits: See CHANGELOG.md for full details
Issue Reference: #1565