creep.push()



  • I love creep.pull(). For me this was one of the most radical changes to screeps and filled a big gap where it felt like something was missing.

    When this was introduced somebody suggested the idea of a correspondingcreep.push() (IIRC their desire was to push creeps forward into battle, which is a cool idea).

    I have been thinking about this a bit more and I think a corresponding creep.push() would be a big help. One of the more fiddly things about using pull() is crossing room boundaries. Whilst it's an interesting challenge to implement at first, it just ends up feeling messy and unsatisfying, with creeps having to do this elaborate dance and taking 5 ticks to move across instead of 2.

    With push(), this could be reduced to 4 ticks: pull up to the exit then (1) pull/swap, (2) push trailer onto exit, (3) move onto exit, (4) move off exit, ready to continue pulling again on tick 5. It's much more natural.

    If you were already pushing up to the exit then it's literally just 2 ticks, although you'll be pulling on the other side, but it only takes 2 ticks to go from pulling to pushing and you can do it at your leisure anywhere in the room without having to dance around the exit portals.

    I haven't worked out what would happen for longer trains, but I'm sure it would make life MUCH easier and faster. A really interesting feature of push() would be the ability to have a creep pulling at the front of the train and another creep pushing at the back. With this setup it might be possible to move a train across a room boundary without doing any swapping.

    Another potential use of push() would be for dealing with tricky traffic situations. As it stands, if a tug/trailer pair enters a heavy traffic area it can be a real nightmare. If two pairs meet there is no hope. With push() you've got many more options to resolve the situation.

    I propose it should work as follows:

    1. As the one in front, the "wagon" calls move(pos) to decide where to move. The pushing creep calls push(wagon), which causes it to move to the wagon's current position, and transfers the fatigue like pull().
    2. The pushing creep always moves to where the wagon was to stay adjacent to it. If this is not possible for some reason, the push does not happen. If the wagon is capable of moving by itself then it can move away, but you cannot push a creep away from you to create a gap.
    3. It should be possible to push() a creep which is pushing another creep in front of it, just like you can pull() a creep that is pulling another creep behind it.
    4. A creep should be allowed to pull() creeps behind it and push() creeps in front at the same time (Wagon-Tug-Wagon).


  • I thought moving thru room boundaries resets fatigue.
    This still requires one move part on the pulled creep but your are down to 2 ticks in that case.

    From the looks of it most of your scenarios could be resolved with that.

    I don't think it is necessary.



  • I thought moving thru room boundaries resets fatigue.

    I had no idea this was the case. This should really be added to the documentation.

    However, it still just feels like a hack, and it's not great having to add one MOVE part to every creep.

    And I really think it would be helpful to be able to "reverse" a creep train without swapping the tug to the front.



  • I was thinking maybe this can be linked to TOUGH parts; TOUGH parts are needed to push, and can push enemies and friendly. But you need to have more TOUGH than the creep being pushed.



  • @likeafox said in creep.push():

    I was thinking maybe this can be linked to TOUGH parts; TOUGH parts are needed to push, and can push enemies and friendly. But you need to have more TOUGH than the creep being pushed.

    Being able to push enemy creeps would be cool! But perhaps a bit unbalanced. Also, the API would be a problem - if you aren't in control of the creep being pushed, how do you decide which direction to go in? This would actually be easier to implement as a pull, and if you can push enemy creeps why can't you pull them as well?



  • I think you can pull a creep from behind! (AKA push).

    The _add-fatigue routine loops to the head of the pulled creeps and adds the fatigue there, as expected.

    Slightly unexpected the MOVE part decrease of fatigue via the same _add-fatigue routine with a negative value.

    That means a creep can "pull" a train from any position.

    A couple caveats:

    • The head of the train must have a MOVE part.
    • It's more intent efficient to have the all the MOVE parts at the head of the train if the train has too much fatigue to move every tick. You need to issue all the pull/move intents every tick to keep the rest of the train helping with the heads fatigue.
    • Edge traversal.