Error message since introduction of new architecture
-
I have the following setup in my Creep prototype definition:
_.assign(Creep.prototype,{ /* ... */, getAttackType : getAttackType, meleeAttack : Creep.prototype.attack, attack : attack_new, /* ... */ }
which basically maps the old
attack
to a new namemeleeAttack
and overwrites the existing name with a new attack method like seen below.function attack_new(target){ var attack = this.getAttackType(); if (attack){ return this[attack](target); } else { l.warn(this.name + "cannot attack - no suitable attack type found", l.info(this)); return ERR_NO_BODYPART; } }
This has been working like a charm for several months now. However, since the change to the architecture was introduced, I get a stack overflow error instead - however not in 100% of the time!
RangeError: Maximum call stack size exceeded at data (/opt/engine/dist/game/creeps.js:20:23) at Creep.Object.defineProperty.get (/opt/engine/dist/game/creeps.js:53:28) at Creep.getAttackType (Prototype_Creep:360:26) at Creep.attack_new [as meleeAttack] (Prototype_Creep:369:23) at Creep.attack_new [as meleeAttack] (Prototype_Creep:371:28) at Creep.attack_new [as meleeAttack] (Prototype_Creep:371:28) ...
Basically,
attack_new
instead of the "old"attack
method is now mapped tomeleeAttack
which causes the infinite loop. My guess is, that the occasional times it's working are the ticks when the global object is newly built, and the ticks afterwards it fails?
-
The only scenario I have in my head, where this could happen is when the global object is preserved for several ticks, but the code actually is executed more then once.
In that case, in the first tick after the initialization of the global object, the originalattack
method has been mapped tomeleeAttack
and after that,attack_new
is correctly mapped toattack
. In this tick, everything runs fine.
On the next tick however,attack
( which now effectively isattack_new
) is again mapped tomeleeAttack
, overwriting the originalattack
method, and thus creating an infinite loop until the global object is reset.
-
I experienced the same issues. Looks like the global object is indeed preserved, but not every tick. You may try to add some checks if you prototype is already extended, and please tell if it works.
Like that:
if(!Creep.prototype.meleeAttack) { _.assign(Creep.prototype,{ /* ... */, getAttackType : getAttackType, meleeAttack : Creep.prototype.attack, attack : attack_new, /* ... */ } }
-
@Rumatah this surely works, but it is not fixing the initial problem...