Can Defold do more "advanced" AI?


#1

So I am in a start up phase of a project I am planning. This will be a kind of trial to see if I have what
it takes to make a game.

Even tho my project is a basic one it has one quite important aspect, AI.

So I tried to search for AI etc in Defold but only found info about a basic AI random movement / chase
player kind of thing and what I wonder is has anyone done a more advanced AI?

Example: AI character that can navigate in a village that can change, (houses removed/added), prefer to use “roads / paths” when it navigates around. Think a small village with a few number of AI characters going around their business. I have tried this in other products with basic navmesh etc that works ok.

Thanks in advance

MP


#2

There are some path-finding examples around. Check out this A* example for instance: https://github.com/JCash/defoldexamples/tree/master/main/astar


#3

Checked it quickly now and will see if I can do something with it tonight. Tho would
need a lot of customization to get it to work with a “villager” AI moving in a city.

But thanks for tip!


#4

I haven’t used that A* example extensively myself, but it should be pretty perfect for what you want, actually. If it works the way I think it does, the level_cost table in main.script stores the movement cost for each type of tile (keyed by the tile index). So if you build your city with a tilemap, all you have to do is put in the movement cost for your tiles (low for roads, more for rough terrain, some very large amount for solid walls, etc.) and it will give you optimal paths through the city for your villagers.


[Edit] Hmm, it seems like there’s a couple small typos in main.script that break the movement cost settings. Maybe @Mathias_Westerdahl can check this?

Current
...
    for ly = 0, h-1 do
	for lx = 0, w-1 do
	    local tile = tilemap.get_tile("/level#tilemap", hash("ground"), lx+1, ly+1)
	    local tilecost = level_cost[tile]
	    if tilecost == nil then
	       tile = 10000 -- should be tilecost = 10000?
	    end
	    
        level[ly * w + lx + 1] = tile -- should be = tilecost?
        count = count + 1
	end
    end
...
Fix?
...
    for ly = 0, h-1 do
	for lx = 0, w-1 do
	    local tile = tilemap.get_tile("/level#tilemap", hash("ground"), lx+1, ly+1)
	    local tilecost = level_cost[tile]
	    if tilecost == nil then
	       tilecost = 10000
	    end
	    
        level[ly * w + lx + 1] = tilecost
        count = count + 1
	end
    end
...

After changing that, it seems to work perfectly. Here’s a screenshot where I added “roads” that are 4x cheaper to move on than regular ground.


[Edit2] . . . and if you don’t feel like figuring out someone else’s code, you can always do your own implementation. There’s an excellent intro to A* here.


#5

That is very good stuff there @ross.grams That actually is spot on what I as thinking with regarding cost of movement etc. Should help with the path finding etc. I shall check that out more and see if I can get my limited mind around it :slight_smile:

Thanks for taking time to reply.


#6

I use 2D grid floodfill algorithm to create paths to the player in an old Ludum Dare entry. These paths are used by the enemies to navigate to the player. The floodfill data can include a cost to accommodate for different kinds of terrain. The code for doing the floodfill can be found here and the whole game here with an HTML5 version here.


#7

Thanks for your example, I’ll try to modernize it for using in my project. In my case I need big cost for turns.