@SystemParadox What's actually happening here is that the console calls .toString() on the object (e.g. Creep.prototype.toString()). [...] The toString() function tries to get this.name, but it's a getter, and it throws an error if the object doesn't have this.id. Nice, yeah, I figured it would be part of the toString invocation. Good find! The heap - that is, global variables or module scoped variables as in your example. These will last until a "global reset" [...] OK, makes sense. I suppose not all of the docs have been updated since the introduction of iVMs. Thanks, that's useful! I do things like this a lot: Room.prototype.getRepairTargets = function () { if (! this._repairTargets) { this._repairTargets = this.find(FIND_MY_STRUCTURES, { filter: struct => struct.hits < struct.hitsMax, }) } return this._repairTargets; }; That way I can call this.room.getRepairTargets() on several different creeps but it will only call find once each tick. Right. I found that JS supports the same "decorator" syntax as Python (a language with which I am much more familiar!) and I figured out how to write a decorator to seamlessly memoize the results of a property descriptor's getter, with the goal of simplifying this common pattern. I use it like: class MyRoom { @memoize get repairTargets() { return this.find(FIND_MY_STRUCTURES, { filter: struct => struct.hits < struct.hitsMax }); } } @SemperRabbit That tracks with what I'm learning - I might make a Proxy of my own. Thanks for your input!