BEGINNER · FIRST EXTENSION

How to Build Your First Screeps Extension

Confirm RCL 2, place one Extension Construction Site, make Builder1 harvest and build it, and understand progress, capacity, and common failure states.

Verification statusChinese source: Read in full · Official documentation: Checked · RCL and constants: Checked

VERIFICATION

Evidence and test status

Chinese source
Read in full
Official documentation
Checked
RCL and constants
Checked
JavaScript syntax
Checked
Offline state review
Passed
Screeps Console
Pending
Live construction test
Pending
Last verified
July 24, 2026

Quick answer

Reach RCL 2, place one Extension Construction Site on a valid open tile, find that site with FIND_MY_CONSTRUCTION_SITES, and make Builder1 alternate between harvesting Energy and calling build(site). The Extension requires 3000 construction progress and is empty when completed.

RCL 2 Extension facts

PropertyRCL 2 valueMeaning
Allowed Extensions5You can place up to five owned Extensions.
Energy capacity50 eachFilled Extensions add room spawning Energy.
Construction cost3000 progressA basic Builder needs many work ticks and trips.

A completed Extension does not create Energy and does not fill itself. Harvester delivery logic must supply it later.

Place one Extension Construction Site

Use the current client's construction interface, choose Extension, and select a valid open tile near the Spawn that does not block an important path. Interface button positions can change, so follow the labels in the current client rather than a fixed screenshot.

The map first shows a Construction Site. The real Extension object appears only after the site reaches its total progress.

Read-only precheck

State impact: Read-only.

const creep = Game.creeps['Builder1'];

if (!creep) {
  console.log('Builder1 was not found.');
} else {
  const controller = creep.room.controller;
  const extensionSites =
    creep.room.find(FIND_MY_CONSTRUCTION_SITES, {
      filter: function (site) {
        return site.structureType === STRUCTURE_EXTENSION;
      }
    });

  console.log(JSON.stringify({
    roomName: creep.room.name,
    controllerLevel: controller ? controller.level : null,
    extensionSiteCount: extensionSites.length,
    firstSiteProgress:
      extensionSites[0] ? extensionSites[0].progress : null,
    firstSiteProgressTotal:
      extensionSites[0] ? extensionSites[0].progressTotal : null,
    carriedEnergy:
      creep.store.getUsedCapacity(RESOURCE_ENERGY)
  }));
}

Complete Builder1 code for one Extension

State impact: Calls harvest(), build(), and moveTo(), and writes creep.memory.building.

const CREEP_NAME = 'Builder1';

function moveToTarget(creep, target, label) {
  const moveResult = creep.moveTo(target, {
    reusePath: 5
  });

  if (moveResult !== OK &&
      moveResult !== ERR_TIRED) {
    console.log(
      creep.name +
      ' moveTo(' +
      label +
      ') returned ' +
      moveResult +
      '.'
    );
  }
}

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

  if (!creep) {
    console.log(
      CREEP_NAME +
      ' was not found. Create it or check the name.'
    );
    return;
  }

  if (creep.spawning) {
    return;
  }

  const source = creep.room.find(FIND_SOURCES)[0];

  if (!source) {
    console.log(
      CREEP_NAME +
      ' cannot find a visible Source.'
    );
    return;
  }

  const sites =
    creep.room.find(FIND_MY_CONSTRUCTION_SITES, {
      filter: function (site) {
        return site.structureType === STRUCTURE_EXTENSION;
      }
    });

  const site = sites[0];
  const usedEnergy =
    creep.store.getUsedCapacity(RESOURCE_ENERGY) || 0;
  const freeEnergy =
    creep.store.getFreeCapacity(RESOURCE_ENERGY) || 0;

  if (usedEnergy === 0) {
    creep.memory.building = false;
  }

  if (freeEnergy === 0) {
    creep.memory.building = true;
  }

  if (creep.memory.building) {
    if (!site) {
      creep.say('no site');
      return;
    }

    const buildResult = creep.build(site);

    if (buildResult === ERR_NOT_IN_RANGE) {
      moveToTarget(creep, site, 'Extension site');
    } else if (buildResult !== OK) {
      console.log(
        CREEP_NAME +
        ' build() returned ' +
        buildResult +
        '.'
      );
    }

    return;
  }

  const harvestResult = creep.harvest(source);

  if (harvestResult === ERR_NOT_IN_RANGE) {
    moveToTarget(creep, source, 'Source');
  } else if (harvestResult !== OK &&
             harvestResult !== ERR_NOT_ENOUGH_RESOURCES) {
    console.log(
      CREEP_NAME +
      ' harvest() returned ' +
      harvestResult +
      '.'
    );
  }
};

How building works across ticks

  1. Builder1 harvests while its Store has free capacity.
  2. When full, memory.building becomes true.
  3. The code selects the first owned Extension site in the current room.
  4. build() works within range 3 and consumes carried Energy.
  5. Site progress increases across ticks.
  6. When Builder1 becomes empty, it returns to harvesting.
  7. After progress reaches the total, the site becomes a StructureExtension.

build() results beginners should recognize

CodeMeaningResponse
OKThe build action was scheduled.Observe later ticks.
ERR_NOT_IN_RANGEThe site is farther than range 3.Move closer.
ERR_NOT_ENOUGH_RESOURCESThe Creep carries no Energy.Return to the Source.
ERR_NO_BODYPARTNo active WORK part remains.Inspect body damage.
ERR_INVALID_TARGETThe site is invalid or can no longer be built.Find the site again next tick.

What to observe

  1. The Controller is at least RCL 2.
  2. An owned Extension Construction Site exists.
  3. Builder1 fills its Store at the Source.
  4. It moves within range 3 of the site.
  5. The site's progress increases.
  6. The Creep repeats several Source-to-site trips.
  7. The site becomes a real Extension.
  8. The new Extension initially has zero Energy.

Common problems

Builder1 says “no site”

No owned Extension site exists in its current room, or the site already finished.

The site exists but progress does not increase

Inspect carried Energy, active WORK, range, and the saved buildResult.

The finished Extension stays empty

Construction and delivery are separate. Update Harvester1 later to fill both Spawn and Extension.

The code ignores another Construction Site

This lesson intentionally filters to Extension sites so it solves one specific beginner task.

Debugging checklist

  • Confirm the Controller is RCL 2 or higher.
  • Confirm Builder1 exists and is not spawning.
  • Confirm an owned Extension site exists in the same room.
  • Confirm a visible Source exists.
  • Confirm active WORK, CARRY, and MOVE.
  • Inspect Store values and memory.building.
  • Save build, harvest, and movement return codes.
  • Verify site progress across later ticks.
  • Do not expect a completed Extension to contain Energy automatically.

Scope and next step

This lesson builds one Extension and does not create layouts, sort several sites, or manage multiple Builders. Continue with the build-repair priority lesson so Builder1 has useful work after the site is finished.

Frequently asked questions

How many Extensions can RCL 2 build?

Five.

How much Energy can each store at RCL 2?

50 Energy.

How much construction progress is required?

3000 progress under the current construction cost.

Why is the finished Extension empty?

A Creep must transfer Energy into it after construction.

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.