Adding New Behaviors

Originally posted on the spring forums

Behaviours are assigned to units, and implement basic logic. For example, the Taskqueuebehaviour.lua file contains a behaviour that implements taskqueues, and the attackerbehaviour.lua file contains a behaviour called AttackerBehaviour that implements attacking, etc. Everything is named to be as obvious as possible.

To assign a behaviour to a unit, you use the behaviours.lua file. Here is the CA version of this file:

require "taskqueues"
require "taskqueuebehaviour"
require "attackerbehaviour"

behaviours = {
	armcom = {
		TaskQueueBehaviour,
	},
}

function defaultBehaviours(unit)
	b = {}
	u = unit:Internal()
	if u:CanBuild() then
		table.insert(b,TaskQueueBehaviour)
	else
		if IsAttacker(unit) then
			table.insert(b,AttackerBehaviour)
		end
	end
	return b
end

Breaking it down, we first include the files containing the behaviours, so that lua knows about them:

require "taskqueues"
require "taskqueuebehaviour"
require "attackerbehaviour"

so taskqueues.lua and taskqueuebehaviour.lua etc get loaded

Then, we define the behaviours table. Shard uses this table to look up what behaviours to assign to what unit. Inside the table is a list of units, and each unit has a list of behaviours

behaviours = {
	armcom = {
		TaskQueueBehaviour,
	},
}

So here, the arm commander ( internal engine name being armcom ), is given the taskqueuebehaviour.

If we had a behaviour called the RandomBannanaBehaviour, we could assign it to the armcom unit type, like this:

behaviours = {
	armcom = {
		TaskQueueBehaviour,
		RandomBannanaBehaviour,
	},
}

and we could assign it to corcom, like this:

behaviours = {
	armcom = {
		TaskQueueBehaviour,
		RandomBannanaBehaviour,
	},
	corcom = {
		RandomBannanaBehaviour,
	},
}

If Shard cannot find an entry in the table, it will call the defaultBehaviours function to decide what behaviours ( if any) to give the unit. Here is the default implementation.

function defaultBehaviours(unit)
	b = {}
	u = unit:Internal()
	if u:CanBuild() then
		table.insert(b,TaskQueueBehaviour)
	else
		if IsAttacker(unit) then
			table.insert(b,AttackerBehaviour)
		end
	end
	return b
end

You may wish to rewrite or override this for your game.

Creating the new behaviour

Create a new file named HelloworldBehaviour.lua, and inside it, put this:

HelloworldBehaviour = class(Behaviour)

function HelloworldBehaviour:Init()
	game:SendToConsole("Hello World!")
end

The first line says that there is a behaviour called HelloworldBehaviour. This means you also get a default implementation, so that you only write the bits you want to. We want to implement the Init method, so we can say hello world. You can see the other callouts that you can use in behaviour.lua or by seeing whats inside other behaviours.

And there we have a brand new behaviour! ^_^ To assign this behaviour to a unit, we need to make 2 modifications. So, to assign the helloworld behaviour to a peewee, we would change our tasklist as follows:

require "taskqueues"
require "taskqueuebehaviour"
require "attackerbehaviour"
require "HelloworldBehaviour"

behaviours = {
	armcom = {
		TaskQueueBehaviour,
	},
	armpw = {
		HelloworldBehaviour,
	},
}

function defaultBehaviours(unit)
	b = {}
	u = unit:Internal()
	if u:CanBuild() then
		table.insert(b,TaskQueueBehaviour)
	else
		if IsAttacker(unit) then
			table.insert(b,AttackerBehaviour)
		end
	end
	return b
end

Here all we’ve done is add the line:

require "HelloworldBehaviour"

This is so that lua knows what we mean when we say HelloworldBehaviour, and then we assigned the behaviour to armpw, the internal name of the peewee.

	armpw = {
		HelloworldBehaviour,
	},

Now, whenever a peewee is built, Shard will output the words “Hello World!” to the console!