Integrating Falcon with Coroutines

51 views
Skip to first unread message

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 2:45:40 PM2/4/13
to falc...@googlegroups.com
Hi

I didn't reach the point when I can finally integrate the new Falcon engine in my game yet (my current game code is far more complex than before) but I'm considering some architectural choices I will have to make.

Basically, I will use Falcon in several different contexts which imply different vm instances with different code manipulating them.

In several of theses use cases, I would like to limit the "time" spent on the script.
Actually, a perfect way to do it would be limit the number of instructions executed (or something equivalent) instead of "time".
I don't understand all details of the new Falcon engine but it seems that it would be possible to execute only a number of instructions per virtual "ticks".

If I'm correct, then, it would be easy to use a coroutine implementation (like boost.coroutines http://www.boost.org/doc/libs/1_53_0/libs/coroutine/doc/html/coroutine/overview.html that I've followed evolution for a long time) to pause and resume the instruction execution as I wish.

I would use them to do something like this (pseudocode, not actual code):


void script_execution_corountine( ... )
{
     while( !falcon_executor.empty() )
     {
         for ( int i = 0; i < MAX_INSTRUCTIONS; i++ )
         {
             falcon_executor.
         }
         coroutine(); // give control back / point of resuming
     }

}


Now my question is: do you see a potential problem coming from this approach?

Thanks for your time.

Klaim / Joel Lamotte



Giancarlo Niccolai

unread,
Feb 4, 2013, 4:31:32 PM2/4/13
to falc...@googlegroups.com
The new engine is totally asynchronous. There isn't any need to use this
kind of tricks, as you can just decide, after a second, that the script
took too long and terminate it from another thread.

Of course, not having to constantly worry about and check for ticks
makes room for better performance and less errors.

Also, the Parallel() interface for the scripts, launching parallel
execution of code, is totally abstract. It might use as many real
processors as you have available, or you may decide to limit the number
of physical processors available for parallel execution to 1, making the
scripts effectively going into a coroutine mode.

Also, the new virtual machine has the ability to launch multiple
parallel processes, that you can control separately, each of which can
have different settings on this regards.

Gian.


Klaim - Joël Lamotte

unread,
Feb 4, 2013, 4:59:00 PM2/4/13
to falc...@googlegroups.com
I might not have been clear but I'm not talking about the cases you're describing.

The case I would need such "trick" is actually to sync the game state cycle, which is independent from time
with the amount of script executed. (note that even if it were dependent on time, it wouldn't be dependent on "real" time)
So the best way to do this is not to rely on time at all.
Also this specific case is with synchronous use.

I have other cases that would benefit from parallelism, but not this one case.
Most cases are independent from other systems. this one need to be updated synchronously with another.

Is it still possible to just trigger instructions processing manually? It would be largely sufficient.

Klaim / Joel Lamotte

Giancarlo Niccolai

unread,
Feb 4, 2013, 5:05:54 PM2/4/13
to falc...@googlegroups.com
I really don't get your usage pattern, but in general you can end the process from within whenever you like.

ATM the isn't any counter of executed instructions, but adding it on a per-process basis is 1-2-3 (there is a single loop where "instructions" are processed, and you know what context they come from, and with that, what process is holding that context).

I wouldn't do in the "real" falcon though, as it's a cause of serious inefficiency, but if you don't mind adding some 5 lines to the official release, it might do for you.

Also notice that execution time of instructions varies greatly. The instruction to perform a "pop" from the data stack takes a fraction of the instruction to perform a read from disk... not that your script has to read the disk, but you get the picture.

Gian.

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 5:19:53 PM2/4/13
to falc...@googlegroups.com
On Mon, Feb 4, 2013 at 11:05 PM, Giancarlo Niccolai <g...@niccolai.cc> wrote:

I really don't get your usage pattern, but in general you can end the process from within whenever you like.

I would prefer to do it from outside and control how much work is done.
 

ATM the isn't any counter of executed instructions, but adding it on a per-process basis is 1-2-3 (there is a single loop where "instructions" are processed, and you know what context they come from, and with that, what process is holding that context).

I wouldn't do in the "real" falcon though, as it's a cause of serious inefficiency, but if you don't mind adding some 5 lines to the official release, it might do for you.


I don't understand why you suggest to add a counter?
My guess is that you already do the instruction processing function so exposing it would work.

Anyway nevermind, I'll check the code and provide a PR if it works as I intended.

 
Also notice that execution time of instructions varies greatly. The instruction to perform a "pop" from the data stack takes a fraction of the instruction to perform a read from disk... not that your script has to read the disk, but you get the picture.

Ok, then instruction might not be the right metric either to mesure work allowed to be done each cycle (I mean "game" cycle - it's not exactly game in this case but you can imagine it like that).

Let me get back in more details when I start integrating Falcon, I think it would clarify if I'm thinking it properly.

Joel Lamotte

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 5:30:44 PM2/4/13
to falc...@googlegroups.com
I just got a thought on something that could help explain the context.

Do you know EVE Online? Recently they got this gigantic battle. 
The programmers of EVE are very smart as they made sure when a server (a solar system) have a lot of people in, 
the time slow down for this system.

Classic architecture of (big) games allow this kind of thing (but not always used) because in games you can't rely
on real time to measure progress of the game state. You can rely on it for example to get fluid animations,
but game-state time is different. Most of the time it's cut in a very specific way called "lock-steps". 
Which mean, you can map each cycle of the game update to real time, slower than RT, or faster, or if you recorded each cycle, 
do the replay of a game session.
My game is mostly built like this, however I have several independent game state running separately.
Each game state have ("will have" actually) a script VM which is executed in sync with the game state update (that might happen at an arbitrary time depending on what you're 
doing, replay, normal game, paused, editor mode etc.)
Note that in my specific case (which is not common), bot AI isn't run by this VM, it's a separate subject (which might imply a script too or not).
So I'm not talking about AI in this specific case. It's mostly about scenarisation of the game session.

Now, I have two strategies:
 1. just run the scripts associated with the game state update cycle : 1 cycle <=> 1 full script execution
 2. run a specific amount of script for a game state update cycle: 1 cycle <=> N script "instructions" executed (looping)

The first one is the simplest and is straightforward I guess.
What I'm asking is if the second one is possible.

But as I said, I'll take a look at the code and see what is possible to do from there.

Joel Lamotte

Giancarlo Niccolai

unread,
Feb 4, 2013, 7:24:08 PM2/4/13
to falc...@googlegroups.com
I think this is better handled with events and inter-agent communication
devices as messages.
When your script is done, it sends a message. When all the scripts, and
other agents in the process that can be C++ or C, have sent their
message, the game ticks one cycle.

Especially when you have multiple CPUs (a standrad on cell phones
nowadays), this is usually way simpler and more efficient.

Gian.



Klaim - Joël Lamotte

unread,
Feb 4, 2013, 8:38:10 PM2/4/13
to falc...@googlegroups.com
On Tue, Feb 5, 2013 at 1:24 AM, Giancarlo Niccolai <g...@niccolai.cc> wrote:
I think this is better handled with events and inter-agent communication
devices as messages.
When your script is done, it sends a message. When all the scripts, and
other agents in the process that can be C++ or C, have sent their
message, the game ticks one cycle.

If I understand correctly, it;s the equivalent of 1) which basically is 
the classic solution - but makes the script a potential bottleneck in the cycle update
(in my case). Might be or not a problem, which is why I was asking 
if there was a way to make the scritps execution "limited" in some ways.


Especially when you have multiple CPUs (a standrad on cell phones
nowadays), this is usually way simpler and more efficient.

As I was saying, in the context of this particular script execution, it's synchronous (with the reste of the update cycle)
and I can't change that, it's the nature of a lock-steps. It have to be
this way for the game state to keep consistent and independent from real time 
(it's also necessary if you do physics- thank god I'm not in this case... )
If you prefer, this script execution is synchronous with the whole game update cycle
but it is execeuted in a task run by a task scheduling mechanism (TBB) which makes the whole system
already exploit the multiple cpus; but the script executions have to be kept synchronous with the rest
of the cycle steps  which have to be executed in fixed order.

Once a cycle is complete, the rest of the systems can take the output and happily generate interpretation 
in parallel as much as they want (graphics, audio).

I I'll have to explain more later to make it clearer (with code I guess).

Forget about it for now, I'll need some sleep and work with the new engine before discussing this more I think.

Joel Lamotte


Paul Davey

unread,
Feb 4, 2013, 8:54:47 PM2/4/13
to falc...@googlegroups.com
Hi Klaim,

I think you will run into other problems if you limit the script execution in other ways, since then it will become non-deterministic how much of the script gets executed before getting cut off, this will cause inconsitencies that would be the same as if the simulation were not synced at all.

Paul


--
You received this message because you are subscribed to the Google Groups "FalconPL" group.
To unsubscribe from this group and stop receiving emails from it, send an email to falconpl+u...@googlegroups.com.
To post to this group, send email to falc...@googlegroups.com.
Visit this group at http://groups.google.com/group/falconpl?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 8:57:52 PM2/4/13
to falc...@googlegroups.com

On Tue, Feb 5, 2013 at 2:54 AM, Paul Davey <plm...@gmail.com> wrote:
I think you will run into other problems if you limit the script execution in other ways, since then it will become non-deterministic how much of the script gets executed before getting cut off, this will cause inconsitencies that would be the same as if the simulation were not synced at all.

I think you are correct.
Only way to keep the cycle update correct seem to be executing the whole script.

I definitely need sleep. 

Joel 

Paul Davey

unread,
Feb 4, 2013, 9:05:01 PM2/4/13
to falc...@googlegroups.com
Well you definitely need some unit of the script like a function or such that you can guarantee has finished before you continue to the next cycle.
Since there are issues like if statements may have different length branches so if things have changed and a different branch is taken it may get stopped before the end rather than completing, this will also make debugging your scripts horrible.

Paul
Reply all
Reply to author
Forward
0 new messages