Trying to create creeps in a more dynamic way



  • Here i am again 🤗

    Rather than hardcoding the body of each role depending on the available energy, i'm trying to create my creeps in a more dynamic way, but for some reason it's not working.

    I'll simplify with only one role so it's lighter to read:

    let DefineCreep = {
        run: function(thisRoom, role, spawn){
            let creepAtt = {};
            let creepName = '';
            let creepBody = [];
            //If i define the body like in the commented line below, it works...
            //creepBody = [CARRY, MOVE];
            //But won't work like this....
            creepBody = this.CreateBody(thisRoom, role);
            switch(role){
                case 'hauler':{
                    creepName = 'Hauler';
                    let haulerAtt = {role: 'hauler', mySpawn: spawn.name, myRoom: thisRoom.name, born: Game.time, task: 'loading', ticksToDie: 20 };
                }break;
                //Rest of the roles...
            }
            let result = [creepName, creepAtt, creepBody];
            //THIS IS WHAT I USE TO SPAWN THE ACTUAL CREEP
            return result;
        },
    
        //And this is the part that is not working...but not throwing any error :(
        CreateBody: function(thisRoom, role){
            let maxEnergy = thisRoom.energyCapacityAvailable;
            let maxBodyParts;
            let basicBodyParts = [];
            let basicBodyCost;
            switch(role){
                case 'hauler':{
                    basicBodyParts = [CARRY, MOVE];
                    basicBodyCost = 100;
                    maxBodyParts = 20;
                }break;
                //Rest of the roles...
            }
            
            let body = [];
            while(maxBodyParts >= basicBodyParts.length && maxEnergy >= basicBodyCost){
                body.push(basicBodyParts);
                maxEnergy -= basicBodyCost;
                maxBodyParts -= basicBodyParts.length;
            }
            return body;
        }
    }
    

    If i don't call CreateBody() and just define the body manually it works, and it's actually the way i was doing so far. But it won't work like this.

    I also tried to call CreateBody() from main.js with same parameters and then printed the body in the console, and it looks like it's creating the body fine.

    Can you guys help my find the reason? It's been 2~3 hours already trying to get it to work xD



  • Fuck my life....

    Given basicBodyParts was [CARRY, MOVE]

    Just replaced....

    body.push(basicBodyParts)
    

    with...

    for(let i in basicBodyParts){
        body.push(basicBodyParts[i];
    }
    

    I am hating this so much 😭



  • @calfa said in Trying to create creeps in a more dynamic way:

    with... for(let i in basicBodyParts){ body.push(basicBodyParts[i]; }

    i would suggest body.push(...basicBodyParts);



  • @saruss nope, you would nest arrays that way. But you could do:

    body.push.apply(basicBodyParts);
    

    The apply() is part of the function object/class and feeds a array as the parameters.



  • @mrfaul said in Trying to create creeps in a more dynamic way:

    @saruss nope, you would nest arrays that way. But you could do:

    body.push.apply(basicBodyParts);
    

    The apply() is part of the function object/class and feeds a array as the parameters.

    @MrFaul Nope, i would not nest arrays. Please read what that three small dots make there: (eg here: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/Spread_operator )



  • @saruss Ah crap yeah right, I'm mixing syntaxis again. I was by "var args" sry my bad, but that is just another example for "There is not one solution" ☺



  • It isn't that bad but you have a limit of 20 body parts. You can use 50 parts. (Saving CPU, less chaos in rooms and so on)



  • @mrfaul @Saruss Thank you so much guys! I dind't know that body.push(...basicBodyParts); thing (didn't know apply() either). Beyond the simplicity to use the three dots, i wonder if there's any improvement in the performance.

    @duckymirror I don't understand. I know there's a limit of 50 body parts but, where does the limit of 20 parts come from?



  • the "limit" is in your code but I think that is just your way of saving energy 🙂
    Just on a side note here there is a small but distinct difference between function(...something) and function.apply(something),
    since .apply() is part of the function object you can't use it on constructors since technically they are not functions yet but return one.
    The spread operator ... should work on most iterable objects since it is a discrete function and allows the use in constructors.

    var func = new constructor().apply(something); // throws error
    var func = new constructor(...something) // works fine
    


  • @mrfaul If i had money and lived in Germany i'd hire you as my teacher 😁

    I didn't realize you were talking about my own limit of 20 parts, but that was just an example. I don't even have a creep role called "hauler".

    Before i created that system to spawn creeps i was defining their bodies by switching available energy in the room and depending on the result, deciding what creep i was going to create. I had about 6 or 7 defined bodies for each role with different costs.

    Now i'm thinking that creating always the biggest possible creep (except for miners) is not the best idea, and this is what i'm on now.

    Thanks again for sharing so much wisdom!!

    Will be back soon with more doubts hahaha probably before the end of the night 😛