It’s Sunday. My long-suffering wife is prepping for the upcoming election. On my own, I decided to spike motion for my game creature.

Assume a long rant here about how hard my wife, Deputy Clerk of our township, works in preparation for elections. We have a presidential primary next Tuesday. All the machines have to be set up and checked, ballots prepared, etc etc. I don’t know half of what the poor woman does, but she’s been working 7 days a week for a couple of weeks now.

Among the tragic outcomes of this is that we didn’t get our traditional breakfast with Sunday Morning today. The good news is that I hit the grocery store and the cat won’t starve.

So I came to BAR1 and after wasting some time decided I’d do a motion spike on the “Game”. Last time, I stopped with a Creature, represented by a block Orc, standing on a small plane or plain, depending how you want to think of it. Today, I’d make it move.

I briefly reviewed the Braitenberg vehicles code and then did something much simpler. It may still be necessary to set up the partial function idea I used there, but for now it wasn’t needed.

You must not be a very good pair to work with, because instead of writing this article contemporaneously, I just went ahead and coded motion, and it went pretty well. Oh, I got a lot of messages trying to execute `nil` and the like, but all the problems were trivial. And I made the Orc move diagonally from the center toward one corner, then reverse and go toward the other corner, repeat until done. It looks like this:

The code changes were all in the Creature object:

``````Creature = class()

local CreatureMaxTime = 300

function Creature:init(entity, x, z, behaviors)
self.entity = entity
self.behaviors = behaviors or {self.walk}
entity.x = x
entity.z = z
entity.y = 2 -- just above the ground
entity.model = craft.model("Blocky Characters:Orc")
entity.scale = vec3(1,1,1)/8
end

function Creature:update(dt)
dt = dt or DeltaTime
for _,b in pairs(self.behaviors) do
b(self)
end
end

function Creature:walk()
local speed = 60
self.time = self.time or CreatureMaxTime
self.mul = self.mul or 1
self.time = self.time - 1
if ( self.time <= 0 ) then
self.mul = -self.mul
self.time = 2*CreatureMaxTime
end
self.entity.x = self.entity.x + self.mul*1/speed
self.entity.z = self.entity.z + self.mul*1/speed
end
``````

I added a `behaviors` collection, initialized by default with `self.walk` which is the function Creature.walk. That function, as you can see, just counts down from `self.time` to zero, and when it gets to zero, it changes the sign of `mul`, which results in the Orc going the other direction. It also sets the time to `2*CreatureMaxTime`, so that after starting in the center and going one way, it goes all the way back and forth after that.

The `update` function sets dt (oops that should be local, and it’s a YAGNI violation since it’s not used), then loops through the `behaviors` list calling each one, passing `self` to it because it’s a method.

That’s all it took to make the little guy move. No changes on other tabs.

This is a really decent spike: it provides a simple behavior that can be elaborated as we go forward. I expect that we’ll have special functions to build behavior lists, as we have in the Braitenberg example, but we’ll deal with that when the time comes.

Not bad for a quick morning’s fun. Now to take the cat food home.

See you next time!

1. Brighton Agile Roundtable, the round table we sit at at the Brighton MI Barnes & Noble.