From 9c8f9f91fa6b1c25ee2a1d1e5c3c2e4861639e05 Mon Sep 17 00:00:00 2001 From: winrid Date: Tue, 27 Sep 2022 15:53:59 -0700 Subject: [PATCH 1/4] Easy Performance Improvements (Reducing lodash filter and shallow clone in hot path) 1. Lodash _.filter is about twice as slow as Array.filter, same with _.map. 2. _.clone() is much slower than {...obj}. 3. Tried to only change things in hot path and where risk seemed low, and limit logic changes. --- src/game/rooms.js | 32 +++++++++---------- src/processor/global-intents/market.js | 8 +++-- .../intents/creeps/attackController.js | 6 ++-- src/processor/intents/creeps/build.js | 4 +-- .../intents/creeps/claimController.js | 4 +-- .../intents/creeps/invaders/findAttack.js | 18 +++++------ src/processor/intents/creeps/invaders/flee.js | 4 +-- .../intents/creeps/invaders/healer.js | 12 +++---- .../intents/creeps/invaders/shootAtWill.js | 2 +- .../intents/creeps/rangedMassAttack.js | 2 +- src/processor/intents/creeps/repair.js | 4 +-- .../intents/creeps/reserveController.js | 2 +- .../intents/creeps/upgradeController.js | 4 +-- .../intents/invader-core/stronghold/creeps.js | 4 +-- .../invader-core/stronghold/stronghold.js | 26 +++++++-------- src/processor/intents/movement.js | 4 +-- src/processor/intents/spawns/renew-creep.js | 2 +- src/processor/intents/spawns/tick.js | 2 +- 18 files changed, 71 insertions(+), 69 deletions(-) diff --git a/src/game/rooms.js b/src/game/rooms.js index f2bac2e1..dfd7c786 100644 --- a/src/game/rooms.js +++ b/src/game/rooms.js @@ -309,19 +309,19 @@ function _findClosestByPath2(fromPos, objects, opts) { objects = register.rooms[fromPos.roomName].find(objects, {filter: opts.filter}); } else if(opts.filter) { - objects = _.filter(objects, opts.filter); + objects = objects.filter(opts.filter); } if(!objects.length) { return null; } - var objectOnSquare = _.find(objects, obj => fromPos.isEqualTo(obj)); + var objectOnSquare = objects.find( obj => fromPos.isEqualTo(obj)); if(objectOnSquare) { return objectOnSquare; } - var goals = _.map(objects, i => { + var goals = objects.map(i => { if(i.pos) { i = i.pos; } @@ -364,11 +364,11 @@ function _findClosestByPath2(fromPos, objects, opts) { lastPos = ret.path[ret.path.length-1]; } - objects.forEach(obj => { + for (const obj of objects) { if(lastPos.isNearTo(obj)) { result = obj; } - }); + } return result; } @@ -646,10 +646,10 @@ exports.make = function(_runtimeData, _intents, _register, _globals) { } if(opts.filter) { - result = _.filter(result, opts.filter); + result = result.filter(opts.filter); } else { - result = _.clone(result); + result = [...result]; } return result; @@ -874,7 +874,7 @@ exports.make = function(_runtimeData, _intents, _register, _globals) { path, cacheKeySuffix = ''; - opts = _.clone(opts || {}); + opts = opts ? {...opts} : {}; if(opts.ignoreCreeps) { cacheKeySuffix += '_ignoreCreeps' @@ -1399,7 +1399,7 @@ exports.makePos = function(_register) { room = register.rooms[this.roomName]; if(_.isObject(secondArg)) { - opts = _.clone(secondArg); + opts = {...secondArg}; } opts = opts || {}; @@ -1428,7 +1428,7 @@ exports.makePos = function(_register) { RoomPosition.prototype.findClosestByPath = register.wrapFn(function(type, opts) { - opts = _.clone(opts || {}); + opts = opts ? {...opts} : {}; var room = register.rooms[this.roomName]; @@ -1522,7 +1522,7 @@ exports.makePos = function(_register) { throw new Error(`Could not access room ${this.roomName}`); } - opts = _.clone(opts || {}); + opts = opts ? {...opts} : {}; var objects = [], result = []; @@ -1531,14 +1531,14 @@ exports.makePos = function(_register) { objects = room.find(type, opts); } if(_.isArray(type)) { - objects = opts.filter ? _.filter(type, opts.filter) : type; + objects = opts.filter ? type.filter(opts.filter) : type; } - objects.forEach((i) => { + for (const i of objects) { if(this.inRangeTo(i, range)) { result.push(i); } - }); + } return result; }); @@ -1550,7 +1550,7 @@ exports.makePos = function(_register) { throw new Error(`Could not access room ${this.roomName}`); } - opts = _.clone(opts || {}); + opts = opts ? {...opts} : {}; var objects = [], result = []; @@ -1559,7 +1559,7 @@ exports.makePos = function(_register) { objects = room.find(type, opts); } if(_.isArray(type)) { - objects = opts.filter ? _.filter(type, opts.filter) : type; + objects = opts.filter ? type.filter(opts.filter) : type; } var closest = null, minRange = Infinity; diff --git a/src/processor/global-intents/market.js b/src/processor/global-intents/market.js index e8ec14b3..e892181e 100644 --- a/src/processor/global-intents/market.js +++ b/src/processor/global-intents/market.js @@ -68,9 +68,11 @@ module.exports = function({orders, userIntents, usersById, gameTime, roomObjects return true; } - _.filter(terminals, i => !!i.send).forEach(terminal => { - - var intent = terminal.send; + terminals.forEach(terminal => { + const intent = terminal.send; + if (!intent) { + return; + } bulkObjects.update(terminal, {send: null}); diff --git a/src/processor/intents/creeps/attackController.js b/src/processor/intents/creeps/attackController.js index 5fe01e89..604369d9 100644 --- a/src/processor/intents/creeps/attackController.js +++ b/src/processor/intents/creeps/attackController.js @@ -31,7 +31,7 @@ module.exports = function(object, intent, {roomObjects, bulk, roomController, ga } if(target.reservation) { - var effect = Math.floor(_.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE); + var effect = Math.floor(object.body.filter((i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE); if(!effect) { return; } @@ -39,7 +39,7 @@ module.exports = function(object, intent, {roomObjects, bulk, roomController, ga bulk.update(target, {reservation: {endTime}}); } if(target.user) { - var effect = Math.floor(_.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_CLAIM_DOWNGRADE); + var effect = Math.floor(object.body.filter((i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_CLAIM_DOWNGRADE); if(!effect) { return; } @@ -50,4 +50,4 @@ module.exports = function(object, intent, {roomObjects, bulk, roomController, ga object.actionLog.attack = {x: target.x, y: target.y}; eventLog.push({event: C.EVENT_ATTACK_CONTROLLER, objectId: object._id}) -}; \ No newline at end of file +}; diff --git a/src/processor/intents/creeps/build.js b/src/processor/intents/creeps/build.js index cee234f0..f4934de3 100644 --- a/src/processor/intents/creeps/build.js +++ b/src/processor/intents/creeps/build.js @@ -64,10 +64,10 @@ module.exports = function(object, intent, {roomObjects, roomTerrain, bulk, roomC return; } - var buildPower = _.filter(object.body, (i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.BUILD_POWER || 0, + var buildPower = object.body.filter((i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.BUILD_POWER || 0, buildRemaining = target.progressTotal - target.progress, buildEffect = Math.min(buildPower, buildRemaining, object.store.energy), - boostedParts = _.map(object.body, i => { + boostedParts = object.body.map(i => { if(i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].build > 0) { return (C.BOOSTS[C.WORK][i.boost].build-1) * C.BUILD_POWER; } diff --git a/src/processor/intents/creeps/claimController.js b/src/processor/intents/creeps/claimController.js index 59120a70..7cb3c25b 100644 --- a/src/processor/intents/creeps/claimController.js +++ b/src/processor/intents/creeps/claimController.js @@ -25,7 +25,7 @@ module.exports = function(object, intent, {roomObjects, bulk, bulkUsers, users}) if(target.level > 0) { return; } - if ((_.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length) === 0) { + if (!object.body.some((i) => i.hits > 0 && i.type == C.CLAIM).length) { return; } if(target.reservation && target.reservation.user != object.user) { @@ -49,4 +49,4 @@ module.exports = function(object, intent, {roomObjects, bulk, bulkUsers, users}) }); driver.addRoomToUser(object.room, users[object.user], bulkUsers); -}; \ No newline at end of file +}; diff --git a/src/processor/intents/creeps/invaders/findAttack.js b/src/processor/intents/creeps/invaders/findAttack.js index 6f27665e..4705998d 100644 --- a/src/processor/intents/creeps/invaders/findAttack.js +++ b/src/processor/intents/creeps/invaders/findAttack.js @@ -80,15 +80,15 @@ module.exports = function(creep, context) { } if(!target) { - const unreachableSpawns = _.filter(roomObjects, o => + const unreachableSpawn = roomObjects ? roomObjects.find(o => o.type == 'spawn' && !checkPath(creep, new fakeRuntime.RoomPosition(o.x, o.y, o.room), scope) - ); - if(!unreachableSpawns.length && roomController && roomController.user) { + ) : null; + if(!unreachableSpawn && roomController && roomController.user) { intents.set(creep._id, 'suicide', {}); return; } - target = unreachableSpawns[0]; + target = unreachableSpawn; if(target) { const direction = fakeRuntime.moveTo(creep, target, {ignoreDestructibleStructures: true, maxRooms: 1, ignoreRoads: true}, scope); if(direction) { @@ -105,15 +105,15 @@ module.exports = function(creep, context) { } const pos = fakeRuntime.RoomPosition.sUnpackLocal(creep['memory_move']['path'][0], creep.room); - const structures = _.filter(roomObjects, o => !!C.CONTROLLER_STRUCTURES[o.type] && o.type != 'spawn' && o.x == pos.x && o.y == pos.y); - if(structures.length > 0) { + const structure = roomObjects.find(o => !!C.CONTROLLER_STRUCTURES[o.type] && o.type != 'spawn' && o.x == pos.x && o.y == pos.y); + if(structure) { if(fakeRuntime.hasActiveBodyparts(creep, C.RANGED_ATTACK)) { - intents.set(creep._id, 'rangedAttack', { id: structures[0]._id }) + intents.set(creep._id, 'rangedAttack', { id: structure._id }) } if(fakeRuntime.hasActiveBodyparts(creep, C.WORK)) { - intents.set(creep._id, 'dismantle', { id: structures[0]._id }); + intents.set(creep._id, 'dismantle', { id: structure._id }); } else { - intents.set(creep._id, 'attack', { id: structures[0]._id, x: structures[0].x, y: structures[0].y }); + intents.set(creep._id, 'attack', { id: structure._id, x: structure.x, y: structure.y }); } } } diff --git a/src/processor/intents/creeps/invaders/flee.js b/src/processor/intents/creeps/invaders/flee.js index 6046fcab..67adf141 100644 --- a/src/processor/intents/creeps/invaders/flee.js +++ b/src/processor/intents/creeps/invaders/flee.js @@ -7,8 +7,8 @@ const _ = require('lodash'), module.exports = function(creep, range, context) { const {scope, intents, hostiles} = context; - const nearCreeps = _.filter(hostiles, c => utils.dist(creep, c) < range); - if(_.some(nearCreeps)) { + const nearCreeps = hostiles.filter(c => utils.dist(creep, c) < range); + if(nearCreeps.length > 0) { const direction = fakeRuntime.flee(creep, nearCreeps, range, {}, scope); if(direction) { intents.set(creep._id, 'move', { direction }); diff --git a/src/processor/intents/creeps/invaders/healer.js b/src/processor/intents/creeps/invaders/healer.js index 525fe223..8f6046ad 100644 --- a/src/processor/intents/creeps/invaders/healer.js +++ b/src/processor/intents/creeps/invaders/healer.js @@ -8,9 +8,9 @@ const _ = require('lodash'), module.exports = function(creep, context) { const {scope, intents, invaders} = context; - let healTargets = _.filter(invaders, c => utils.dist(c, creep) <= 3); - if(_.some(healTargets)) { - const healTarget = _.first(healTargets.sort((a, b) => (b.hitsMax - b.hits) - (a.hitsMax - a.hits))); + let healTargets = invaders.filter(c => utils.dist(c, creep) <= 3); + if(healTargets.length > 0) { + const healTarget = healTargets.sort((a, b) => (b.hitsMax - b.hits) - (a.hitsMax - a.hits))[0]; if(utils.dist(creep, healTarget) <= 1) { intents.set(creep._id, 'heal', {id: healTarget._id, x: healTarget.x, y: healTarget.y}); } else { @@ -22,7 +22,7 @@ module.exports = function(creep, context) { if(!flee(creep, 4, context)) { const fleeTarget = fakeRuntime.findClosestByPath( creep, - _.filter(invaders, c => (c != creep) && fakeRuntime.hasActiveBodyparts(c, C.HEAL)), + invaders.filter(c => (c != creep) && fakeRuntime.hasActiveBodyparts(c, C.HEAL)), null, scope); @@ -37,12 +37,12 @@ module.exports = function(creep, context) { return; } - let target = fakeRuntime.findClosestByPath(creep, _.filter(invaders, c => c.hits < c.hitsMax), null, scope); + let target = fakeRuntime.findClosestByPath(creep, invaders.filter(c => c.hits < c.hitsMax), null, scope); if(!target) { if(flee(creep, 4, context)) { return; } - target = fakeRuntime.findClosestByPath(creep, _.filter(invaders, c => (c != creep) && !fakeRuntime.hasActiveBodyparts(c, C.HEAL)), null, scope); + target = fakeRuntime.findClosestByPath(creep, invaders.filter(c => (c != creep) && !fakeRuntime.hasActiveBodyparts(c, C.HEAL)), null, scope); } if(!target) { diff --git a/src/processor/intents/creeps/invaders/shootAtWill.js b/src/processor/intents/creeps/invaders/shootAtWill.js index acd2debd..270a04ce 100644 --- a/src/processor/intents/creeps/invaders/shootAtWill.js +++ b/src/processor/intents/creeps/invaders/shootAtWill.js @@ -11,7 +11,7 @@ module.exports = function(creep, context) { const { intents, hostiles } = context; - const targets = _.filter(hostiles, c => utils.dist(creep, c) <= 3); + const targets = hostiles.filter(c => utils.dist(creep, c) <= 3); if(!_.some(targets)){ return; diff --git a/src/processor/intents/creeps/rangedMassAttack.js b/src/processor/intents/creeps/rangedMassAttack.js index d46429b5..f941d8bc 100644 --- a/src/processor/intents/creeps/rangedMassAttack.js +++ b/src/processor/intents/creeps/rangedMassAttack.js @@ -23,7 +23,7 @@ module.exports = function(object, intent, scope) { return; } - var targets = _.filter(roomObjects, (i) => { + var targets = roomObjects.filter((i) => { return (!_.isUndefined(i.user) || i.type == 'powerBank') && i.user != object.user && i.x >= object.x - 3 && i.x <= object.x + 3 && i.y >= object.y - 3 && i.y <= object.y + 3; diff --git a/src/processor/intents/creeps/repair.js b/src/processor/intents/creeps/repair.js index 56b7219b..e8ae3170 100644 --- a/src/processor/intents/creeps/repair.js +++ b/src/processor/intents/creeps/repair.js @@ -20,12 +20,12 @@ module.exports = function(object, intent, {roomObjects, bulk, stats, eventLog}) return; } - var repairPower = _.filter(object.body, (i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.REPAIR_POWER || 0, + var repairPower = object.body.filter((i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.REPAIR_POWER || 0, repairEnergyRemaining = object.store.energy / C.REPAIR_COST, repairHitsMax = target.hitsMax - target.hits, repairEffect = Math.min(repairPower, repairEnergyRemaining, repairHitsMax), repairCost = Math.min(object.store.energy, Math.ceil(repairEffect * C.REPAIR_COST)), - boostedParts = _.map(object.body, i => { + boostedParts = object.body.map(i => { if(i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].repair > 0) { return (C.BOOSTS[C.WORK][i.boost].repair-1) * C.REPAIR_POWER; } diff --git a/src/processor/intents/creeps/reserveController.js b/src/processor/intents/creeps/reserveController.js index 6fed9ebb..cf204fe9 100644 --- a/src/processor/intents/creeps/reserveController.js +++ b/src/processor/intents/creeps/reserveController.js @@ -23,7 +23,7 @@ module.exports = function(object, intent, {roomObjects, bulk, gameTime, eventLog return; } - var effect = _.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE; + var effect = object.body.filter((i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE; if(!effect) { return; } diff --git a/src/processor/intents/creeps/upgradeController.js b/src/processor/intents/creeps/upgradeController.js index 30fde070..3eafcf60 100644 --- a/src/processor/intents/creeps/upgradeController.js +++ b/src/processor/intents/creeps/upgradeController.js @@ -26,9 +26,9 @@ module.exports = function(object, intent, {roomObjects, bulk, bulkUsers, stats, target._upgraded = target._upgraded || 0; - var buildPower = _.filter(object.body, (i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.UPGRADE_CONTROLLER_POWER || 0, + var buildPower = object.body.filter((i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.UPGRADE_CONTROLLER_POWER || 0, buildEffect = Math.min(buildPower, object.store.energy), - boostedParts = _.map(object.body, i => { + boostedParts = object.body.map(i => { if(i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].upgradeController > 0) { return C.BOOSTS[C.WORK][i.boost].upgradeController-1; } diff --git a/src/processor/intents/invader-core/stronghold/creeps.js b/src/processor/intents/invader-core/stronghold/creeps.js index b5ac9e58..0003b68a 100644 --- a/src/processor/intents/invader-core/stronghold/creeps.js +++ b/src/processor/intents/invader-core/stronghold/creeps.js @@ -68,7 +68,7 @@ const behaviors = { return; } - const repairRamparts = _.filter(ramparts, r => r.hitsTarget && r.hits < r.hitsTarget); + const repairRamparts = ramparts.filter(r => r.hitsTarget && r.hits < r.hitsTarget); if(!_.some(repairRamparts)) { return; } @@ -86,7 +86,7 @@ const behaviors = { const safeMatrixCallback = defence.createSafeMatrixCallback(context); fakeRuntime.walkTo(creep, target, { range: 3, costCallback: safeMatrixCallback }, context); - const targetInRange = _.first(_.filter(repairRamparts, r => utils.dist(creep, r) <= 3)); + const targetInRange = repairRamparts.find(r => utils.dist(creep, r) <= 3); if(targetInRange) { intents.set(creep._id, 'repair', {id: targetInRange._id, x: targetInRange.x, y: targetInRange.y}); } diff --git a/src/processor/intents/invader-core/stronghold/stronghold.js b/src/processor/intents/invader-core/stronghold/stronghold.js index 726b4b43..fe3eddc3 100644 --- a/src/processor/intents/invader-core/stronghold/stronghold.js +++ b/src/processor/intents/invader-core/stronghold/stronghold.js @@ -154,8 +154,8 @@ const refillTowers = function refillTowers(context) { return false; } - const underchargedTowers = _.filter(towers, t => (t.store.energy <= 2*C.TOWER_ENERGY_COST) && _.some(ramparts, {x: t.x, y: t.y})); - if(_.some(underchargedTowers)) { + const underchargedTowers = towers.filter(t => (t.store.energy <= 2*C.TOWER_ENERGY_COST) && _.some(ramparts, {x: t.x, y: t.y})); + if(underchargedTowers.length > 0) { const towerToCharge = _.min(underchargedTowers, 'store.energy'); if(towerToCharge) { intents.set(core._id, 'transfer', {id: towerToCharge._id, amount: towerToCharge.storeCapacityResource.energy - towerToCharge.store.energy, resourceType: C.RESOURCE_ENERGY}); @@ -169,8 +169,8 @@ const refillTowers = function refillTowers(context) { const refillCreeps = function refillCreeps(context) { const {core, intents, defenders} = context; - const underchargedCreeps = _.filter(defenders, c => (c.storeCapacity > 0) && (2*c.store.energy <= c.storeCapacity)); - if(_.some(underchargedCreeps)) { + const underchargedCreeps = defenders.filter(c => (c.storeCapacity > 0) && (2*c.store.energy <= c.storeCapacity)); + if(underchargedCreeps.length > 0) { const creep = _.min(underchargedCreeps, 'store.energy'); if(creep) { intents.set(core._id, 'transfer', {id: creep._id, amount: creep.storeCapacity - creep.store.energy, resourceType: C.RESOURCE_ENERGY}); @@ -187,8 +187,8 @@ const towersMaintenance = function towersMaintenance(context) { return; } - const protectedCreeps = _.filter(damagedDefenders, d => _.some(ramparts, {x: d.x, y: d.y})); - if(_.some(protectedCreeps)) { + const protectedCreeps = damagedDefenders.filter(d => _.some(ramparts, {x: d.x, y: d.y})); + if(protectedCreeps.length > 0) { const creep = _.first(protectedCreeps); const tower = _.first(towers); intents.set(tower._id, 'heal', {id: creep._id}); @@ -196,8 +196,8 @@ const towersMaintenance = function towersMaintenance(context) { return; } - const protectedRoads = _.filter(damagedRoads, r => _.some(ramparts, {x: r.x, y: r.y})); - if(_.some(protectedRoads)) { + const protectedRoads = damagedRoads.filter(r => _.some(ramparts, {x: r.x, y: r.y})); + if(protectedRoads.length > 0) { const road = _.first(damagedRoads); const tower = _.first(towers); intents.set(tower._id, 'repair', {id: road._id}); @@ -220,12 +220,12 @@ const focusClosest = function focusClosest(context) { intents.set(t._id, 'attack', {id: target._id}); } - const meleesNear = _.filter(defenders, d => (range(d, target) == 1) && _.some(d.body, {type: C.ATTACK})); + const meleesNear = defenders.filter(d => (range(d, target) == 1) && _.some(d.body, {type: C.ATTACK})); for(let melee of meleesNear) { intents.set(melee._id, 'attack', {id: target._id, x: target.x, y: target.y}); } - const rangersInRange = _.filter(defenders, d => (range(d, target) <= 3) && _.some(d.body, {type: C.RANGED_ATTACK})); + const rangersInRange = defenders.filter(d => (range(d, target) <= 3) && _.some(d.body, {type: C.RANGED_ATTACK})); for(let r of rangersInRange) { if(range(r,target) == 1) { intents.set(r._id, 'rangedMassAttack', {}); @@ -244,7 +244,7 @@ const focusMax = function focusMax(context) { return false; } - const activeTowers = _.filter(towers, t => t.store.energy >= C.TOWER_ENERGY_COST); + const activeTowers = towers.filter(t => t.store.energy >= C.TOWER_ENERGY_COST); const target = _.max(hostiles, creep => { let damage = _.sum(activeTowers, tower => { let r = utils.dist(creep, tower); @@ -277,12 +277,12 @@ const focusMax = function focusMax(context) { return damage; }); - const meleesNear = _.filter(defenders, d => (range(d, target) == 1) && _.some(d.body, {type: C.ATTACK})); + const meleesNear = defenders.filter(d => (range(d, target) == 1) && _.some(d.body, {type: C.ATTACK})); for(let melee of meleesNear) { intents.set(melee._id, 'attack', {id: target._id, x: target.x, y: target.y}); } - const rangersInRange = _.filter(defenders, d => (range(d, target) <= 3) && _.some(d.body, {type: C.RANGED_ATTACK})); + const rangersInRange = defenders.filter(d => (range(d, target) <= 3) && _.some(d.body, {type: C.RANGED_ATTACK})); for(let r of rangersInRange) { if(range(r,target) == 1) { intents.set(r._id, 'rangedMassAttack', {}); diff --git a/src/processor/intents/movement.js b/src/processor/intents/movement.js index caf97029..b93b81de 100644 --- a/src/processor/intents/movement.js +++ b/src/processor/intents/movement.js @@ -117,7 +117,7 @@ exports.check = function(roomIsInSafeMode) { var moves = object.type == 'powerCreep' ? 0 : utils.calcBodyEffectiveness(object.body, C.MOVE, 'fatigue', 1), weight = object.type == 'powerCreep' ? 0 : - _.filter(object.body, (i) => i.type != C.MOVE && i.type != C.CARRY).length; + object.body.filter( (i) => i.type != C.MOVE && i.type != C.CARRY).length; weight += object.type == 'powerCreep' ? 0 : calcResourcesWeight(object); weight = weight || 1; @@ -199,7 +199,7 @@ exports.execute = function(object, scope) { return; } - var cellObjects = _.filter(roomObjects, (i) => i.x == move.x && i.y == move.y); + var cellObjects = roomObjects ? roomObjects.filter( (i) => i.x == move.x && i.y == move.y) : []; var fatigueRate = 2; diff --git a/src/processor/intents/spawns/renew-creep.js b/src/processor/intents/spawns/renew-creep.js index 6818f76a..6e3a7bba 100644 --- a/src/processor/intents/spawns/renew-creep.js +++ b/src/processor/intents/spawns/renew-creep.js @@ -21,7 +21,7 @@ module.exports = function(object, intent, scope) { if(Math.abs(target.x - object.x) > 1 || Math.abs(target.y - object.y) > 1) { return; } - if(_.filter(target.body, (i) => i.type == C.CLAIM).length > 0) { + if(target.body.some((i) => i.type == C.CLAIM)) { return; } diff --git a/src/processor/intents/spawns/tick.js b/src/processor/intents/spawns/tick.js index b383554e..3ad4b39f 100644 --- a/src/processor/intents/spawns/tick.js +++ b/src/processor/intents/spawns/tick.js @@ -32,7 +32,7 @@ module.exports = function(object, scope) { if(!roomController || roomController.level < 1 || roomController.user != object.user) { return; } - var spawns = _.filter(roomObjects, {type: 'spawn'}); + let spawns = roomObjects.filter((object) => object.type === 'spawn'); if(spawns.length > C.CONTROLLER_STRUCTURES.spawn[roomController.level]) { spawns.sort(utils.comparatorDistance(roomController)); spawns = _.take(spawns, C.CONTROLLER_STRUCTURES.spawn[roomController.level]); From ddd7e4616870b29b4d5c3a32ecd1fdbcc3985b97 Mon Sep 17 00:00:00 2001 From: winrid Date: Sat, 17 Jun 2023 14:41:33 -0700 Subject: [PATCH 2/4] adding shim into native array methods (filter, find, map) --- src/utils.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/utils.js b/src/utils.js index 7c25b460..24a9a435 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,31 @@ var _ = require('lodash'); +// shim lodash to use native array methods, built into the VM, when available. +// this only works if the module imports _ instead of the method directly. +const oldFilter = _.filter; +_.filter = (data, predicate) => { + if (data && typeof predicate === 'function') { + return data.filter(predicate); + } + return oldFilter(data, predicate); +} + +const oldFind = _.find; +_.find = (data, predicate) => { + if (data && typeof predicate === 'function') { + return data.find(predicate); + } + return oldFind(data, predicate); +} + +const oldMap = _.map; +_.map = (data, predicate) => { + if (data && typeof predicate === 'function') { + return data.map(predicate); + } + return oldMap(data, predicate); +} + var driver, C, offsetsByDirection = [, [0,-1], [1,-1], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1]]; function loadDriver() { From 8558a5c5588f3844ae75d458e9f39963ec4f5b49 Mon Sep 17 00:00:00 2001 From: winrid Date: Sat, 17 Jun 2023 14:49:26 -0700 Subject: [PATCH 3/4] Going back to lodash in many places to reduce # of changes in PR, since we were able to isolate the optimization in a shim. --- src/game/rooms.js | 12 ++++++------ src/processor/intents/creeps/attackController.js | 4 ++-- src/processor/intents/creeps/build.js | 4 ++-- src/processor/intents/creeps/invaders/healer.js | 6 +++--- src/processor/intents/creeps/invaders/shootAtWill.js | 2 +- src/processor/intents/creeps/rangedMassAttack.js | 2 +- src/processor/intents/creeps/repair.js | 4 ++-- src/processor/intents/creeps/reserveController.js | 2 +- src/processor/intents/creeps/upgradeController.js | 4 ++-- .../intents/invader-core/stronghold/creeps.js | 2 +- src/processor/intents/movement.js | 4 ++-- src/processor/intents/spawns/tick.js | 2 +- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/game/rooms.js b/src/game/rooms.js index dfd7c786..e745bc23 100644 --- a/src/game/rooms.js +++ b/src/game/rooms.js @@ -309,19 +309,19 @@ function _findClosestByPath2(fromPos, objects, opts) { objects = register.rooms[fromPos.roomName].find(objects, {filter: opts.filter}); } else if(opts.filter) { - objects = objects.filter(opts.filter); + objects = _.filter(objects, opts.filter); } if(!objects.length) { return null; } - var objectOnSquare = objects.find( obj => fromPos.isEqualTo(obj)); + var objectOnSquare = _.find(objects, obj => fromPos.isEqualTo(obj)); if(objectOnSquare) { return objectOnSquare; } - var goals = objects.map(i => { + var goals = _.map(objects, i => { if(i.pos) { i = i.pos; } @@ -646,7 +646,7 @@ exports.make = function(_runtimeData, _intents, _register, _globals) { } if(opts.filter) { - result = result.filter(opts.filter); + result = _.filter(result, opts.filter); } else { result = [...result]; @@ -1531,7 +1531,7 @@ exports.makePos = function(_register) { objects = room.find(type, opts); } if(_.isArray(type)) { - objects = opts.filter ? type.filter(opts.filter) : type; + objects = opts.filter ? _.filter(type, opts.filter) : type; } for (const i of objects) { @@ -1559,7 +1559,7 @@ exports.makePos = function(_register) { objects = room.find(type, opts); } if(_.isArray(type)) { - objects = opts.filter ? type.filter(opts.filter) : type; + objects = opts.filter ? _.filter(type, opts.filter) : type; } var closest = null, minRange = Infinity; diff --git a/src/processor/intents/creeps/attackController.js b/src/processor/intents/creeps/attackController.js index 604369d9..505eb6ac 100644 --- a/src/processor/intents/creeps/attackController.js +++ b/src/processor/intents/creeps/attackController.js @@ -31,7 +31,7 @@ module.exports = function(object, intent, {roomObjects, bulk, roomController, ga } if(target.reservation) { - var effect = Math.floor(object.body.filter((i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE); + var effect = Math.floor(_.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE); if(!effect) { return; } @@ -39,7 +39,7 @@ module.exports = function(object, intent, {roomObjects, bulk, roomController, ga bulk.update(target, {reservation: {endTime}}); } if(target.user) { - var effect = Math.floor(object.body.filter((i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_CLAIM_DOWNGRADE); + var effect = Math.floor(_.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_CLAIM_DOWNGRADE); if(!effect) { return; } diff --git a/src/processor/intents/creeps/build.js b/src/processor/intents/creeps/build.js index f4934de3..cee234f0 100644 --- a/src/processor/intents/creeps/build.js +++ b/src/processor/intents/creeps/build.js @@ -64,10 +64,10 @@ module.exports = function(object, intent, {roomObjects, roomTerrain, bulk, roomC return; } - var buildPower = object.body.filter((i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.BUILD_POWER || 0, + var buildPower = _.filter(object.body, (i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.BUILD_POWER || 0, buildRemaining = target.progressTotal - target.progress, buildEffect = Math.min(buildPower, buildRemaining, object.store.energy), - boostedParts = object.body.map(i => { + boostedParts = _.map(object.body, i => { if(i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].build > 0) { return (C.BOOSTS[C.WORK][i.boost].build-1) * C.BUILD_POWER; } diff --git a/src/processor/intents/creeps/invaders/healer.js b/src/processor/intents/creeps/invaders/healer.js index 8f6046ad..d69ad06f 100644 --- a/src/processor/intents/creeps/invaders/healer.js +++ b/src/processor/intents/creeps/invaders/healer.js @@ -22,7 +22,7 @@ module.exports = function(creep, context) { if(!flee(creep, 4, context)) { const fleeTarget = fakeRuntime.findClosestByPath( creep, - invaders.filter(c => (c != creep) && fakeRuntime.hasActiveBodyparts(c, C.HEAL)), + _.filter(invaders, c => (c != creep) && fakeRuntime.hasActiveBodyparts(c, C.HEAL)), null, scope); @@ -37,12 +37,12 @@ module.exports = function(creep, context) { return; } - let target = fakeRuntime.findClosestByPath(creep, invaders.filter(c => c.hits < c.hitsMax), null, scope); + let target = fakeRuntime.findClosestByPath(creep, _.filter(invaders, c => c.hits < c.hitsMax), null, scope); if(!target) { if(flee(creep, 4, context)) { return; } - target = fakeRuntime.findClosestByPath(creep, invaders.filter(c => (c != creep) && !fakeRuntime.hasActiveBodyparts(c, C.HEAL)), null, scope); + target = fakeRuntime.findClosestByPath(creep, _.filter(invaders, c => (c != creep) && !fakeRuntime.hasActiveBodyparts(c, C.HEAL)), null, scope); } if(!target) { diff --git a/src/processor/intents/creeps/invaders/shootAtWill.js b/src/processor/intents/creeps/invaders/shootAtWill.js index 270a04ce..acd2debd 100644 --- a/src/processor/intents/creeps/invaders/shootAtWill.js +++ b/src/processor/intents/creeps/invaders/shootAtWill.js @@ -11,7 +11,7 @@ module.exports = function(creep, context) { const { intents, hostiles } = context; - const targets = hostiles.filter(c => utils.dist(creep, c) <= 3); + const targets = _.filter(hostiles, c => utils.dist(creep, c) <= 3); if(!_.some(targets)){ return; diff --git a/src/processor/intents/creeps/rangedMassAttack.js b/src/processor/intents/creeps/rangedMassAttack.js index f941d8bc..d46429b5 100644 --- a/src/processor/intents/creeps/rangedMassAttack.js +++ b/src/processor/intents/creeps/rangedMassAttack.js @@ -23,7 +23,7 @@ module.exports = function(object, intent, scope) { return; } - var targets = roomObjects.filter((i) => { + var targets = _.filter(roomObjects, (i) => { return (!_.isUndefined(i.user) || i.type == 'powerBank') && i.user != object.user && i.x >= object.x - 3 && i.x <= object.x + 3 && i.y >= object.y - 3 && i.y <= object.y + 3; diff --git a/src/processor/intents/creeps/repair.js b/src/processor/intents/creeps/repair.js index e8ae3170..56b7219b 100644 --- a/src/processor/intents/creeps/repair.js +++ b/src/processor/intents/creeps/repair.js @@ -20,12 +20,12 @@ module.exports = function(object, intent, {roomObjects, bulk, stats, eventLog}) return; } - var repairPower = object.body.filter((i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.REPAIR_POWER || 0, + var repairPower = _.filter(object.body, (i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.REPAIR_POWER || 0, repairEnergyRemaining = object.store.energy / C.REPAIR_COST, repairHitsMax = target.hitsMax - target.hits, repairEffect = Math.min(repairPower, repairEnergyRemaining, repairHitsMax), repairCost = Math.min(object.store.energy, Math.ceil(repairEffect * C.REPAIR_COST)), - boostedParts = object.body.map(i => { + boostedParts = _.map(object.body, i => { if(i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].repair > 0) { return (C.BOOSTS[C.WORK][i.boost].repair-1) * C.REPAIR_POWER; } diff --git a/src/processor/intents/creeps/reserveController.js b/src/processor/intents/creeps/reserveController.js index cf204fe9..6fed9ebb 100644 --- a/src/processor/intents/creeps/reserveController.js +++ b/src/processor/intents/creeps/reserveController.js @@ -23,7 +23,7 @@ module.exports = function(object, intent, {roomObjects, bulk, gameTime, eventLog return; } - var effect = object.body.filter((i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE; + var effect = _.filter(object.body, (i) => i.hits > 0 && i.type == C.CLAIM).length * C.CONTROLLER_RESERVE; if(!effect) { return; } diff --git a/src/processor/intents/creeps/upgradeController.js b/src/processor/intents/creeps/upgradeController.js index 3eafcf60..30fde070 100644 --- a/src/processor/intents/creeps/upgradeController.js +++ b/src/processor/intents/creeps/upgradeController.js @@ -26,9 +26,9 @@ module.exports = function(object, intent, {roomObjects, bulk, bulkUsers, stats, target._upgraded = target._upgraded || 0; - var buildPower = object.body.filter((i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.UPGRADE_CONTROLLER_POWER || 0, + var buildPower = _.filter(object.body, (i) => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.UPGRADE_CONTROLLER_POWER || 0, buildEffect = Math.min(buildPower, object.store.energy), - boostedParts = object.body.map(i => { + boostedParts = _.map(object.body, i => { if(i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].upgradeController > 0) { return C.BOOSTS[C.WORK][i.boost].upgradeController-1; } diff --git a/src/processor/intents/invader-core/stronghold/creeps.js b/src/processor/intents/invader-core/stronghold/creeps.js index 0003b68a..5f00f6cc 100644 --- a/src/processor/intents/invader-core/stronghold/creeps.js +++ b/src/processor/intents/invader-core/stronghold/creeps.js @@ -68,7 +68,7 @@ const behaviors = { return; } - const repairRamparts = ramparts.filter(r => r.hitsTarget && r.hits < r.hitsTarget); + const repairRamparts = _.filter(ramparts, r => r.hitsTarget && r.hits < r.hitsTarget); if(!_.some(repairRamparts)) { return; } diff --git a/src/processor/intents/movement.js b/src/processor/intents/movement.js index b93b81de..caf97029 100644 --- a/src/processor/intents/movement.js +++ b/src/processor/intents/movement.js @@ -117,7 +117,7 @@ exports.check = function(roomIsInSafeMode) { var moves = object.type == 'powerCreep' ? 0 : utils.calcBodyEffectiveness(object.body, C.MOVE, 'fatigue', 1), weight = object.type == 'powerCreep' ? 0 : - object.body.filter( (i) => i.type != C.MOVE && i.type != C.CARRY).length; + _.filter(object.body, (i) => i.type != C.MOVE && i.type != C.CARRY).length; weight += object.type == 'powerCreep' ? 0 : calcResourcesWeight(object); weight = weight || 1; @@ -199,7 +199,7 @@ exports.execute = function(object, scope) { return; } - var cellObjects = roomObjects ? roomObjects.filter( (i) => i.x == move.x && i.y == move.y) : []; + var cellObjects = _.filter(roomObjects, (i) => i.x == move.x && i.y == move.y); var fatigueRate = 2; diff --git a/src/processor/intents/spawns/tick.js b/src/processor/intents/spawns/tick.js index 3ad4b39f..b383554e 100644 --- a/src/processor/intents/spawns/tick.js +++ b/src/processor/intents/spawns/tick.js @@ -32,7 +32,7 @@ module.exports = function(object, scope) { if(!roomController || roomController.level < 1 || roomController.user != object.user) { return; } - let spawns = roomObjects.filter((object) => object.type === 'spawn'); + var spawns = _.filter(roomObjects, {type: 'spawn'}); if(spawns.length > C.CONTROLLER_STRUCTURES.spawn[roomController.level]) { spawns.sort(utils.comparatorDistance(roomController)); spawns = _.take(spawns, C.CONTROLLER_STRUCTURES.spawn[roomController.level]); From 6f3770aeb916a113b9f0e15509bc684d70f3aafc Mon Sep 17 00:00:00 2001 From: winrid Date: Sat, 17 Jun 2023 14:55:13 -0700 Subject: [PATCH 4/4] Fixing invalid length check --- src/processor/intents/creeps/claimController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/intents/creeps/claimController.js b/src/processor/intents/creeps/claimController.js index 7cb3c25b..150798b3 100644 --- a/src/processor/intents/creeps/claimController.js +++ b/src/processor/intents/creeps/claimController.js @@ -25,7 +25,7 @@ module.exports = function(object, intent, {roomObjects, bulk, bulkUsers, users}) if(target.level > 0) { return; } - if (!object.body.some((i) => i.hits > 0 && i.type == C.CLAIM).length) { + if (!object.body.some((i) => i.hits > 0 && i.type == C.CLAIM)) { return; } if(target.reservation && target.reservation.user != object.user) {