MOVEMENT · ROOMPOSITION DISTANCE

Which Screeps RoomPosition Distance Method Should You Use?

Choose between getRangeTo(), inRangeTo(), isNearTo(), isEqualTo(), findClosestByRange(), findClosestByPath(), and findInRange() without confusing linear range with route reachability.

Verification statusChinese source article: Reviewed in full · Official docs: Checked — RoomPosition range, equality, adjacency and closest-target methods · Room boundary: Same-room linear comparison is separated from cross-room routing

VERIFICATION

Evidence and test status

Chinese source article
Reviewed in full
Official docs
Checked — RoomPosition range, equality, adjacency and closest-target methods
Room boundary
Same-room linear comparison is separated from cross-room routing
Semantic boundary
isNearTo() includes the same tile because it equals inRangeTo(target, 1)
JavaScript syntax
Passed
Offline relation review
Passed — equal, adjacent, diagonal, range 3, cross-room and target-selection states
Screeps Console test
Pending
Live path and target-selection test
Pending
Last verified
July 25, 2026

Quick answer

Use RoomPosition range methods to answer a coordinate question and path methods to answer a travel question. getRangeTo(), inRangeTo(), isNearTo(), isEqualTo(), findClosestByRange(), and findInRange() do not prove that terrain and structures permit a route. findClosestByPath(), findPathTo(), PathFinder.search(), and moveTo() involve pathfinding.

Linear range and path distance

QuestionUse
Can the action run now?Linear range
Are two coordinates equal or adjacent?Equality or range
Which target is geometrically closest?Closest by range
Which target has the shortest usable route?Closest by path
Which rooms should a Creep cross?Map-level routing

In an eight-direction grid, diagonal displacement counts by the larger coordinate difference. From (10,10) to (13,12), the linear range is 3.

getRangeTo() and inRangeTo()

const range = creep.pos.getRangeTo(target);

if (creep.pos.inRangeTo(target, 3)) {
  // A documented range-3 action may run.
}

getRangeTo() returns a number. inRangeTo() returns a boolean and expresses the business rule more directly.

function getSameRoomRange(from, to) {
  if (
    !from
    || !to
    || from.roomName !== to.roomName
  ) {
    return null;
  }

  return Math.max(
    Math.abs(from.x - to.x),
    Math.abs(from.y - to.y)
  );
}

isNearTo() and isEqualTo()

const withinOne = creep.pos.isNearTo(target);
const sameTile = creep.pos.isEqualTo(target);
const strictlyAdjacent = withinOne && !sameTile;

The official API defines isNearTo(target) as the same test as inRangeTo(target, 1). That includes range 0. Game objects such as a Creep and a solid Structure usually cannot occupy the same tile, but pure RoomPosition comparisons can.

Closest by range or path

const linearTarget = creep.pos.findClosestByRange(
  FIND_HOSTILE_CREEPS
);

const reachableSource = creep.pos.findClosestByPath(
  FIND_SOURCES_ACTIVE
);
MethodTerrain and blockersTypical use
findClosestByRange()NoTower target, quick shortlist, geometry
findClosestByPath()YesA Creep must travel to one candidate

Both return null when no matching candidate is found. Path-based selection can also return null when candidates exist but no path is available under the supplied options.

Filter candidates with findInRange()

const hostiles = tower.pos.findInRange(
  FIND_HOSTILE_CREEPS,
  10
);

This returns every candidate inside the linear range. It is useful before sorting by hits, role, threat, or another rule. It does not test reachability.

Do not compare local coordinates across rooms

if (from.roomName !== to.roomName) {
  return {
    comparable: false,
    reason: 'different-rooms'
  };
}

Every room reuses local coordinates 0–49. Two positions at (25,25) in different rooms are not the same world location. Use Game.map.findRoute(), PathFinder, or moveTo() for cross-room travel.

Complete same-room relation helper

function describePositionRelation(
  from,
  to,
  requiredRange
) {
  if (
    !from
    || !to
    || from.roomName !== to.roomName
    || !Number.isInteger(requiredRange)
    || requiredRange < 0
  ) {
    return {
      comparable: false,
      sameTile: false,
      withinOne: false,
      strictlyAdjacent: false,
      inRequiredRange: false,
      range: null
    };
  }

  const range = Math.max(
    Math.abs(from.x - to.x),
    Math.abs(from.y - to.y)
  );

  return {
    comparable: true,
    sameTile: range === 0,
    withinOne: range <= 1,
    strictlyAdjacent: range === 1,
    inRequiredRange: range <= requiredRange,
    range
  };
}

This pure function verifies coordinate semantics. It does not inspect terrain, structures, Creeps, or path callbacks.

Use the required action range

State impact: this example may submit one movement order. It does not write Memory.

const ACTION_RANGE = {
  harvest: 1,
  withdraw: 1,
  transfer: 1,
  pickup: 1,
  build: 3,
  repair: 3,
  upgrade: 3
};

function prepareForAction(creep, target, action) {
  if (!creep || !target?.pos) {
    return {
      status: 'object-invalid'
    };
  }

  const requiredRange = ACTION_RANGE[action];

  if (!Number.isInteger(requiredRange)) {
    return {
      status: 'action-range-unknown'
    };
  }

  if (
    creep.pos.roomName === target.pos.roomName
    && creep.pos.inRangeTo(target, requiredRange)
  ) {
    return {
      status: 'action-range-ready',
      requiredRange,
      range: creep.pos.getRangeTo(target)
    };
  }

  const moveResult = creep.moveTo(target, {
    range: requiredRange,
    reusePath: 10
  });

  return {
    status: moveResult === OK
      ? 'move-submitted'
      : 'move-failed',
    requiredRange,
    moveResult
  };
}

Do not force every action to range 1. Build, repair, and Controller upgrade work at range 3. The range option tells pathfinding where it may stop; it does not change the action's API.

Range does not prove reachability

Two coordinates can have range 2 while a wall, hostile Rampart, Structure, room edge, CostMatrix rule, or traffic pattern prevents direct travel. Range answers “how far apart are the coordinates?” Pathfinding answers “how can this Creep travel under these rules?”

Likewise, a Controller at range 3 is ready for upgrading even when the shortest route to that position would have required many earlier steps. Action range and path length are different measurements.

Debugging checklist

  • Check roomName before same-room range logic.
  • Use isEqualTo() for exact coordinates.
  • Remember that isNearTo() includes range 0.
  • Use inRangeTo() for action readiness.
  • Use findClosestByRange() only when linear proximity is intended.
  • Use findClosestByPath() when a Creep must travel.
  • Handle null from both closest-target methods.
  • Do not use pathfinding merely to check an already-satisfied action range.
  • Do not use range as proof of reachability.

Scope and next steps

This guide does not compare PathFinder heuristics, CPU cost across large candidate sets, multi-room linear distance, portals, traffic reservations, or route caching. Continue with cross-room route planning.

Frequently asked questions

Does getRangeTo() consider obstacles?

No. It is a linear coordinate measurement.

Does isNearTo() mean exactly one tile away?

No. It means range is at most 1. Exclude isEqualTo() for strict adjacency.

Which closest method should a moving Creep use?

Use path-based selection when route length and reachability matter.

Can local x and y compare different rooms?

No. Check room names and use map or path routing.

Official documentation

SOURCE AND SCOPE

Review the source, evidence, or next system

This English guide is rewritten for a focused search intent while preserving the technical scope and verification boundaries of its Chinese source. Live-room evidence is claimed only when the verification record says it exists.