Simultaneous Actions Clarification



  • New player questions. The official docs on Simultaneous Actions are not especially clear. The image and the code example seem to contradict each other. There is no mention of order of execution. (Presumably it follows the code?) What about hostile creeps/towers? (If a tower shot would kill my creep, but it also heals itself enough to still have hp, what happens?) What does it mean when build & repair listed in all three 'rows'?

    I'd rather not have to test/read the source in order to understand the action system, so I'm hoping there's a better description written up somewhere.



  • The docs article you link is about answering the question: which actions can 1 creep simultaneously within a single tick?
    That means that order of execution indeed isn't answered there: just if something executes. For example, it shows you cannot build() and repair() in 1 tick with the same creep, but you can rangedAttack() and heal() (not rangedHeal()).

    Execution order is little tricky. Regarding damage, you can consider all attacks and heals to occur at the same time. newHits = hitsLastTick + receivedHealing - receivedDamage, so you can save your creep by healing it at the same time it receives damage. In fact, "pre-healing" is a common part of how to attack rooms with defending towers.

    Some other intents like moves are more tricky. If two creeps want to move to the same tile, it's pretty random which one gets it.



  • I understand what the image is attempting to convey. It still does a poor job of it, and doesn't even cover all of the things a creep can do (such as move). It also implies you can't transfer & drop in a single tick, but then the example below contradicts that. Which is it? What does the caveat "When the total energy amount is not enough" actually applied to?

    Also, for a page titled "Simultaneous execution of creep actions", I would expect something about how actions of different interact. I specifically want to know if the order that the actions (of all creeps) that are produced in my code is precisely the order they are applied, especially with regards to movement.


  • TMB

    Movement is applied last, and doesn't block any other action applied to or by the creep. If something is in range of an attack, you're guaranteed to hit even if it moves away.

    When a creep does multiple actions at once, I'm not sure in what order they are executed. Looking at how some of my creeps work, I believe that action that remove resources from the creep are consistently called before actions that refill the creep :

    • When my static harvesters are full, they can both drop their whole cargo into a container, then harvest in more resources within the same tick.

    however

    • When my static upgraders are empty, they may gather energy from a container but cannot use that same energy to upgrade the controller within the same tick.


  • I agree that that page is not very clear and that are things that I'd expect to find there, but aren't there (like resolution of conflicting move, withdraw and transfer intents). Some of your questions are answered there, if you read very carefully. That diagram shows dependencies between actions, if an action is not there (like move) , it's independent from the others. I find the last line misleading, but if you read the text that follows, it explains (sort of) that, unlike the other lines, a creep can perform one action from each box in it, as long as it carries enough energy for all of them. It will perform the actions, from right to left, until it runs out of energy. AFAIK, the order in which you add the intents doesn't affect how they get resolved (aside from calling the same method for the same creep, which actually just overrides the previous intent).



  • Based on the code, it appears to be pretty much completely random. In a room, intents are processed by user, in whatever order the database decides to give it. If there is any order to the users, it would be whichever user the Screeps server decides to run first. In 90% of cases, when intents conflict, the one processed first takes priority. The remaining 10% is handled in the post-tick events (check tick.js in one of the directories here).



  • Thanks for the info. This helps clarify things a whole lot.