Context: I'm making a little "program your robot army" sort of game in Java in which the player writes Lua scripts (which are then run by LuaJ) to program their robots to do stuff. So far there are two objectives:
- Keep It Simple, Stupid, and
- React to the environment.
To take a simple example of what I currently have, the player should be able to tell their robot to go to a particular location with something like
Like Colobot, the scripting engine effectively halts (blocks) at that instruction until the robot has reached its destination.
I like this -- it's meets the first requirement nicely, in that you can't do anything until
goTo decides to return. It's also simple on the Java side -- I can basically do
while (/* condition */) yield() and just resume the coroutine every tick (then maintaining state in local variables is trivial). But: what if that resource at (5,8) disappears, or an enemy comes near, or energy runs low? There's no opportunity to bail -- the robot has to reach (5,8) before it can do anything else.
The main other idea I can think of is to produce some sort of loop:
while not robot:near(5,8) do if robot:enemyNearby() then break -- and do some other stuff, presumably else robot:moveTo(5,8) end end
moveTo this time sets the velocity/acceleration and then immediately returns, without blocking until arrival.
I could have
robot:goTo return the actual coroutine (either wrapped, so you just call it, or directly, which requires calling
coroutine.resume and passing the coroutine), which might look something like this:
moveTask = robot:moveTo(5,8) while not robot:near(5,8) do if robot:enemyNearby() then break else moveTask() -- or perhaps coroutine.resume(moveTask) -- or some other syntactic sugar end end
These last two approaches look pretty similar, but reusing a coroutine as in the second example makes managing state (e.g. a path) trivial, at the cost of exposing coroutines to the player.
To reiterate, the goal is to allow for writing simple scripts, in which a set of actions are executed in series (sorta like queued actions in The Sims), while simultaneously allowing more complex scripts with actions that may be interrupted by arbitrary events (nearby enemy, target moved, stats dropping).
Any tips or ideas would be much appreciated!