Picking a Source
Your room has two sources. Both programs send the harvester to one of them, and each has a different approach to choosing.
var sources = creep.room.find(FIND_SOURCES);
if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
creep.moveTo(sources[0]);
}const source = creep.pos.findClosestByPath(FIND_SOURCES);The first takes index zero of whatever find returns. The second measures the walked route from where the creep stands. This exercise runs the same loop over each: query the room, work out the pick, deploy, watch.
Setup
Quit the server if one is running (Ctrl-C in its terminal), then bring the world up on the original tutorial’s code:
rm -rf .server-data
nix run .#server
nix run .#deploy-local -- tutorial-js
nix run .#clientReload the viewer page and connect. You start here on every pass.
The tutorial’s pick: sources[0]
Query the room.
room-feedsigns in, opens the same websocket feed the viewer reads, and prints the spawn and the source list in the server’s own order:nix run .#room-feed -- <user> <pass> | jq .{ "room": "W9N8", "spawn": { "name": "Spawn1", "x": 21, "y": 25 }, "sources": [ { "id": "…", "x": 19, "y": 31 }, { "id": "…", "x": 13, "y": 37 } ] }You can get the same values from the console tab. Count the sources first:
Game.spawns['Spawn1'].room.find(FIND_SOURCES).length2Two sources, so the valid indexes are 0 and 1. Then ask for each position.
Where the spawn stands:
Game.spawns['Spawn1'].pos[room W9N8 pos 21,25]Where the first source in the server’s list stands — index 0:
Game.spawns['Spawn1'].room.find(FIND_SOURCES)[0].pos[room W9N8 pos 19,31]Where the second source stands — index 1:
Game.spawns['Spawn1'].room.find(FIND_SOURCES)[1].pos[room W9N8 pos 13,37]Look up the pick.
sources[0]is index zero of that list — the whole algorithm is the server’s ordering, so the choice is already sitting in your query output. Make note of the coordinates it points to.Start the tutorial’s creep from the console tab:
Game.spawns['Spawn1'].spawnCreep([WORK, CARRY, MOVE], 'Harvester1')Watch which source it walks to, and hold it against your note.
The port’s pick: findClosestByPath
The port’s line runs
findClosestByPath, and the name is the whole story: find the closest source, with close measured by walking. A source two tiles away behind a wall can be farther, in this measure, than one ten tiles across open ground. The engine measures by running the A* search algorithm over the room’s tiles — walls block, a swamp tile costs five plain ones — and the source reached by the cheapest walk is the pick. On this room’s open ground that is simply the nearest source to the spawn.Look at the room. One source sits closer to the spawn than the other. Make note of which source the port’s harvester will walk to.
Check your note against the pathfinder itself, from the console tab:
Game.spawns['Spawn1'].pos.findClosestByPath(FIND_SOURCES).pos[room W9N8 pos 19,31]Deploy the port —
nix run .#deploy-local— and watch where its harvester walks. Hold it against your note. Note whether the two programs picked the same source from this spawn.
Move the spawn
- Press the respawn button and place the spawn beside the other source. Run both passes again: new query, new
sources[0]note, deploy the tutorial and watch; then a new look at which source is nearest, deploy the port and watch. One program changed its pick with the layout. Which line of which file is the reason? - Wipe the world: stop the server, delete
.server-data, start it again, and re-run the query. Compare the source ids and their order against your notes. What survived the wipe, and how reliable does that makesources[0]as a way to pick a source?
Back to Let’s Play Screeps.