Recommend a lightweight pathfinding library



  • So, I need to optimize my pathfinding, and I'd like to get to that from both ends (both the algorithm and caching), so I've been looking for a good library to do the thing for some time, unsucessfully. So, can anyone recommend a small (a file or two) and fast js pathfinding library with support of movement costs?



  • Following is my high efficiency caching code.
    It uses the builtin path finding and caches very aggressively.

    I've run 50+ creeps on 20cpu with this code.

    It handles blocked paths by taking a random step+hoping it finds a better cached path. This actually works rather well.
    When multiple routes involving the given tile have been cached, the script chooses from them in a weighted random fashion, this keeps all your creeps from clogging up on the same route when they travel at differing speeds.

    
    function routeCreep(creep,dest) {
    
    
        if(creep.fatigue>0){
            return -1;
        }
        if(typeof dest == "undefined"){
            return -1;
        }
    
        var locStr = creep.room.name+"."+creep.pos.x+"."+creep.pos.y
    
        var path = false;
    
        if(typeof Memory.routeCache !== "object"){
             Memory.routeCache = {};
        }
    
        if(typeof Memory.routeCache[locStr] === "undefined"){
    
            Memory.routeCache[locStr] = {'dests':{},'established':Game.time}
    
    
        }
        if(typeof Memory.routeCache[locStr]['dests'][''+dest.id] === "undefined"){    
            Memory.routeCache[locStr]['dests'][dest.id] = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0};
            path = creep.room.findPath(creep.pos,dest.pos,{maxOps:500,heuristicWeight:2})
            if(typeof path[0] !== "undefined"){
    
    
            Memory.routeCache[locStr]['dests'][''+dest.id][path[0].direction]+=1;
    
            for(var i =0;i<path.length-1;i++){
                var step = path[i];
                var stepStr = creep.room.name+"."+step.x+"."+step.y//creep.room.name+"."+step.x+"."+step.y
                if(typeof Memory.routeCache[stepStr] === "undefined"){
                    Memory.routeCache[stepStr] = {'dests':{},'established':Game.time,'usefreq':0.0};
                }
                if(typeof Memory.routeCache[stepStr]['dests'][''+dest.id] === "undefined"){
                   Memory.routeCache[stepStr]['dests'][''+dest.id] = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0};
                }
                //console.log(path[i+1].direction);
                Memory.routeCache[stepStr]['dests'][''+dest.id][path[i+1].direction]+=1;
    
            }
            }
            else{
    
                dir = Math.floor(Math.random()*8);
    
    
                var error = creep.move(dir);
                return error;
    
            }
        }
    
        for(var k in Memory.routeCache[locStr]['dests']){
            if(Game.getObjectById(k)==null){//clean out invalid routes
                delete  Memory.routeCache[locStr]['dests'][k];
                //console.log("Pruned",k)
            }
        }
    
    
        var total = 0.0//pick from the weighted list of steps
        for(var d in Memory.routeCache[locStr]['dests'][''+dest.id]){
            total+=Memory.routeCache[locStr]['dests'][''+dest.id][d];
            }
        }
        var total=total*Math.random();
    
        var dir = 0;
        for(var d in Memory.routeCache[locStr]['dests'][''+dest.id]){
            total-=Memory.routeCache[locStr]['dests'][''+dest.id][d];
            if(total<0){
                dir = d;
                break;
            }
    
        }
    
        if(creep.pos.getRangeTo(dest)>1 && pathisBlocked(creep.pos,dir)){ //you will need your own "pathisBlocked" function!
            dir = Math.floor(Math.random()*8);
        }
    
    
        var error = creep.move(dir);
         return error;
    
    }
    
    


  • Great! Very helpful. But one question: how do you deal with moving targets, like creeps? I didn't see that handled in the code.



  • The short answer is: I don't.

    I have creeps that target moving creeps re-calculate every time they move.
    The only real caching options here are: check if the target has moved enough to merit an update, if so recalculate.