Skip to content

Commit 2697f56

Browse files
committed
Use unique Name<T> type for names of creeps, rooms, spawns, etc
1 parent b8bd8e6 commit 2697f56

21 files changed

+181
-150
lines changed

dist/index.d.ts

Lines changed: 64 additions & 52 deletions
Large diffs are not rendered by default.

dist/screeps-tests.ts

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,22 @@
1212

1313
// Sample inputs
1414

15-
const creep: Creep = Game.creeps.sampleCreep;
16-
const room: Room = Game.rooms.W10S10;
17-
const flag: Flag = Game.flags.Flag1;
18-
const powerCreep: PowerCreep = Game.powerCreeps.samplePowerCreep;
19-
const spawn: StructureSpawn = Game.spawns.Spawn1;
15+
const creepName = "sampleCreep" as Name<Creep>;
16+
const creep: Creep = Game.creeps[creepName];
17+
const roomName = "W11S11" as Name<Room>;
18+
const room: Room = Game.rooms[roomName];
19+
const flagName = "Flag1" as Name<Flag>;
20+
const flag: Flag = Game.flags[flagName];
21+
const powerCreepName = "samplePowerCreep" as Name<PowerCreep>;
22+
const powerCreep: PowerCreep = Game.powerCreeps[powerCreepName];
23+
const spawnName = "Spawn1" as Name<StructureSpawn>;
24+
const spawn: StructureSpawn = Game.spawns[spawnName];
2025
const body: BodyPartConstant[] = [WORK, WORK, CARRY, MOVE];
26+
const shardName = "shard0" as Name<Shard>;
2127

2228
// Sample inputs for Game.map.findRoute testing
23-
const anotherRoomName: Room = Game.rooms.W10S11;
29+
const anotherRoomName = "E22S22" as Name<Room>;
30+
const anotherRoom: Room = Game.rooms[anotherRoomName];
2431

2532
// Sample memory extensions
2633
interface CreepMemory {
@@ -74,24 +81,24 @@ function resources(o: GenericStore): ResourceConstant[] {
7481
// Game.creeps
7582

7683
{
77-
for (const creepName of Object.keys(Game.creeps)) {
84+
for (const creepName of Object.keys(Game.creeps) as Array<keyof typeof Game.creeps>) {
7885
Game.creeps[creepName].moveTo(flag);
7986
}
8087
}
8188

8289
// Game.flags
8390

8491
{
85-
creep.moveTo(Game.flags.Flag1);
92+
creep.moveTo(Game.flags[flagName]);
8693
}
8794

8895
// Game.powerCreeps
8996

9097
{
9198
PowerCreep.create("steve", POWER_CLASS.OPERATOR) === OK;
9299

93-
for (const i of Object.keys(Game.powerCreeps)) {
94-
const powerCreep = Game.powerCreeps[i];
100+
for (const powerCreepName of Object.keys(Game.powerCreeps) as Array<keyof typeof Game.powerCreeps>) {
101+
const powerCreep = Game.powerCreeps[powerCreepName];
95102

96103
if (powerCreep.ticksToLive === undefined) {
97104
// Not spawned in world; spawn creep
@@ -104,7 +111,7 @@ function resources(o: GenericStore): ResourceConstant[] {
104111
powerCreep.powers[PWR_GENERATE_OPS].cooldown === 0 &&
105112
(powerCreep.carry.ops || 0) < 10
106113
) {
107-
Game.powerCreeps[i].usePower(PWR_GENERATE_OPS);
114+
Game.powerCreeps[powerCreepName].usePower(PWR_GENERATE_OPS);
108115
} else {
109116
// Boost resource
110117
const targetSource = Game.getObjectById("targetSourceID" as Id<Source>)!;
@@ -127,7 +134,7 @@ function resources(o: GenericStore): ResourceConstant[] {
127134
powerCreep.upgrade(PWR_GENERATE_OPS);
128135
}
129136

130-
const myPowaCreeps = Game.rooms.sim.find(FIND_MY_POWER_CREEPS);
137+
const myPowaCreeps = Game.rooms["sim" as Name<Room>].find(FIND_MY_POWER_CREEPS);
131138

132139
// Constant type checking
133140
POWER_INFO[PWR_GENERATE_OPS].className === POWER_CLASS.OPERATOR;
@@ -137,7 +144,7 @@ function resources(o: GenericStore): ResourceConstant[] {
137144
// Game.spawns
138145

139146
{
140-
for (const i of Object.keys(Game.spawns)) {
147+
for (const i of Object.keys(Game.spawns) as Array<keyof typeof Game.spawns>) {
141148
Game.spawns[i].createCreep(body);
142149

143150
// Test StructureSpawn.Spawning
@@ -188,7 +195,7 @@ function resources(o: GenericStore): ResourceConstant[] {
188195
// Game.cpu.setShardLimits()
189196

190197
{
191-
Game.cpu.setShardLimits({ shard0: 20, shard1: 10 });
198+
Game.cpu.setShardLimits({ [shardName]: 20, ["privateshard" as Name<Shard>]: 10 });
192199
}
193200

194201
// Game.cpu.halt()
@@ -227,9 +234,9 @@ function resources(o: GenericStore): ResourceConstant[] {
227234
}
228235

229236
{
230-
if (Game.spawns["Spawn1"].energy === 0) {
237+
if (Game.spawns[spawnName].energy === 0) {
231238
Game.notify(
232-
"Spawn1 is out of energy",
239+
`${spawnName} is out of energy`,
233240
180, // group these notifications for 3 hours
234241
);
235242
}
@@ -238,7 +245,7 @@ function resources(o: GenericStore): ResourceConstant[] {
238245
// Game.map.describeExits()
239246

240247
{
241-
const exits = Game.map.describeExits("W8N3");
248+
const exits = Game.map.describeExits(roomName);
242249
if (exits) {
243250
keys(exits).map((exitKey) => {
244251
const nextRoom = exits[exitKey];
@@ -252,8 +259,8 @@ function resources(o: GenericStore): ResourceConstant[] {
252259
// Game.map.findExit()
253260

254261
{
255-
if (creep.room.name !== anotherRoomName.name) {
256-
const exitDir = Game.map.findExit(creep.room, anotherRoomName);
262+
if (creep.room.name !== anotherRoom.name) {
263+
const exitDir = Game.map.findExit(creep.room, anotherRoom);
257264
if (exitDir !== ERR_NO_PATH && exitDir !== ERR_INVALID_ARGS) {
258265
const exit = creep.pos.findClosestByRange(exitDir);
259266
if (exit !== null) {
@@ -266,13 +273,13 @@ function resources(o: GenericStore): ResourceConstant[] {
266273
}
267274

268275
{
269-
creep.moveTo(new RoomPosition(25, 25, anotherRoomName.name));
276+
creep.moveTo(new RoomPosition(25, 25, anotherRoom.name));
270277
}
271278

272279
// Game.map.findRoute()
273280

274281
{
275-
const route = Game.map.findRoute(creep.room, anotherRoomName);
282+
const route = Game.map.findRoute(creep.room, anotherRoom);
276283

277284
if (route !== ERR_NO_PATH && route.length > 0) {
278285
const exit = creep.pos.findClosestByRange(route[0].exit);
@@ -283,7 +290,7 @@ function resources(o: GenericStore): ResourceConstant[] {
283290
}
284291

285292
{
286-
const route = Game.map.findRoute(creep.room, anotherRoomName, {
293+
const route = Game.map.findRoute(creep.room, anotherRoom, {
287294
routeCallback(roomName, fromRoomName) {
288295
if (roomName === "W10S10") {
289296
// avoid this room
@@ -295,8 +302,8 @@ function resources(o: GenericStore): ResourceConstant[] {
295302
}
296303

297304
{
298-
const from = new RoomPosition(25, 25, "E1N1");
299-
const to = new RoomPosition(25, 25, "E4N1");
305+
const from = new RoomPosition(25, 25, roomName);
306+
const to = new RoomPosition(25, 25, "W1S1" as Name<Room>);
300307

301308
// Use `findRoute` to calculate a high-level plan for this path,
302309
// prioritizing highways and owned rooms
@@ -348,11 +355,11 @@ function resources(o: GenericStore): ResourceConstant[] {
348355
// Game.map.getTerrainAt(pos)
349356

350357
{
351-
Game.map.getTerrainAt(25, 20, "W10N10");
358+
Game.map.getTerrainAt(25, 20, roomName);
352359
}
353360

354361
{
355-
Game.map.getTerrainAt(new RoomPosition(25, 20, "W10N10"));
362+
Game.map.getTerrainAt(new RoomPosition(25, 20, roomName));
356363
}
357364

358365
// Game.map.getRoomStatus(roomName)
@@ -368,7 +375,7 @@ function resources(o: GenericStore): ResourceConstant[] {
368375

369376
{
370377
// Game.market.calcTransactionCost(amount, roomName1, roomName2)
371-
const cost = Game.market.calcTransactionCost(1000, "W0N0", "W10N5");
378+
const cost = Game.market.calcTransactionCost(1000, roomName, anotherRoomName);
372379

373380
// Game.market.cancelOrder(orderId)
374381
for (const id of Object.keys(Game.market.orders)) {
@@ -379,7 +386,7 @@ function resources(o: GenericStore): ResourceConstant[] {
379386
Game.market.changeOrderPrice("57bec1bf77f4d17c4c011960", 9.95);
380387

381388
// Game.market.createOrder({type, resourceType, price, totalAmount, [roomName]})
382-
Game.market.createOrder({ type: ORDER_SELL, resourceType: RESOURCE_GHODIUM, price: 9.95, totalAmount: 10000, roomName: "W1N1" });
389+
Game.market.createOrder({ type: ORDER_SELL, resourceType: RESOURCE_GHODIUM, price: 9.95, totalAmount: 10000, roomName: roomName });
383390
Game.market.createOrder({ type: ORDER_SELL, resourceType: RESOURCE_GHODIUM, price: 9.95, totalAmount: 10000 });
384391

385392
// Testing the hardcoded string literal value of the `type` field
@@ -398,18 +405,18 @@ function resources(o: GenericStore): ResourceConstant[] {
398405
}
399406

400407
// Game.market.deal(orderId, amount, [yourRoomName])
401-
Game.market.deal("57cd2b12cda69a004ae223a3", 1000, "W1N1");
408+
Game.market.deal("57cd2b12cda69a004ae223a3", 1000, roomName);
402409

403410
const amountToBuy = 2000;
404411
const maxTransferEnergyCost = 500;
405412
const orders = Game.market.getAllOrders({ type: ORDER_SELL, resourceType: RESOURCE_GHODIUM });
406413

407414
for (const i of orders) {
408415
if (i.roomName) {
409-
const transferEnergyCost = Game.market.calcTransactionCost(amountToBuy, "W1N1", i.roomName);
416+
const transferEnergyCost = Game.market.calcTransactionCost(amountToBuy, roomName, i.roomName);
410417

411418
if (transferEnergyCost < maxTransferEnergyCost) {
412-
Game.market.deal(i.id, amountToBuy, "W1N1");
419+
Game.market.deal(i.id, amountToBuy, roomName);
413420
break;
414421
}
415422
}
@@ -427,7 +434,7 @@ function resources(o: GenericStore): ResourceConstant[] {
427434
(currentOrder) =>
428435
currentOrder.resourceType === RESOURCE_GHODIUM &&
429436
currentOrder.type === ORDER_SELL &&
430-
Game.market.calcTransactionCost(1000, targetRoom, currentOrder.roomName!) < 500,
437+
Game.market.calcTransactionCost(1000, anotherRoomName, currentOrder.roomName!) < 500,
431438
);
432439

433440
// Game.market.getOrderById(id)
@@ -451,7 +458,7 @@ function resources(o: GenericStore): ResourceConstant[] {
451458
// PathFinder
452459

453460
{
454-
const pfCreep = Game.creeps.John;
461+
const pfCreep = Game.creeps[creepName];
455462

456463
const goals = pfCreep.room.find(FIND_SOURCES).map((source) => {
457464
// We can't actually walk on sources-- set `range` to 1
@@ -573,7 +580,7 @@ function resources(o: GenericStore): ResourceConstant[] {
573580
InterShardMemory.setLocal(localShardData);
574581
localShardData = InterShardMemory.getLocal();
575582

576-
const remoteShardData: string = InterShardMemory.getRemote("shard2") || "";
583+
const remoteShardData: string = InterShardMemory.getRemote("shard2" as Name<Shard>) || "";
577584
}
578585

579586
// Find Overloads
@@ -984,7 +991,7 @@ function resources(o: GenericStore): ResourceConstant[] {
984991
// test discriminated union
985992
switch (unowned.structureType) {
986993
case STRUCTURE_TOWER:
987-
unowned.heal(Game.creeps.myCreep);
994+
unowned.heal(Game.creeps["myCreep" as Name<Creep>]);
988995
break;
989996
case STRUCTURE_CONTAINER:
990997
case STRUCTURE_STORAGE:
@@ -1000,15 +1007,15 @@ function resources(o: GenericStore): ResourceConstant[] {
10001007
// test discriminated union using filter functions on find
10011008

10021009
// $ExpectType AnyStructure
1003-
const from = Game.rooms.myRoom.find(FIND_STRUCTURES, {
1010+
const from = Game.rooms["myRoom" as Name<Room>].find(FIND_STRUCTURES, {
10041011
filter: (s) => (s.structureType === STRUCTURE_CONTAINER || s.structureType === STRUCTURE_STORAGE) && s.store.energy > 0,
10051012
})[0];
10061013
// $ExpectType AnyOwnedStructure | null
10071014
const to = from.pos.findClosestByPath(FIND_MY_STRUCTURES, {
10081015
filter: (s) => (s.structureType === STRUCTURE_SPAWN || s.structureType === STRUCTURE_EXTENSION) && s.energy < s.energyCapacity,
10091016
});
10101017

1011-
Game.rooms.myRoom
1018+
Game.rooms["myRoom" as Name<Room>]
10121019
.find(FIND_MY_STRUCTURES, {
10131020
filter: (s) => s.structureType === STRUCTURE_RAMPART,
10141021
})
@@ -1017,7 +1024,7 @@ function resources(o: GenericStore): ResourceConstant[] {
10171024

10181025
{
10191026
// Test that you can use signatures
1020-
EXTENSION_ENERGY_CAPACITY[Game.rooms.myRoom.controller!.level];
1027+
EXTENSION_ENERGY_CAPACITY[Game.rooms[roomName].controller!.level];
10211028

10221029
REACTIONS[Object.keys(creep.carry)[0]];
10231030

@@ -1036,7 +1043,7 @@ function resources(o: GenericStore): ResourceConstant[] {
10361043

10371044
tombstone.id;
10381045

1039-
const creep = Game.creeps["dave"];
1046+
const creep = Game.creeps["dave" as Name<Creep>];
10401047
creep.withdraw(tombstone, RESOURCE_ENERGY);
10411048
}
10421049

@@ -1127,13 +1134,13 @@ function resources(o: GenericStore): ResourceConstant[] {
11271134
// Room.Terrain
11281135

11291136
{
1130-
const room = Game.rooms[""];
1137+
const room = Game.rooms["" as Name<Room>];
11311138

11321139
const myTerrain = room.getTerrain();
11331140

1134-
const otherTerrain = new Room.Terrain("E2S7");
1141+
const otherTerrain = new Room.Terrain(roomName);
11351142

1136-
const anotherTerrain = Game.map.getRoomTerrain("W2N5");
1143+
const anotherTerrain = Game.map.getRoomTerrain(anotherRoomName);
11371144

11381145
const ret = myTerrain.get(5, 5);
11391146
if (ret === 0) {
@@ -1267,10 +1274,10 @@ function atackPower(creep: Creep) {
12671274
// Game.map.visual
12681275
{
12691276
const mapVis = Game.map.visual;
1270-
const point1 = new RoomPosition(1, 1, "E1N1");
1271-
const point2 = new RoomPosition(1, 1, "E1N8");
1272-
const point3 = new RoomPosition(1, 1, "E8N8");
1273-
const point4 = new RoomPosition(1, 1, "E1N8");
1277+
const point1 = new RoomPosition(1, 1, roomName);
1278+
const point2 = new RoomPosition(1, 1, anotherRoomName);
1279+
const point3 = new RoomPosition(1, 1, "E8N8" as Name<Room>);
1280+
const point4 = new RoomPosition(1, 1, "E1N8" as Name<Room>);
12741281

12751282
mapVis.line(point1, point2).circle(point3, { fill: "#f2f2f2" }).poly([point1, point2, point3, point4]).rect(point3, 50, 50);
12761283

src/creep.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ interface Creep extends RoomObject {
7878
* You can choose the name while creating a new creep, and it cannot be changed later.
7979
* This name is a hash key to access the creep via the {@link Game.creeps} object.
8080
*/
81-
name: string;
81+
name: Name<Creep>;
8282
/**
8383
* An object with the creep’s owner info.
8484
*/

src/flag.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ interface Flag extends RoomObject {
2323
*
2424
* This name is a hash key to access the flag via the {@link Game.flags} object. The maximum name length is 60 characters.
2525
*/
26-
name: string;
26+
name: Name<Flag>;
2727
/**
2828
* Flag secondary color. One of the {@link ColorConstant COLOR_*} constants.
2929
*/
@@ -62,8 +62,8 @@ interface Flag extends RoomObject {
6262
}
6363

6464
interface FlagConstructor extends _Constructor<Flag> {
65-
new (name: string, color: ColorConstant, secondaryColor: ColorConstant, roomName: string, x: number, y: number): Flag;
66-
(name: string, color: ColorConstant, secondaryColor: ColorConstant, roomName: string, x: number, y: number): Flag;
65+
new (name: Name<Flag>, color: ColorConstant, secondaryColor: ColorConstant, roomName: Name<Room>, x: number, y: number): Flag;
66+
(name: Name<Flag>, color: ColorConstant, secondaryColor: ColorConstant, roomName: Name<Room>, x: number, y: number): Flag;
6767
}
6868

6969
declare const Flag: FlagConstructor;

src/game.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ interface Game {
99
/**
1010
* A hash containing all your creeps with creep names as hash keys.
1111
*/
12-
creeps: { [creepName: string]: Creep };
12+
creeps: { [creepName: Name<Creep>]: Creep };
1313
/**
1414
* A hash containing all your flags with flag names as hash keys.
1515
*/
16-
flags: { [flagName: string]: Flag };
16+
flags: { [flagName: Name<Flag>]: Flag };
1717
/**
1818
* Your Global Control Level.
1919
*/
@@ -35,7 +35,7 @@ interface Game {
3535
*
3636
* Even power creeps not spawned in the world can be accessed here.
3737
*/
38-
powerCreeps: { [creepName: string]: PowerCreep };
38+
powerCreeps: { [creepName: Name<PowerCreep>]: PowerCreep };
3939
/**
4040
* An object with your global resources that are bound to the account, like pixels or cpu unlocks.
4141
*
@@ -47,11 +47,11 @@ interface Game {
4747
*
4848
* A room is visible if you have a creep or an owned structure in it.
4949
*/
50-
rooms: { [roomName: string]: Room };
50+
rooms: { [roomName: Name<Room>]: Room };
5151
/**
5252
* A hash containing all your spawns with spawn names as hash keys.
5353
*/
54-
spawns: { [spawnName: string]: StructureSpawn };
54+
spawns: { [spawnName: Name<StructureSpawn>]: StructureSpawn };
5555
/**
5656
* A hash containing all your structures with structure id as hash keys.
5757
*/

0 commit comments

Comments
 (0)