Quick answer
Inspect the Rampart first, then create one request containing its exact ID, expected room, X, Y, desired boolean state, and a confirmation generated from that state and position. Recover the current object, verify it is your Rampart and all identity fields match, stop if isPublic already equals the requested value, disable the request before setPublic(), save the return code, and re-read the Rampart later.
Understand what public means
rampart.setPublic(true);
Public access permits other players' Creeps to pass through the Rampart. The method does not implement an alliance list, player-specific access, a visitor schedule, hostile-body filtering, or intent detection.
rampart.setPublic(false);
Setting the value to false restores private passage behavior. It does not transfer ownership, change other Ramparts, activate Safe Mode, or run Tower logic.
Inspect Ramparts read-only first
function inspectOwnedRamparts(roomName) {
const room = Game.rooms[roomName];
if (!room) {
return [];
}
return room.find(FIND_MY_STRUCTURES, {
filter: structure =>
structure.structureType === STRUCTURE_RAMPART
}).map(rampart => ({
id: rampart.id,
roomName: rampart.pos.roomName,
x: rampart.pos.x,
y: rampart.pos.y,
isPublic: rampart.isPublic,
hits: rampart.hits,
hitsMax: rampart.hitsMax
}));
}
Review the ID, coordinate, current state and defensive context before creating a mutation request.
Bind confirmation to target state and position
function buildRampartConfirmation(
roomName,
x,
y,
shouldBePublic
) {
const state = shouldBePublic
? 'PUBLIC'
: 'PRIVATE';
return 'SET_RAMPART_' + state + '_' + roomName + '_' + x + '_' + y;
}
Memory.rampartPublicRequest = {
enabled: true,
rampartId: 'replace-with-owned-rampart-id',
roomName: 'W1N1',
x: 20,
y: 20,
public: true,
confirmation: 'SET_RAMPART_PUBLIC_W1N1_20_20'
};
Changing public to private, moving the expected coordinate, or copying the request to another room invalidates the old phrase.
Build a testable access plan
function evaluateRampartRequest(input) {
const request = input.request;
const rampart = input.rampart;
if (!request || request.enabled !== true) {
return { ready: false, reason: 'disabled' };
}
if (
typeof request.rampartId !== 'string'
|| typeof request.roomName !== 'string'
|| !Number.isInteger(request.x)
|| !Number.isInteger(request.y)
|| request.x < 0
|| request.x > 49
|| request.y < 0
|| request.y > 49
|| typeof request.public !== 'boolean'
) {
return { ready: false, reason: 'invalid-request' };
}
const expected = buildRampartConfirmation(
request.roomName,
request.x,
request.y,
request.public
);
if (request.confirmation !== expected) {
return { ready: false, reason: 'confirmation-mismatch' };
}
if (!rampart) {
return { ready: false, reason: 'rampart-missing' };
}
if (input.owned !== true) {
return { ready: false, reason: 'not-owner' };
}
if (rampart.structureType !== STRUCTURE_RAMPART) {
return { ready: false, reason: 'type-mismatch' };
}
if (rampart.pos.roomName !== request.roomName) {
return { ready: false, reason: 'room-mismatch' };
}
if (
rampart.pos.x !== request.x
|| rampart.pos.y !== request.y
) {
return { ready: false, reason: 'position-mismatch' };
}
if (rampart.isPublic === request.public) {
return { ready: false, reason: 'state-already-matches' };
}
return { ready: true, reason: 'ready' };
}
Complete setPublic() handler
function handleRampartPublicRequest() {
const request = Memory.rampartPublicRequest;
if (!request || request.enabled !== true) {
return { status: 'disabled' };
}
const rampart = typeof request.rampartId === 'string'
? Game.getObjectById(request.rampartId)
: null;
const owned = Boolean(
rampart
&& Game.structures[rampart.id]
);
const plan = evaluateRampartRequest({
request,
rampart,
owned
});
request.checkedAt = Game.time;
request.status = plan.reason;
if (!plan.ready) {
request.enabled = false;
return { status: plan.reason };
}
request.enabled = false;
request.status = 'submitted';
request.submittedAt = Game.time;
request.before = {
rampartId: rampart.id,
roomName: rampart.pos.roomName,
x: rampart.pos.x,
y: rampart.pos.y,
beforePublic: rampart.isPublic,
requestedPublic: request.public
};
const result = rampart.setPublic(request.public);
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 = handleRampartPublicRequest();
if (
outcome.status === 'accepted'
|| outcome.status === 'failed-review-required'
) {
console.log(JSON.stringify({
type: 'rampart-public-result',
...outcome
}));
}
};
Stop when the state already matches
A matching state can mean the request is stale or another module already handled it. Close the request, record state-already-matches, and avoid a permanent per-tick no-op loop.
Disable before the call
request.enabled = false;
const result = rampart.setPublic(request.public);
Opening a Rampart can change real room access. A rejected request must be reviewed and explicitly resubmitted instead of retrying automatically.
Verify the next tick
function verifyRampartPublicRequest(request) {
const rampart = typeof request?.rampartId === 'string'
? Game.getObjectById(request.rampartId)
: null;
if (!rampart) {
return {
verified: false,
reason: 'rampart-not-visible'
};
}
return {
verified: rampart.isPublic === request.public,
rampartId: rampart.id,
isPublic: rampart.isPublic,
requestedPublic: request.public
};
}
Recover the current object. Do not reuse a previous-tick Rampart reference.
Public is not a visitor whitelist
One boolean cannot represent allowed usernames, permitted body parts, time windows, room-specific access, or automatic closure after hostile behavior. Those policies need a higher-level dispatcher, and the safest default remains private unless a reviewed operation requires public passage.
Handle return codes
| Code | Meaning | Review |
|---|---|---|
OK | State change scheduled | Re-read isPublic later |
ERR_NOT_OWNER | Rampart is not yours | ID, Game.structures and ownership |
Do not copy Creep range or Energy return codes into this method.
Debugging checklist
- Inspect Ramparts read-only first.
- Use the exact Rampart ID.
- Lock room, X, Y and target boolean.
- Bind the confirmation to state and position.
- Verify ownership through current objects.
- Stop on type, room or position mismatch.
- Close a matching-state request.
- Disable before the call.
- Save the return code and before snapshot.
- Re-read
isPubliclater.
Scope and next steps
This guide does not implement alliances, scheduled gates, body-part access, automatic threat response, Safe Mode coordination, or multi-Rampart batches. Continue with staged fortification maintenance.
Frequently asked questions
Can I pass a username array to setPublic()?
No. The method accepts a boolean, not a player list.
Why not make every road Rampart public automatically?
Layout alone does not prove access intent. A copied rule can expose protected interior paths or critical Structures.
Should public Ramparts automatically return to private?
That can be a separate reviewed task, but this one-time handler does not invent a timeout or silently reverse another request.