lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Friday 10 February 2006 17:00, Guy Davidson wrote:
[...]
> Next, we want to use Lua as a scripting language.  Now, we are clearly
> suffering a bit of a semantic cock-up here, as everyone on the team seems
> to have a different idea of what a scripting language is.  For example,
> some see a scripting language as a setup system for UI layout management,
> others for speedy macros, while there are those who tell me a scripting
> language is for narrating the movement of armies about the battlefield. 
> Frankly, I'm not so bothered about this, but I need to accommodate all
> these uses.

I haven't used Lua for AI scripting in specific, but I have used it for 
descriptive systems (I'm currently working on a build tool written in Lua 
that does this), and Lua's really good at it. The key useful feature is that 
you can miss out the parentheses on a function call that takes as a parameter 
either a constant string or a table. This means that you can use constructs 
like:

dialogue {
	label { text = "First widget" },
	checkbox {
		text = "Click here to do something!"
	},
	button {
		text = "Cancel",
		onClick = function (self)
			cancelCurrentDialogue()
		}
	}
}

That's an expression consisting of a number of function calls each of which 
takes exactly one table. Each table contains named items (attributes for the 
current item) and numbered items (children of the current item). Very handy.

[...]
> Given my earlier observation about
> execution being lined up in big chunks, I'm concerned this isn't going to
> be possible without fundamentally altering the way that Lua executes its
> commands.

Lua *compiles* code as chunks --- but you probably don't want to execute your 
scripts at the same time as you compile them (unless you want to use up 
valuable AI time parsing text!). A chunk is just a basic block and doesn't 
really have any representation in the bytecode.

Something like this is perfectly possible:

---snip---
require "ai"

local state = "aggressive"

function attacked()
	state = "cowardly"
end

function tick()
	if (state == "aggressive") then
		ai.faceTowards(ai.playerLocation())
		ai.fire()
		return 2 -- sleep for 2 seconds
	else
		ai.faceAwayFrom(ai.playerLocation())
		ai.forwards(100)
		return 0.5 -- sleep for 0.5 seconds
	end
end
---snip---

You *execute* the script when your creature is initialised, probably at level 
startup. This runs the code above, which does nothing apart from populating 
the VM with some functions. Then at run time, your AI infrastructure calls 
tick() every time it wants your creature do its thing, and calls attacked() 
whenever your player shoots at the creature. 

(You can even do the script compilation off-line if you want, so all you do at 
run time is load precompiled Lua byte-code.)

It'll make a big difference in your design whether you want to have one Lua VM 
per creature, or per group of creatures, or per level, or per world. Lua does 
have enough built-in control structures to allow you to build a 
multi-threaded non-preemptive scheduler in pure Lua --- look up coroutines in 
the documentation --- but using multiple VMs can make the scripts easier to 
write and faster to run.

Can you tell us what your developers want to be *able* to do? Then we can tell 
you whether it's possible or not. That might be easier than trying to tell 
you what Lua's capable of, so you can tell your developers what approach they 
should use...

-- 
+- David Given --McQ-+ "If God spammed rasfw with the answer to Life, the
|  dg@cowlark.com    | Universe, and Everything, I'd report him to
| (dg@tao-group.com) | abuse@heaven.org." --- David Bilek
+- www.cowlark.com --+ 

Attachment: pgpCb3ktTAxwq.pgp
Description: PGP signature