Short article on AI

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

Short article on AI

Post by ivan »

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.
User avatar
TsT
Party member
Posts: 161
Joined: Thu Sep 25, 2008 7:04 pm
Location: France
Contact:

Re: Short article on AI

Post by TsT »

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

Re: Short article on AI

Post by ivan »

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.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Short article on AI

Post by ivan »

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

Re: Short article on AI

Post by Kadoba »

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

Re: Short article on AI

Post by ivan »

Kadoba wrote:Your website is down for me.
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 ) )
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Short article on AI

Post by ivan »

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
I might write a full article on this later on.
Last edited by ivan on Sat Aug 13, 2011 5:48 am, edited 5 times in total.
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Short article on AI

Post by T-Bone »

I find the name "ai.love" very nice :neko:
Post Reply

Who is online

Users browsing this forum: Majestic-12 [Bot] and 61 guests