Difference between revisions of "Maturity Matrix"
Line 36: | Line 36: | ||
=== First Found Filling === |
=== First Found Filling === |
||
When first filling extensions, generally users have either harvesters or dedicated field fillers that look for energy then seek a target to fill. Generally the 'first empty' target is considered, which can be improved byPath or byRange considerations. Depending on implementation and extension field setup this can mean the creep either passes by, misses, or does not consider the most optimal route when filling. |
When first filling extensions, generally users have either harvesters or dedicated field fillers that look for energy then seek a target to fill. Generally the 'first empty' target is considered, which can be improved byPath or byRange considerations. Depending on implementation and extension field setup this can mean the creep either passes by, misses, or does not consider the most optimal route when filling. |
||
+ | |||
⚫ | |||
⚫ | It is quite possible, when haulers of energy are transporting energy to-and-fro that they will come across an extension or extension field in their route. If they are already hauling this energy to be used in the execution of filling and other tasks, why not fill on the fly? By searching their immediate area, if an empty spawn/extension is found a hauler can sporadically choose to execute a transfer operation even while moving as long as the transfer was valid when called. This cuts down on dedicated fillers having to execute on searching/pathing to an extension and speeds up fill time, but can cut down on the efficiency of some field filling routes. |
||
=== Field and Route Filling === |
=== Field and Route Filling === |
||
Line 43: | Line 46: | ||
A capacitor generally as an electronic component stores electrical energy then discharges it. In concept of extension filling, it is possible to have larger carry size creeps with few-to-no move parts that 'sit' in one space nearby a source of energy (container, storage, ect) then when extensions are used by the spawning process the capacitor creep then feeds on the source of energy and distributes it to the surrounding extensions/spawns without ever having to move. Haulers / other creeps can refill the reserves of the capacitor system, meaning the capacitors themselves only have to execute on withdraw and transfer intents, no pathfinding needed and generally very rapid without having to travel to find energy/a place to put it. |
A capacitor generally as an electronic component stores electrical energy then discharges it. In concept of extension filling, it is possible to have larger carry size creeps with few-to-no move parts that 'sit' in one space nearby a source of energy (container, storage, ect) then when extensions are used by the spawning process the capacitor creep then feeds on the source of energy and distributes it to the surrounding extensions/spawns without ever having to move. Haulers / other creeps can refill the reserves of the capacitor system, meaning the capacitors themselves only have to execute on withdraw and transfer intents, no pathfinding needed and generally very rapid without having to travel to find energy/a place to put it. |
||
+ | == Upgrading a Controller == |
||
⚫ | |||
+ | |||
⚫ | It is quite possible, when haulers of energy are transporting energy to-and-fro that they will come across an extension or extension field in their route. If they are already hauling this energy to be used in the execution of filling and other tasks, why not fill on the fly? By searching their immediate area, if an empty spawn/extension is found a hauler can sporadically choose to execute a transfer operation even while moving as long as the transfer was valid when called. This cuts down on dedicated fillers having to execute on searching/pathing to an extension and speeds up fill time, but can cut down on the efficiency of some field filling routes. |
||
+ | === Harvester & Generic Creeps === |
||
+ | As presented in the form of a 'harvester' or 'upgrader' in Screep's Tutorial, mainly these are creeps that gather energy opportunity wise and pump it into the controller. This works well to start, however does mean that they have to mine and pathfind to the source of energy and back to the controller |
||
+ | |||
+ | === Static upgraders === |
||
+ | Static upgraders can pull from a source of energy (container,storage,terminal ect) and only focusing on upgrading. As Withdraw and UpgradeController are non-conflicting actions, it is possible to consistently pull from the source of energy (when upgrading would put the creep below the lowest amount) and upgrade the controller at the same time. This means the upgrader needs fewer move parts and really, only one carry part as even a 49 part work creep still needs a carry party to use energy from, and as they store 50 energy, can only ever use 49 energy a tick. |
||
+ | |||
+ | === Temple rooms, praising and boosts === |
||
+ | Though the use of boosts, it is possible to use the same amount of energy but get more 'points' into a controller. Combined with whats known as 'praising' at a temple room, a user can have creeps consistently pump energy into a controller to gain Global Control Level points and speed up progression. |
||
+ | |||
+ | == Building Structures == |
||
+ | |||
+ | === User Placed Structures === |
||
+ | |||
+ | === Queue Placed Structures === |
||
+ | |||
+ | === Fully Automatic / Automated Plan Structures === |
||
== Harvesting Energy == |
== Harvesting Energy == |
||
Line 83: | Line 102: | ||
== Creep Combat == |
== Creep Combat == |
||
+ | // Break down into 'Creep Combat managment' vs 'spawning combat creeps'? |
||
+ | |||
+ | === User-Spawned Defenders/Attackers === |
||
+ | |||
+ | === Automatic Spawning & Defending === |
||
+ | |||
+ | === Fully Automatic Dynamic Spawning === |
||
+ | |||
+ | ==== Time To Kill / Time to Die ==== |
||
+ | |||
+ | === Find Closest & Attack === |
||
+ | |||
+ | === Kiting & Ranged combat === |
||
+ | |||
+ | === Duo-combat === |
||
+ | |||
+ | === Quad-Combat === |
||
+ | |||
+ | == Observability (Logging & Statistics) == |
||
+ | |||
+ | === Console.log() and basic debugging === |
||
+ | |||
+ | === Room Visuals & Map Visuals === |
||
+ | |||
+ | === Web API & External Tool logging / visualization === |
||
+ | |||
+ | == Factory Management == |
||
+ | |||
+ | === Mimnum filling & manual orders === |
||
+ | |||
+ | === Chaining & multiple tier managment === |
||
+ | |||
+ | === Full automatic production, balancing and T5 production === |
||
== Lab Logistics == |
== Lab Logistics == |
||
+ | |||
+ | === User Generated demands === |
||
+ | |||
+ | === Recipe demand === |
||
+ | |||
+ | === Fully automatic Recipe switching & lab configuring === |
||
+ | |||
+ | == Terminal Logic == |
||
+ | |||
+ | === Basic filling & hard coded / console transfering/dealing === |
||
+ | |||
+ | === Task based / need based filling & transfering/dealing === |
||
+ | |||
+ | === Fully automatic task-based system === |
||
== Creep Movement (Pathfinding) == |
== Creep Movement (Pathfinding) == |
Revision as of 17:12, 10 January 2022
While developing your bot, there many, many different implementations different systems can use. Some are more efficient than others, comparing your progress to other such implementations can be useful to gauge where you are and how far you have to go. It is important to remember, that Screeps is a sandbox however, if something works for you and your happy with it, use it. However, if you are looking to improve a system, or just wondering how your implementation can compare then you may find this useful.
Structure
This article will be broken up into various game 'systems' that a bot normally has. Each system will then list different implementations generally from 'least efficient' or 'easiest to code' to 'most efficient' or 'hardest to code'. This will vary by user, of course, some things may be on-par or similar to other implementations efficiency wise, or be a small part to add on not necessarily a full rework.
Spawning Creeps
Hard-Coded & Console Generated
The first stage for spawning creeps introduced in Screep's tutorial. Creeps can be generated by a user typing the information out into the console, and subsequently spawning the creep, or hard-coding it into the main or other modules. This is very easy, as it is mostly user controlled but not very robust. If data changes in-game (say, a spawn in destroyed) the hard-coded item will cease to function, and a user can only spend so much time without having to fulfil other requirements than spawning creeps, like eating, or sleeping.
If & Else-If Chain & Filter Head-count
Introduced in Screep's Tutorial, this implementation centers around getting a head-count for currently living creeps then going though either a set of IF statements or a chain of IF ELSE IF statements looking for a (normally) hardcoded value. When a discrepancy is found, a spawning call is put out and a creep is spawned. This system can be further improved by optimizing how and when the headcount is done, vs how long / how many statements are checked. This implementation does tend to run into challenges when the number of roles/type of creeps a user is spawning gets past a certain point.
Library Object & Looping
A further evolution of the spawning system, by keeping an 'object' of paired role/type names along with quantities or other data a user can thereby implement a looping architecture to iterate though the object, using the contained data to fetch counts, and compare needs. This can then be further evolved by a management system adjusting counts as needed by pressures of the environment on the colony so that a balance of creeps of many times is maintained when they are needed, or counts reduced when they are not.
Queue System
Instead of looking down a list of 'highest priority' strictly on an object, a management system can go though its own processes to determine what 'needs to be' spawned next, then simply push it to a queue that the 'spawning system' can execute on when it can, or adjust as needed.
Dynamic Energy Considerations
Another part though not normally a major overhaul, depending on colony/room need some times it is imperative that certain creeps are replenished but not necessarily always at the maximum size. Having a user's spawn system know this, and take into account when it needs to 'make do' with what energy is at hand is useful to maintain a constant operation.
Examples Include:
- Catch-up - If a user's spawn/extension filler(s) have perished and no creep is going to take over, a creep needs to be spawned to do so, even if the 'normal size' is not available due to energy.
- Cold boot / Recovery - If something catastrophic has happened, and a user is not getting any more energy, the spawn system can take this into account (either by measuring income or by measuring reserves) and spawn with what it has to recover accordingly.
Dynamic Part Generation
Normally implemented along-side systems that keep track of things such as Hauling Logistics, Defense/Combat creeps, or other such systems. Dynamic Part Generation takes into account not only that a creep needs to be spawned, but what size and composition it needs to be. Examples include:
- Hauling Logistics - How many 'total carry parts' required to haul energy for a room (or chain of rooms), by how many creeps required/exist (as dependent on RCL creeps can only be so large due to energy requirements) and what energy is available now.
- Combat Logistics - How many 'total combat parts' are required to defeat the enemy defenses / enemy creeps? What configuration/order? Spread out over how many creeps?
Extension & Spawn Filling
First Found Filling
When first filling extensions, generally users have either harvesters or dedicated field fillers that look for energy then seek a target to fill. Generally the 'first empty' target is considered, which can be improved byPath or byRange considerations. Depending on implementation and extension field setup this can mean the creep either passes by, misses, or does not consider the most optimal route when filling.
Sporadic and Opportunity filling
It is quite possible, when haulers of energy are transporting energy to-and-fro that they will come across an extension or extension field in their route. If they are already hauling this energy to be used in the execution of filling and other tasks, why not fill on the fly? By searching their immediate area, if an empty spawn/extension is found a hauler can sporadically choose to execute a transfer operation even while moving as long as the transfer was valid when called. This cuts down on dedicated fillers having to execute on searching/pathing to an extension and speeds up fill time, but can cut down on the efficiency of some field filling routes.
Field and Route Filling
By having predictable extension fields or a dynamic path generator around given fields, when coupled with the spawn's ability to pull energy from a set order of spawns/extensions it is possible to fill extensions in a 'route' such as the creep starts at a designated point then proceeds along the route filling extensions/spawns as it goes cutting down on searching/pathing and speeding up the filling.
Capacitor Filling
A capacitor generally as an electronic component stores electrical energy then discharges it. In concept of extension filling, it is possible to have larger carry size creeps with few-to-no move parts that 'sit' in one space nearby a source of energy (container, storage, ect) then when extensions are used by the spawning process the capacitor creep then feeds on the source of energy and distributes it to the surrounding extensions/spawns without ever having to move. Haulers / other creeps can refill the reserves of the capacitor system, meaning the capacitors themselves only have to execute on withdraw and transfer intents, no pathfinding needed and generally very rapid without having to travel to find energy/a place to put it.
Upgrading a Controller
Harvester & Generic Creeps
As presented in the form of a 'harvester' or 'upgrader' in Screep's Tutorial, mainly these are creeps that gather energy opportunity wise and pump it into the controller. This works well to start, however does mean that they have to mine and pathfind to the source of energy and back to the controller
Static upgraders
Static upgraders can pull from a source of energy (container,storage,terminal ect) and only focusing on upgrading. As Withdraw and UpgradeController are non-conflicting actions, it is possible to consistently pull from the source of energy (when upgrading would put the creep below the lowest amount) and upgrade the controller at the same time. This means the upgrader needs fewer move parts and really, only one carry part as even a 49 part work creep still needs a carry party to use energy from, and as they store 50 energy, can only ever use 49 energy a tick.
Temple rooms, praising and boosts
Though the use of boosts, it is possible to use the same amount of energy but get more 'points' into a controller. Combined with whats known as 'praising' at a temple room, a user can have creeps consistently pump energy into a controller to gain Global Control Level points and speed up progression.
Building Structures
User Placed Structures
Queue Placed Structures
Fully Automatic / Automated Plan Structures
Harvesting Energy
Harvesters
Harvesters and 'on demand' source mining roles as shown in Screep's tutorial are the first most common implementation of creeps acquiring energy. When a creep needs energy, it seeks out a source acquires the energy needed then moves on. While easy to implement, this often leave sources with energy left-over in them when their regeneration timer goes off, meaning that it is 'wasted' (not used).
Drop-Mining & Static Harvesting
Static harvesters are a big step when it comes to maximizing energy for a room, with a creep or creeps dedicated to harvesting a source, a user can normally drain it long before the regeneration timer lapses meaning the maximum amount of energy is pulled from the source to be used. The first step is normally drop mining where the energy is dropped to the floor, some energy may be lost in this implementation as energy evaporates/sublimates (decays) and is lost forever. However, creeps when needing energy can instead move to these piles to collect energy without having to mine it.
Container Mining & Hauler Logistics
Container mining is a big step in insuring that the decay of the drop mining/static harvesting method is lessened though some investment must be made into the container as its hits will decay and require repair at a rate dependent on the state of the room (Owned/Unowned). To drop mine into the container, a creep also has to specifically select a location to stand, and always stand on to insure the energy is property dropped into the container.
Remote Mining
Once a room's energy has been harnessed, energy from other rooms can be as well. This becomes more complex due to having to assign miners to multiple rooms, getting them to the rooms (pathing), building and maintaining containers, reserving the room to increase the energy, and various other tasks.
Source Keeper Mining
Currently the hardest challenge when it comes to gathering energy. While source keeper's (SK's) rooms are very energy rich, and even include a mineral with a public extractor to mine resources from they are always guarded by SKs generated from SK lairs paired with each source. As well invasions in these rooms still occur and with stronger invaders as well as Invader Strongholds which have a chance to spawn.
To mine a SK room you generally need:
- A way to kill the keepers consistently
- Miners that know to avoid danger
- Haulers that know to avoid danger
- A way to deal with, or avoid invasions
- A plan for how to deal with or avoid Strongholds
Hauling Logistics
Opportunity Gathering
Generally when first starting on hauling energy around to either store or use, the first implementation tends to be having creeps seek out sources (such as piles of energy, containers with energy or storages) and then transporting to some centeralized location dependent on the creep's function (container/drop -> storage or storage -> controller to use for upgrading, ect). without consideration of other creep(s) actions.
Mining / Hauler Pairs
Another implementation is to have every container/drop miner have its own 'twin' hauler, this way there is not a conflict in different haulers going for similar tasks, but depending on how they are managed does mean the creep may have downtime or be waiting for a miner to spawn, or other situations in where it could do something else while 'waiting'
Task execution
When using a Top-Down or Management based approach haulers generally execute on tasks that they are assigned by their manager. The manager takes care to not have conflicts and assign tasks as-needed.
Creep Combat
// Break down into 'Creep Combat managment' vs 'spawning combat creeps'?
User-Spawned Defenders/Attackers
Automatic Spawning & Defending
Fully Automatic Dynamic Spawning
Time To Kill / Time to Die
Find Closest & Attack
Kiting & Ranged combat
Duo-combat
Quad-Combat
Observability (Logging & Statistics)
Console.log() and basic debugging
Room Visuals & Map Visuals
Web API & External Tool logging / visualization
Factory Management
Mimnum filling & manual orders
Chaining & multiple tier managment
Full automatic production, balancing and T5 production
Lab Logistics
User Generated demands
Recipe demand
Fully automatic Recipe switching & lab configuring
Terminal Logic
Basic filling & hard coded / console transfering/dealing
Task based / need based filling & transfering/dealing
Fully automatic task-based system
Creep Movement (Pathfinding)
moveTo
moveTo is the main pre-packaged solution when it comes to pathfinding, a user mainly only has to set a target desired to 'move to' and the function takes care of the pathing, caching and executing of the movement all in one. This is a powerful function that will carry a user far, however possibly by design it is not 'perfect' allowing the user to get familiar with the movement system and evolve past it in the future.
adding Options to moveTo
moveTo allows for various opts or 'options' to be passed as an argument in the form of an object along with the target you are looking to move to. These options can have a huge impact on the way moveTo itself acts and behaves allowing for more complex/efficient movement.
reusePath
by default, moveTo will cache and use the results of 'new' moveTo request for 5 ticks, or when it crosses a exit tile (as paths are only cached an encoded string 'in room'). This behavior can be modified by passing an object with the property reusePath
along with a numerical value of the amount of game ticks the user wishes the function to reuse the cached path. Depending on how far away the target is, or the complexity of the room(s) considered, repathing every 5 ticks can become costly when many creeps are considered. Increasing this, means that you have creeps that will reuse the path for longer but will react slower to pathing obstructions. This is up to the user to resolve normally in the form of collision management.
ignoreCreeps & Collision management
by default, moveTo will consider creep objects found when pathingfinding as 'impassable'. This means that it will attempt to pathfind around the creep found in the path, which can result in higher costs, even though the creep in the path is moveable, or may have moved by the time the creep arrives at that step in the path. The ignoreCreeps
option allows for a user to as the name suggests, tell moveTo to ignore creeps when considering blockages/obstacles in the path. This generally allows for faster/shorter routes to be found as in a crowded base or a long busy areas of road creeps can often be found.
However, if the creep in question blocking the path remains, that is where collision management comes in. moveTo will continue to attempt to execute the next step in the path, even though the path is obstructed meaning the creep does not move. Implementing a system that detects when a path obstruction/blockage/collision has occurred, and then resolving it helps fix this issue as insures that the creeps are taking the 'shortest route'
range
by default, the moveTo will attempt to path 'onto or near' the object it is targeting. However, there are times when moving between rooms or to certain areas that the user's creeps do not need to necessarily worry about being so precise. For example, a creep traveling to a distant room to scout without vision does not need to path to any particular tile to do so, just enter the room. This is where the range
option comes in handy, the pathfinding of moveTo will attempt to find a pathable location 'in range' of the target provided meaning many operations of pathfinding can be saved thus saving CPU.
maxRooms and maxOps
While not necessary in most use-cases, these two operations are important in several specific functions. For example with maxRooms, you can tell the moveTo function to only consider X number of rooms when pathfinding. If you have a creep, for example, that you want to only ever stay within its home room for whatever reason, then you can pass a maxRooms opt of 1 and it will not attempt to path outside of the room to get to any given target (even if it is a shorter path). As well, maxOps allows the user to set the maximum number of operations while pathfinding, when going a far distance or a complex path, increasing the number of maxOps opt will allow it to run for longer hopefully finding a path. This does, however, use more CPU.
costCallback and PathFinder.CostMatrix
by default, the moveTo system will use the built in PathFinder in screeps to create and cache (when necessary) CostMatricies for a user's creeps to use when using moveTo. With the costCallback option however, a user can provide a customized cost matrix to be used instead of the default one that is generated/cached. This is probably the more complex of the options and likely the last step before moving on beyond the confines of moveTo. The user must make a costMatrix for a room considering (or not considering) all impathable objects, this can include custom values for whatever locations the user desires either to fully obstruct or allow passage though. An example, say the user has dedicated static mining creeps that should not move, or be moved. As such, even though the container they stand on is passable, or the creep passable if ignoreCreeps is on, the user can modify the costmatrix for the room to make this location impassable so the creeps do not consider it when trying to move, allowing the miner to continue without being obstructed, moved ect.
PathFinder.search
This is the base function that as-of-writing all other pathfinding functions in Screeps uses. It is by far the most powerful solution to pathfinding given by the API. It requires the user to be far more specific when passing options but allows for a wide flexibility of path generation options.
Path Caching & moveByPath
Generally once a user has become familiar with the pathfinder system, they can begin storing paths to be reused along common routes. An example would be a miner is always assigned to X source, and spawns from a spawn. The route is always the same, or becomes the same once they reach a certain point along the path. This path can be found, cached, and then reused by moveByPath or a user's custom implementation to execute move commands so that instead of pathfinding every time, the user only has to pathfind the once, or once in a while (incase new structures or obstructions have been added) dramatically reducing CPU costs.
Node Networks & cached path assignment
Once paths have been cached, a user can then evolve into caching common routes or destinations to areas that can be reused by various creeps dynamically instead of by specific need. Mainly, a user needs to create this pathing network with a 'start' node and 'end' node or any other amount of 'nodes' they desire. A creep (or its management system) can then consider its position as well as the position of its assigned task (goal position, lets say) when looking for a path. If the goal position is within X distance of a pathing end, start, or other node and the creep is within Y of the 'other end' of the cached path / node pair then the creep can be assigned the cached path to use for traversing to nearby its target. This may require a short moveTo/pathing operation to snap to / affix to the path, but once on the path movebypath or a user's system of executing moves by the stored path can be used. The creep thereby didn't need to do the complex pathing operations to its target, only short jumps, saving CPU.
An Example:
A hauler creep is assigned a container in a remote harvesting room 2 rooms away, it is currently idling by the storage from a previous drop off. The hauler creep first looks at node(s) in the same room as its target, searching for the closest one to its assigned container, the creep then looks for the node(s) that pair with the desired node(s) for ones it is standing on or near to. Once found, it then moves to the 'start' node and once there, proceeds along the path till it is nearby its target (or closer enough to leave the 'rail' path).
Creep Action Management
Role Modules & Agent Based Approach
An agent based approach known as 'roles' is what is presented in Screep's Tutorial. Primarily, each creep is assigned a role via memory (normally as a string) which is used to then determine what module (normally of the 'same' or similar name) to have the creep execute. The creep then works though the module's logic to determine what to do and how to act. This works well in keeping creeps consistent and focused with their logic, however it does mean that unless otherwise programmed to do so, they only consider their own situation and also normally run checks multiple times instead of just once.
Top Down / Management based Approach
A Top-Down or Management based approach primarily means that instead of each creep being responsible for finding its own goals, targets, information and the like, it is instead assigned these things by a manager considering the entire picture. This enables the system to fetch data as-needed, pass it / use it over the span of multiple creeps instead of multiple times over creeps and even change creeps as needed.
An example:
A management system for assigning tasks for haulers beings its tick. It looks first for available haulers that do not have a task assigned to them, if found, it then proceeds to look at all available containers assigned to its room, filtering out any containers that are already assigned to other creeps already or that energy will be not enough for the task to be worth assigning. If containers were found, it then progresses though the available creeps, assigning them to containers as they are available. The creeps (or their own different management systems) then only act on their assigned task.