最近在玩screeps,记点东西

Game

Game.cpu.getUsed()

screeps里没有console.time()和console.timeEnd(),不过有 Game.cpu.getUsed() 函数起到差不多的作用。用两个getUsed把想要查看性能的地方包起来,再求差即可。

Game.cpu.generatePixel()

如果你刚开始玩这个游戏的话可以给主循环加上这条代码,帮助你获取pixel资源。与CPU限制有关的资料见此。https://screeps-cn.github.io/cpu-limit.html

if(Game.cpu.bucket == 10000) {
    Game.cpu.generatePixel();
}

Game.gcl

升到第n级GCL所需总经验的公式如下:Math.pow(gclLevel - 1, C.GCL_POW) * C.GCL_MULTIPLY

其中 GCL_POW 为2.4, GCL_MULTIPLY 为1 000 000,

即: (n - 1)^2.4 * 1 000 000

Game.gpl

升到第n级所需总经验的公式如下:n^2 * 1 000,

Game.market

Game.market.getAllOrders()

具体可以参见getAllOrders的源码,当传入的filter带有resourceType属性时,会直接从服务器缓存中返回该种类型的所所有订单。反之则返回全部订单。第二种写法相当于对所有订单执行了过滤,所以消耗了大量的时间。

Game.structures

Game.structures中不包含reserve的controller

Creep

Creep.prototype.claimController

占领controller无主但房间内留有其他玩家建筑的房间不会导致建筑瞬间被摧毁。但是无法使用别人的建筑。

寻路部分

Creep.prototype.moveTo里面套了一个creep.prototype.moveByPath

Creep.prototype.moveByPath

路径的数组输入和字符串输入是两套逻辑..数组输入具有较大的宽容性,还未上路时,在起点的周围8格内都可以回到起点。而字符串输入没有这个容错。

注:Path数组样例

[{ x: 10, y: 5, dx: 1,  dy: 0, direction: RIGHT },
 { x: 10, y: 6, dx: 0,  dy: 1, direction: BOTTOM },
 { x: 9,  y: 7, dx: -1, dy: 1, direction: BOTTOM_LEFT },
 ...]    
Creep.prototype.moveByPath = register.wrapFn(function(path) {
        if(_.isArray(path) && path.length > 0 && (path[0] instanceof globals.RoomPosition)) {
            var idx = _.findIndex(path, (i) => i.isEqualTo(this.pos));
            if(idx === -1) {
                if(!path[0].isNearTo(this.pos)) {
                    return C.ERR_NOT_FOUND;
                }
            }
            idx++;
            if(idx >= path.length) {
                return C.ERR_NOT_FOUND;
            }

            return this.move(this.pos.getDirectionTo(path[idx]));
        }

        if(_.isString(path)) {
            path = utils.deserializePath(path);
        }
        if(!_.isArray(path)) {
            return C.ERR_INVALID_ARGS;
        }
        var cur = _.find(path, (i) => i.x - i.dx == this.pos.x && i.y - i.dy == this.pos.y);
        if(!cur) {
            return C.ERR_NOT_FOUND;
        }

        return this.move(cur.direction);
    });

Room

RoomPosition.prototype.findInRange

findInRange居然是先进行一次find,然后从结果中过滤出给定范围内的对象。。

RoomPosition

findInRange距离为0时可以在同格内寻找。

Invader

InvaderCreep

偶然发现InvaderCreep杀光房间内所有creep后会自杀。暂时没去探究是否为设定。

此外,非claimed的房间内应该没有自杀行为。

各等级要塞

不写了,有空直接对着要塞的生成源码抄

lv1:

Rampart具有100k hits

战利品:

lv2:

Mineral

注:以下代码来源于官方自带的私服,暂时没有看官服的

矿脉类型概率

if(opts.mineral === undefined) {
                    var types = ['H','H','H','H','H','H',  'O','O','O','O','O','O',  'Z','Z','Z', 'K','K','K', 'U','U','U', 'L','L','L', 'X'];
                    opts.mineral = types[Math.floor(Math.random()*types.length)];
}

H、O:6/25

Z、K、U、L:3/25

X:1/25

此外,根据私服源码,默认的房间生成方法里,每个‘正常’房间只有1种的1座矿脉。不过可以调参数以不生成。

矿脉数量

官服中默认条件下只会生成一种的一座矿脉。不过在私服里可以修改数据来得到同种多座\多种矿脉

同种多座
多种多座