DEFENSE · IRREVERSIBLE NUKER OPERATION

How to Launch a Nuke Without Reusing a Stale Target Request

Bind confirmation to target room and coordinates, recover an owned active Nuker by ID, check cooldown, NUKE_RANGE, Energy and Ghodium capacities, disable before launchNuke(), save the return code, and verify later evidence without requiring target-room visibility.

Verification statusChinese source article: Reviewed in full · Official docs: Checked — StructureNuker.launchNuke(), RoomPosition, NUKE_RANGE, capacities, cooldown and return codes · Target boundary: The article does not choose enemy rooms, claim strategic benefit, or predict damage outcomes

VERIFICATION

Evidence and test status

Chinese source article
Reviewed in full
Official docs
Checked — StructureNuker.launchNuke(), RoomPosition, NUKE_RANGE, capacities, cooldown and return codes
Target boundary
The article does not choose enemy rooms, claim strategic benefit, or predict damage outcomes
Execution boundary
OK schedules the command; cooldown, target-room Nuke objects and later game state must be observed afterward
JavaScript syntax
Passed
Offline launch review
Passed — confirmation, coordinates, ownership, active state, cooldown, range, Energy, Ghodium and ready states
Screeps Console test
Pending
Live protected-area, launch, cooldown, target Nuke object and resource-consumption test
Pending
Last verified
July 26, 2026

Quick answer

Create one Memory request containing the exact Nuker ID, target room, X, Y, and a confirmation string generated from those target fields. Require integer coordinates from 0 through 49, an owned active Nuker, zero cooldown, linear distance within NUKE_RANGE, at least NUKER_ENERGY_CAPACITY Energy, and at least NUKER_GHODIUM_CAPACITY Ghodium. Disable the request before calling launchNuke(), store the return code, and verify later state.

Treat launchNuke() as irreversible

A submitted launch cannot be converted into a different target by later code. This guide therefore does not automatically choose rooms, players, coordinates, or timing.

function describeNuker(nuker) {
  if (!nuker) {
    return { found: false };
  }

  return {
    found: true,
    id: nuker.id,
    roomName: nuker.pos.roomName,
    owned: nuker.my === true,
    active: nuker.isActive() === true,
    cooldown: nuker.cooldown,
    energy: nuker.store.getUsedCapacity(
      RESOURCE_ENERGY
    ),
    ghodium: nuker.store.getUsedCapacity(
      RESOURCE_GHODIUM
    )
  };
}

Bind confirmation to the exact target

function buildNukeConfirmation(roomName, x, y) {
  return 'LAUNCH_NUKE_' + roomName + '_' + x + '_' + y;
}

A generic value such as LAUNCH does not prove that the player reviewed the current target. A target-bound phrase becomes invalid whenever the room or coordinate changes.

Create a one-time request

Memory.nuker ??= {};
Memory.nuker.launchRequest = {
  enabled: true,
  nukerId: 'replace-with-owned-nuker-id',
  targetRoom: 'W2N2',
  x: 25,
  y: 25,
  confirmation: 'LAUNCH_NUKE_W2N2_25_25'
};

Review the whole object. Turning on only enabled is not sufficient confirmation.

Build a testable launch plan

function evaluateNukeRequest(input) {
  const request = input.request;

  if (!request || request.enabled !== true) {
    return { ready: false, reason: 'disabled' };
  }

  if (
    typeof request.targetRoom !== 'string'
    || !Number.isInteger(request.x)
    || !Number.isInteger(request.y)
    || request.x < 0
    || request.x > 49
    || request.y < 0
    || request.y > 49
  ) {
    return { ready: false, reason: 'invalid-target' };
  }

  if (
    request.confirmation !== buildNukeConfirmation(
      request.targetRoom,
      request.x,
      request.y
    )
  ) {
    return { ready: false, reason: 'confirmation-mismatch' };
  }

  if (input.owned !== true) {
    return { ready: false, reason: 'not-owner' };
  }

  if (input.active !== true) {
    return { ready: false, reason: 'structure-inactive' };
  }

  if (!Number.isFinite(input.cooldown) || input.cooldown > 0) {
    return { ready: false, reason: 'nuker-waiting' };
  }

  if (!Number.isFinite(input.distance) || input.distance > NUKE_RANGE) {
    return { ready: false, reason: 'target-out-of-range' };
  }

  if (input.energyAvailable < NUKER_ENERGY_CAPACITY) {
    return { ready: false, reason: 'energy-shortage' };
  }

  if (input.ghodiumAvailable < NUKER_GHODIUM_CAPACITY) {
    return { ready: false, reason: 'ghodium-shortage' };
  }

  return { ready: true, reason: 'ready' };
}

Preflight cannot reproduce every protected-location rule. The API return code remains authoritative.

Recover and validate the Nuker

function getOwnedNuker(nukerId) {
  const structure = typeof nukerId === 'string'
    ? Game.getObjectById(nukerId)
    : null;

  if (
    !structure
    || structure.structureType !== STRUCTURE_NUKER
    || structure.my !== true
  ) {
    return null;
  }

  return structure;
}

Use the exact ID instead of selecting the first Nuker in a room. Multiple Nukers or copied configuration must not change the source structure.

Complete launch handler

function handleNukeRequest() {
  const request = Memory.nuker?.launchRequest;

  if (!request || request.enabled !== true) {
    return { status: 'disabled' };
  }

  const nuker = getOwnedNuker(request.nukerId);
  if (!nuker) {
    request.enabled = false;
    request.status = 'nuker-missing';
    return { status: request.status };
  }

  const distance = Game.map.getRoomLinearDistance(
    nuker.room.name,
    request.targetRoom
  );
  const energyAvailable = nuker.store.getUsedCapacity(
    RESOURCE_ENERGY
  );
  const ghodiumAvailable = nuker.store.getUsedCapacity(
    RESOURCE_GHODIUM
  );
  const plan = evaluateNukeRequest({
    request,
    owned: nuker.my,
    active: nuker.isActive(),
    cooldown: nuker.cooldown,
    distance,
    energyAvailable,
    ghodiumAvailable
  });

  request.checkedAt = Game.time;
  request.status = plan.reason;

  if (!plan.ready) {
    request.enabled = false;
    return { status: plan.reason };
  }

  const target = new RoomPosition(
    request.x,
    request.y,
    request.targetRoom
  );

  request.enabled = false;
  request.status = 'submitted';
  request.submittedAt = Game.time;
  request.before = {
    nukerId: nuker.id,
    sourceRoom: nuker.room.name,
    targetRoom: target.roomName,
    x: target.x,
    y: target.y,
    distance,
    cooldown: nuker.cooldown,
    energyAvailable,
    ghodiumAvailable
  };

  const result = nuker.launchNuke(target);

  request.result = result;
  request.resultAt = Game.time;
  request.status = result === OK
    ? 'accepted'
    : 'failed-review-required';

  return {
    status: request.status,
    result,
    before: request.before
  };
}
module.exports.loop = function () {
  const outcome = handleNukeRequest();

  if (
    outcome.status === 'accepted'
    || outcome.status === 'failed-review-required'
  ) {
    console.log(JSON.stringify({
      type: 'launch-nuke-result',
      ...outcome
    }));
  }
};

Disable before the API call

request.enabled = false;
const result = nuker.launchNuke(target);

Any retry requires a new review. A failed request should not fire later when cooldown, resources, or room state changes.

Verify later evidence

function inspectSubmittedNukeRequest(request) {
  const nuker = getOwnedNuker(request?.nukerId);
  const targetRoom = Game.rooms[
    request?.targetRoom
  ];

  return {
    nukerFound: Boolean(nuker),
    nukerCooldown: nuker?.cooldown ?? null,
    energy: nuker
      ? nuker.store.getUsedCapacity(RESOURCE_ENERGY)
      : null,
    ghodium: nuker
      ? nuker.store.getUsedCapacity(RESOURCE_GHODIUM)
      : null,
    targetVisible: Boolean(targetRoom),
    visibleNukes: targetRoom
      ? targetRoom.find(FIND_NUKES).map(nuke => ({
          id: nuke.id,
          x: nuke.pos.x,
          y: nuke.pos.y,
          timeToLand: nuke.timeToLand
        }))
      : []
  };
}

Do not require target-room visibility

A missing Game.rooms[targetRoom] entry means the room is not currently visible. It does not prove the launch failed. Use the saved API result and source Nuker state, then inspect target-room Nuke objects when visibility becomes available.

Handle return codes

CodeMeaningReview
OKLaunch scheduledCooldown, resources and later Nuke evidence
ERR_NOT_OWNERNuker not yoursID and ownership
ERR_NOT_ENOUGH_RESOURCESEnergy or Ghodium missingBoth Store resources
ERR_INVALID_TARGETTarget location rejectedProtected areas and target rules
ERR_NOT_IN_RANGERoom beyond Nuker rangeNUKE_RANGE and linear distance
ERR_INVALID_ARGSInvalid RoomPositionRoom name and coordinates
ERR_TIREDNuker cooldown activenuker.cooldown
ERR_RCL_NOT_ENOUGHStructure inactiveRCL and isActive()

Debugging checklist

  • Use the exact owned Nuker ID.
  • Validate 0–49 coordinates.
  • Bind confirmation to target room and position.
  • Check active state and cooldown.
  • Calculate current linear distance.
  • Use named Energy and Ghodium capacity constants.
  • Disable stale and submitted requests.
  • Save the full before snapshot and return code.
  • Do not require target-room visibility.
  • Verify later evidence without claiming damage outcomes.

Scope and next steps

This guide does not choose a target, estimate damage, model Ramparts, select launch timing, coordinate multiple Nukers, or retry rejected launches. Continue with reviewed Rampart access changes.

Frequently asked questions

Can one generic confirmation phrase be reused?

It should not be. Build the phrase from the exact target so copied or edited requests fail closed.

Why close the request after a resource shortage?

Otherwise it may launch later as soon as logistics fill the Nuker, without a new human review.

Can preflight guarantee the location is valid?

No. Keep ERR_INVALID_TARGET and the current official result as the final same-tick authority.

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.