At the end of last week's entry, I'd laid out my basic idea for handling AI in a way that would support lots of different AI paradigms. In theory, it was very appealing - but the more examples I tried out, the more questions that popped up around how the AI "program" controls how its tasks are run. A complex bit of AI can have some main background logic, several event handlers, any of which can fire off a set of sub-tasks, which might in turn run event handlers and background tasks. Not only is working out how to prioritise/mediate between all these tasks complicated in itself, but providing a simple, intuitive and deterministic interface for the program author makes it that much harder again.
This was definitely a problem that wasn't going to solve itself in a day - so I set out to write a few basic Tasks to play with while I thought about it.
The first two blocks I've created are Moove and PhysicsSensor. The Moove Task allows you to directly drive an Agent around the game world, by propelling him forward and/or turning him. And the PhysicsSensor allows you to react to bumping into things.
Even with just two blocks, I've been able to build lots of different rule-based motion reminiscent of the mighty Head Over Heels. I've got enemies that turn left or right whenever they hit something, enemies which patrol back and forward, enemies which spin for a bit and head off in a new direction ... and I guess that's about as far as I've got. But it's still encouraging to see how easy it is to re-use even just two very simple blocks in lots of different ways and then pushing blocks in front of them to see them react.
Here's a simple "walk forward until you hit something, and then spin for 0.7 of a second" program:
And here are the little Elephants running about using those instructions:
The hardest bit to get right was the super-dooper accurate angle motion (turn exactly 90 degrees then walk forward) because even a slight error sends you into the wall and ruins the predictability (and hence the game play). In the end, I realised I'd never get it 100% accurate due to the numerical error in the arctan calculation used to determine the current direction - but I got it accurate to within 1/256th of a degree and then made the collision detection code ever-so-slightly-forgiving.
Anyway, with my little toy in place, I got back to thinking about the bigger problems of Task management. And I'm glad to say, I'm now the proud owner of an 8 page design document that lays it all out! It's a lot of relatively dry work (months of work I suspect), so don't expect to see the finished problem for quite a while, but I'm optimistic it will be pretty powerful once it's done.
Cheers!