## Short article on AI

General discussion about LÖVE, Lua, game development, puns, and unicorns.
ivan
Party member
Posts: 1719
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Short article on AI

Hey everybody, check out my short article on game AI using behavior trees:
http://2dengine.com/
The examples do not use the Love framework but I think it's not that important,
in a sense that the code is clear and not very framework dependent.
Thanks,
Ivan

PS. If I make a full fledged module I promise to name it (Crazy Ivan's)AI
Last edited by ivan on Sun Sep 20, 2015 9:26 am, edited 1 time in total.
TsT
Party member
Posts: 161
Joined: Thu Sep 25, 2008 7:04 pm
Location: France
Contact:

### Re: Short article on AI

Nice
My projects current projects : dragoon-framework (includes lua-newmodule, lua-provide, lovemodular, , classcommons2, and more ...)
ivan
Party member
Posts: 1719
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Short article on AI

Check it out, part 2 of the AI tutorial is up:
http://2dengine.com/
Last edited by ivan on Sun Sep 20, 2015 9:26 am, edited 2 times in total.
ivan
Party member
Posts: 1719
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Short article on AI

Updated to version 1.1. Fixed a couple of bugs in the code.
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

### Re: Short article on AI

Your website is down for me.
ivan
Party member
Posts: 1719
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Short article on AI

Looks like there was some server downtime last night. Should be ok now.

Also, if anybody is interested, the AI module could be used for visual effects as well.
Here is a nice little tween class that you can add to the "ai2.lua" module:

Code: Select all

--
-- Tween
--
local TweenG = {}
local TweenGMT = { __index = TweenG }

base.setmetatable ( TweenG, { __index = Goal } )

function TweenG:Create ( property, value, time, elapsed )
local goal = {}
base.setmetatable ( goal, TweenGMT )

goal.property = property
goal.value = value
goal.time = time
goal.elapsed = elapsed or 0

return goal
end
function TweenG:Destroy ( )
self.property = nil
self.value = nil
self.time = nil
self.elapsed = nil
end
function TweenG:Reset ( )
self.elapsed = 0
end
function TweenG:Process ( delta, owner )
self.elapsed = self.elapsed + delta

-- condition
if self.elapsed >= self.time then
owner[self.property] = self.value
local used = delta - ( self.elapsed - self.time )
self:Reset ( )
return completed, used
end

-- output
local ratio = delta / ( self.time - ( self.elapsed - delta ) )
local value = owner[self.property]
owner[self.property] = value + ( self.value - value ) * ratio

return active, delta
end

Tween = TweenG.Create
This will allow you to modulate any numeric property of the owner object so for example you can do stuff like:

Code: Select all

-- changes the sprite's alpha between 0 and 1 in a 2 second tween:
c = CreateObject ( x, y, r )
c.goal = ai:Sequence ( true )
c.goal:Push ( ai:Tween ( "alpha", 0, 2 ) )
c.goal:Push ( ai:Tween ( "alpha", 1, 2 ) )
ivan
Party member
Posts: 1719
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Short article on AI

Check it out, I have a new demo of the AI system. The demo is a simple Asteroids-like game.
The arrow keys move your little ship and Z shoots.
Enemy AI code:

Code: Select all

  local hit = ai:Sequence ( false )
hit:Push ( ai:ReceiveMSG ( "shot" ) )
hit:Push ( ai:MoveTo ( x, y ) )
local goal = ai:Parallel ( true )
goal:Push ( ai:MoveTo ( 0, 10, speed, id ) )
goal:Push ( ai:RotateTo ( 0, 0, turnRate, playerID ) )
goal:Push ( hit )
Basically, the enemies are rotating towards the player and moving forward at the same time.
MoveTo moves the enemy to a given point: 0, 10 (in this case, a position relative to their own heading).
RotateTo rotates the enemy to a given point: 0, 0 (relative to the position of another object - playerID).
Whenever an enemy receives the "shot" message, he moves to x, y which is his initial position (in world coordinates).
Notice that since no speed is specified in the latter case, the enemy is teleported to his initial position.

Bullet AI:

Code: Select all

    local move = ai:Sequence ( false )
move:Push ( ai:MoveTo ( x, y, speed ) )
move:Push ( ai:Function ( "DestroyObject", id ) )
local goal = ai:Parallel ( false )
goal:Push ( move )
goal:Push ( ai:SendMSG ( "contacts", "shot" ) )
Bullets move in a straight line and notify all of their contacts of being "shot".
Upon reaching its destination point, each bullet destroys itself.

The AI system is pretty efficient and seems to work pretty smooth with up to 2000 enemies.
You can adjust the number of enemies on the following line:

Code: Select all

-- create enemies
for i = 1, 20, 1 do