Caching.md - Mirroar/hivemind GitHub Wiki
Caching
Hivemind uses a flexible caching system to optimize performance by storing frequently accessed or expensive-to-calculate data. Caching helps reduce CPU usage and avoid redundant calculations, but it's important to use it correctly to avoid bugs or stale data.
How the Cache Works
- The cache stores data under a unique cache key (a string identifier) for a specified interval (in ticks).
- When you request cached data, you provide a key, a maximum age, and a callback to generate the data if it's missing or expired.
- The cache system supports three main storage locations:
- Heap cache: Data is stored in the bot's heap memory. It is fast and efficient, but is lost on a global reset (e.g., code upload). Use
cache.inHeap
andcache.fromHeap
. - Memory cache: Data is stored in persistent
Memory
and survives global resets. Usecache.inMemory
andcache.fromMemory
. - Object cache: Data is stored on the
_cache
property of any object (commonly used for game objects like rooms or creeps to store calculated properties for the current tick only). Usecache.inObject
andcache.fromObject
.
- Heap cache: Data is stored in the bot's heap memory. It is fast and efficient, but is lost on a global reset (e.g., code upload). Use
Example Usage
import cache from 'utils/cache';
// Cache in heap for 10 ticks
const result = cache.inHeap('myKey', 10, () => expensiveCalculation());
// Cache in persistent memory for 100 ticks
const result = cache.inMemory('myPersistentKey', 100, () => fetchData());
// Cache on a room object for the current tick
const sources = cache.inObject(room, 'sources', 1, () => room.find(FIND_SOURCES));
Important Notes
- Never store game objects (like Creep, Room, or Structure instances) in cache. These objects are only valid for the current tick and will become invalid or cause errors if accessed later. Instead, cache their IDs or calculated properties and retrieve them using
Game.getObjectById
. - Choose the cache location based on how long you want the data to persist and how expensive it is to recalculate.
- Use unique and descriptive cache keys to avoid collisions.
- The
maxAge
parameter controls how often the cached data is refreshed. Shorter intervals mean fresher data but more CPU usage. - The cache interval is not fixed - the system will automatically adjust based on CPU usage and the current game state. This means that if the bot is under heavy load, it may skip some cache updates to prioritize critical tasks.
Best Practices
- Use heap cache for fast, per-tick optimizations that don't need to survive global resets.
- Use memory cache for data that is expensive to recalculate and should persist across resets.
- Use object cache for properties that are specific to a single game object (e.g., a room's sources or a creep's calculated path).
- Always cache serializable data (numbers, strings, arrays, plain objects), not game objects.