GETTING STARTED · BEGINNER LESSON 5 OF 12

How to Make a Screeps Creep Deliver Energy to a Spawn

CURATED PATH

These links are maintained for a concrete prerequisite, failure mode, debugging step, or next lesson instead of generic topic similarity.

Beginner / Energy

Recommended next steps

Harvest EnergyPrerequisite stepNext lesson: understand WORK, CARRY, and MOVENext lessonSpawn a CreepEnter the Spawn systemWorking-state switchingNext step
Verification statusChinese source: Read in full · Official documentation: Checked August 29, 2026 — Game.spawns, Creep.transfer(), Store capacity methods, and scheduled-action semantics · Static code review: Passed — minimal transfer and complete round-trip examples preserve delivery mode, wait on full Spawn capacity, and handle transfer range separately

VERIFICATION

Evidence and test status

Chinese source
Read in full
Official documentation
Checked August 29, 2026 — Game.spawns, Creep.transfer(), Store capacity methods, and scheduled-action semantics
Static code review
Passed — minimal transfer and complete round-trip examples preserve delivery mode, wait on full Spawn capacity, and handle transfer range separately
JavaScript syntax
Passed — all executable JavaScript blocks checked offline
Source-capacity boundary
The larger-body Source-harvest hardening is intentionally delegated to the previous harvesting lesson instead of duplicated here
Screeps Console test
Pending — no live transfer transcript is claimed
Live round-trip test
Pending — no real-shard multi-tick delivery trace is claimed
Last editorial review
August 29, 2026
Publication status
Published
Live multi-tick test
Pending — no live multi-tick Source-to-Spawn execution is claimed

What you will complete in this lesson

Start with one Creep that already carries Energy. You will make it walk to a named Spawn, transfer its Energy, and then connect that delivery step to the harvesting loop from the previous lesson.

Finished loop: Source → Creep Store → Spawn → back to the Source.

This lesson controls one named Creep, the first active Source it can find, and one named Spawn. Extension priorities and multi-Creep logistics come later.

Before you run the delivery code

Complete the previous Energy harvesting lesson first. For the one-way delivery test, the Creep needs CARRY and MOVE, must have finished spawning, and must already carry some Energy. The complete round trip also needs an active WORK part so the Creep can harvest again after delivery.

Find your real object names in the Console:

Object.keys(Game.creeps);
Object.keys(Game.spawns);

The examples below use Harvester1 and Spawn1. Replace both names exactly; Screeps names are case-sensitive.

Make one Creep deliver Energy

This is the smallest useful delivery loop. It tries transfer() first and only moves when the Spawn is out of range:

const CREEP_NAME = 'Harvester1';
const SPAWN_NAME = 'Spawn1';

module.exports.loop = function () {
  const creep = Game.creeps[CREEP_NAME];
  const spawn = Game.spawns[SPAWN_NAME];

  if (!creep || !spawn || creep.spawning) return;

  const transferResult = creep.transfer(
    spawn,
    RESOURCE_ENERGY
  );

  if (transferResult === ERR_NOT_IN_RANGE) {
    creep.moveTo(spawn);
  }
};

transfer() moves resources from the Creep to the target. The Spawn must be adjacent to the Creep, so ERR_NOT_IN_RANGE means “move closer and retry on a later tick.”

If the call returns OK, the transfer was scheduled successfully. When you need to confirm the processed result, inspect the Creep and Spawn Stores on a later tick.

Keep delivery mode until the Creep is empty

A repeating worker needs to remember whether it is currently harvesting or delivering. If you switch direction whenever the Creep merely has some free capacity, a partial unload can make it leave the Spawn while it still carries Energy.

Use one boolean in Creep Memory:

const usedEnergy =
  creep.store.getUsedCapacity(RESOURCE_ENERGY) ?? 0;

const freeEnergyCapacity =
  creep.store.getFreeCapacity(RESOURCE_ENERGY) ?? 0;

if (usedEnergy === 0) {
  creep.memory.delivering = false;
} else if (freeEnergyCapacity === 0) {
  creep.memory.delivering = true;
}

The rule is:

  • empty Store → harvest;
  • full Store → deliver;
  • partially full Store → keep the previous mode.

Once delivery starts, the Creep stays in delivery mode until its Energy reaches zero.

Run the first complete Energy round trip

The following beginner version combines the harvest and delivery phases. It waits when the Spawn has no free Energy capacity instead of abandoning delivery mode.

State impact: it calls harvest(), transfer(), and moveTo(), and writes creep.memory.delivering.

const CREEP_NAME = 'Harvester1';
const SPAWN_NAME = 'Spawn1';

module.exports.loop = function () {
  const creep = Game.creeps[CREEP_NAME];
  const spawn = Game.spawns[SPAWN_NAME];

  if (!creep || !spawn || creep.spawning) return;

  const usedEnergy =
    creep.store.getUsedCapacity(RESOURCE_ENERGY) ?? 0;
  const freeEnergy =
    creep.store.getFreeCapacity(RESOURCE_ENERGY) ?? 0;

  if (usedEnergy === 0) {
    creep.memory.delivering = false;
  } else if (freeEnergy === 0) {
    creep.memory.delivering = true;
  }

  if (creep.memory.delivering) {
    const spawnFreeEnergy =
      spawn.store.getFreeCapacity(RESOURCE_ENERGY) ?? 0;

    if (spawnFreeEnergy === 0) return;

    const transferResult = creep.transfer(
      spawn,
      RESOURCE_ENERGY
    );

    if (transferResult === ERR_NOT_IN_RANGE) {
      creep.moveTo(spawn, { reusePath: 5 });
    }

    return;
  }

  const source =
    creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);

  if (!source) return;

  const harvestResult = creep.harvest(source);

  if (harvestResult === ERR_NOT_IN_RANGE) {
    creep.moveTo(source, { reusePath: 5 });
  }
};

This loop deliberately uses the simplest beginner phase boundary: harvest until the Energy Store is full, then deliver until it is empty. The previous harvesting lesson explains the optional larger-body capacity guard for workers whose next Source harvest batch may be larger than their remaining Store space.

What the round trip looks like across ticks

Start-of-tick stateModeWhat the code does
The Creep has free Energy capacity.HarvestFind an active Source, harvest when adjacent, or move toward it.
The Creep starts a tick with no free Energy capacity.DeliverSet creep.memory.delivering = true.
The Spawn is out of range.Delivertransfer() returns ERR_NOT_IN_RANGE, then the Creep moves toward the Spawn.
The Creep is beside a Spawn with free Energy capacity.Delivertransfer() can return OK; verify the Store change later if needed.
The Spawn is full.DeliverThe Creep waits and keeps its delivery state.
The Creep starts a tick with zero Energy.HarvestSet delivering = false and return to a Source.

Four transfer results to understand first

Return codeWhat it meansWhat to do
OKThe transfer was scheduled successfully.Continue the loop; inspect later Store state when you need proof of the processed result.
ERR_NOT_IN_RANGEThe Spawn is too far away.Move toward the Spawn and retry on a later tick.
ERR_FULLThe target cannot receive more of that resource.Check spawn.store.getFreeCapacity(RESOURCE_ENERGY).
ERR_NOT_ENOUGH_RESOURCESThe Creep does not have the requested resource amount.Re-read the Creep Store before retrying.

If another code appears, use the English Screeps return-code reference and keep the exact result instead of replacing it with a generic success/failure boolean.

Confirm that delivery actually happened

The value returned by transfer() describes the current action request. OK means the operation was scheduled successfully; it is not a same-line receipt for the later processed Store values.

For this lesson, the practical check is simple: after a successful delivery tick, inspect a later tick and confirm that the Creep carries less Energy and the Spawn stores more Energy. Other Creeps can change the Spawn at the same time, so those Store values prove the observed state change, not unique causality.

Fix the common beginner problems

The Creep or Spawn is not found

Run Object.keys(Game.creeps) and Object.keys(Game.spawns) again. Replace both example names exactly, including capitalization.

The Creep waits beside the Spawn

Check spawn.store.getFreeCapacity(RESOURCE_ENERGY). If it is zero, the Spawn is full; the worker should stay in delivery mode and wait rather than treating this as a movement failure.

The Creep turns back to the Source too early

Do not set delivering = false merely because the Creep has free capacity after a partial unload. Switch back to harvesting only when usedEnergy === 0.

A larger worker reaches the Source with only a little free capacity

Keep this delivery lesson simple and apply the larger-body capacity hardening from the harvesting lesson. That Source-specific boundary belongs to the acquisition phase rather than the delivery phase.

Completion check

You have completed this lesson when you can:

  • replace the example Creep and Spawn names with real objects;
  • explain that transfer() moves Energy from the Creep to the Spawn;
  • handle ERR_NOT_IN_RANGE by moving toward the Spawn;
  • recognize OK as a scheduled action rather than same-line proof of the processed amount;
  • keep creep.memory.delivering true while the Creep still carries Energy;
  • confirm a later decrease in Creep Energy and increase in Spawn Energy;
  • watch the worker return to harvesting only after it becomes empty.

Continue to Creep body parts

Your first worker can now complete a basic Energy round trip. The next lesson explains why missing or damaged body parts can stop harvesting, carrying, or movement.

Understand WORK, CARRY, and MOVE →

Return to the English beginner roadmap to review the complete twelve-lesson sequence.

Official sources

SOURCE AND SCOPE

Review the source, evidence, or next system

This English guide keeps the technical scope and verification boundaries of its Chinese source. The verification record shows which checks were completed and which runtime observations are still pending.