How can I detect that I have respawned ?



  • Hi,

    I would like to do certain things once, every time I respawn in the multiplayer world : some computations, set ups and such, but I can't find a way to do it. Game.time==0 only works in simulation, because the ticks keep going in multiplayer.

    What I've done so far feels weak and isn't automatic : manually setting a boolean in the console every time I restart.

    Any ideas ? Have you ever needed this ?



  • if (!Memory.some.random.thing) {

      Do all the things

      Memory.some.random.thing = "Sorted"

    }



  • Well yeah, that's more or less the boolean I was talking about. That works the first time, but in Screeps, Memory remains the same unless told otherwise, doesn't it ? When I respawn after that, Memory.some.random.thing will still keep its value, and therefore won't go in the if, right ? Or am I missing something ?



  • Maybe count your creeps and structures? If there is only the spawn then you respawned...



  • There're 2 ways to keep things in memory.

    First a persistence one. You store what ever you want in Memory object as Heilos said. But it also has some useful alias with many game object such as creep and room. For example if you want to keep something only available to each room, you can use

    Game.rooms['E10N10'].memory.something = 'some value';

    When you spawn in new room your room data is new to that room. Same as creeps, you can store information or order for each creep you spawn by store it in Game.creeps['CreepName'].memory.order = 'attack-x,y'.

    These information store in Memory object are available through game loops.

     

    The other way to use memory is a none persistence one. Javascript allow you to add data to objects. For example

    Game.rooms['E10N10'].hostiles = Game.rooms['E10N10'].find(FIND_HOSTILE_CREEPS);

    Then you can use Game.rooms['E10N10'].hostiles in current game loop. This data exists only current game loop but it maybe useful to store some temporary or update-every-tick data. It save your CPU usage without call this function for every creep in that room.

     

    .  



  • This is what I managed to get :

    function newGame() {
        let roomNames = _.keys(Game.rooms);
        let res = false;
        if (roomNames.length === 1) {
            let onlyRoom = Game.rooms[roomNames[0]];
            if (typeof onlyRoom.memory.newGame === "undefined") {
                for (let oldRoom in Memory.rooms) {
                    delete Memory.rooms[oldRoom].newGame;
                }
                res = true;
                onlyRoom.memory.newGame = false;
            }
        }
        return res;
    }

     

    Haven't tested it much, but it looks fine, especially since you can hide the ugliness behind a nice if (newGame()).

    Bonus : it should not return true after massive attacks, leaving you with 0 screeps and only a spawn, which could make it look like it's a start.

    Mega bonus : it should work even if you spawn in a room you used to own.



  • I see, I'm not experience respawn yet so I don't know that all my previous memory data are still there.



  • My script just sets a special "start" flag you can check. Once I'm a few ticks into the game, I disable the init script anyway to save CPU.



  • How about summing the progress of your controller(s)

    _.sum(_.filter(Game.rooms, r=>{return r.controller && r.controller.my}), 'controller.progress') == 0

    you can also check if there is a controller with level > 1 before summing. 

    But the sum will be == 0 for some loops until the first progress is made. 

    If you need only the first loop you will have to combine this approach with the memory approach. 

    when == 0 (&& !first Loop gone) set "first Loop gone" (this is your first loop)

    then when > 0 set "first Loop gone" = false to wait for respawn again