I need to specify and execute lists of actions. “accelerate for 10 seconds, then decelerate for 5 seconds”, that kind of stuff. Kind of timed trigger, ticked off inside update() calls.
If would be easy to implement that thing, but before I reinvent the wheel, maybe something like that is already available? I have taken a (very short) look at AnimChannel and got the impression it’s already specialized to working with something that has bones and such; what I need is something that ticks off time as the tpf values flow in, and launches planned actions as they become current.
I’m seeing lots of boilerplate coming to me for coding the behaviour.
I’d like to write activity plans, such as:
walk towards next patrol point
player seen? -> start attack routine
waypoint reached? -> choose next waypoint
Coding this as a separate thread would work. What I don’t like about that approach is that every scene graph update would have to be put into a Runnable; that would be a constant stream of small temporary objects.
Anonymous inner classes are a whole lot of tiresome boilerplate.
I’d have to explicitly stop all activity-related threads whenever the game stops.
Coding this directly in the update loop would mean that I’d have to fragment the plan into states of a state machine, obfuscating the overall logic. (State machines aren’t always bad, but simple activity plans are best written as a sequence.)
Also, I’d have to collect tpf data in every agent.
Ah thanks, I hadn’t seen these.
I was assuming that they can’t react to change. E.g. one of the behaviours that I need to implement is adjusting the current speed vector so that it always points towards the player. I suspect that motion paths can’t do that kind of reactive stuff, but I’ll take a closer look anyway.
I have analysed the requirements a bit more, and the core of the problem seems to be that I want three things:
Code that runs in the render loop (for reactive stuff)
Code that runs in a separate thread (for planned stuff)
Both within the same class because the plans affect which reactions are active.
Now that means having data for different threads within the same class -> recipe for race conditions and ensuing disaster.
I’m wondering how other people structure this.
Split the class and bite the bullet that the logic is distributed across classes?
Have dual-thread classes but have a convention that, say, the non-render thread code is restricted to accessing just the thread-safe member variables?
Do everything in a separate thread and do all scenegraph updates via a Runnable?
This might be the question how to divide up the logic between render loop and agent threads.
Hehe, it’s amazing that we sometimes have the same questions in mind. Now I assumed you always raise interesting questions about principle. When you ask about time-based activities I recall exactly I want to ask this specific question 2 years ago.
First, you should make sure you have a clear view of this kind of activity.
is just happen without the need of other things react(like a keyframe in animation), try “notification-event scheduler”; fire appropriate event in a timeline and forget. The same concept was implemented in out Cinematic system. Now I’m trying to make an framework call F(x) which is more generic for schedule time base action, and interpolate value in functional style with the help of Guava Function.
is the kind of activity can cause reaction (like physics) or trigger chain of actions (the next patrol point) or not have a fixed routine. The “Pattern” you asking for it an “action scheduler”. fire appropriate action in a timeline, may queue additional actions to solve later, time-based or event based. It’s a more complex type of the above. And the most obvious way to handle a chains of actions is a queue.
More sotisphicated options to bring concurrency may treat each action is a actor within an Actor framework or a Task in a Task framework…etc.
I see you are trying to make the 2nd : So some concepts are :
— Option B additional concepts:
ActionChain : ordered action list
with Duration: can form as Task (action with duration) to be scheduled
Additional data: add to each action to add more features: position, values, mass…
with Interplator : from A -> B, curves, physics, AI pathfinding … etc
If you implement Action as Runable you blur the Executor concept and use the Java in thread executor directly. If you are confidence and familiar with multi-threading, this is a wise move. But it’s also limit your extensible and resuable because Runable is not as generic as an Action<Object> or something like a generic wraper of a class, a Closure in groovy or a Function in Guava.
About the Scheduler concept (which is also very important but if you dont really have an stand alone Executor, this two merged):
You can have one update beat “belong to the Scheduler” in one thread and remind its Task when its time, let it run in a thread, suppend the Task when timeover or duration end. I recommend you to take a look at GPars, don’t be mislead as it for Groovy only, it’s also for Java.
You can also have many update beat “belong to each action (or type of action) you start” in separate threads. This suite better for situation involve physic or AI.
In conclusion, my idea above is having seperated levels of implementation of such “Scheduler” or level of timing in real-time app like a game. For my framework, Fx and Advanced animation have a same timing system; Logic and GameEvents have more complex one; AI have a most sottiphicated one; … Scripting in Groovy and GPars also bring some power to expand when I need. Anyway, you should look at GPars’s Task, it will help!
Thanks @atomix, that’s an interesting list of options that I need to think about some more.
For now, I’m just trying to get something “clean and simple” (it’s still for the tutorial thing), writing as little framework code as possible because, hey, it’s a tutorial
The best path for that seems to be putting code into Threads and let these communicate, race conditions and enqueue() calls be damned. I guess I’ll stick with java.lang.concurrent stuff.
Darnit. I wouldn’t have thought that writing GOOD tutorials is so hard. Whenever I do something, I have to find a technique that’s easy, endorsed, and light on code bloat; now that I see that requirement spelled out, I see how this could become a challenge, but I certainly didn’t expect this.
But I’m learning a whole lot here, so it’s everything but a waste of time
For a ‘beginner’ tutorial, yes it’s hard to find a balance point where people all share the same common and root knowledge. And if you want to bring more advance techs, it’s defeat the tutorial point anyway. ‘Advance tutorial’ can be easiler to write thought. It should be good if you can come up with a clean and clear, and lightweight design for a timing system, it will help all of us.