🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

script blocks c++ execution

Started by
3 comments, last by thedustbustr 20 years, 11 months ago
Sample python scripted cutscene: def cutscene(): camera.orbit(0,0,0) #orbit around the origin sleep(1) actor1.say("The evil prince will kill us all!") sleep(1.5) If I execute this script, won''t the sleep()''s prevent the engine from updating (so there would be a 2.5 second gap where no frames get rendered)? How do you avoid this? 1) I could run Python in a (c++) thread, but that is a royal pain in the ass and then I''d have to make all of my objects thread-safe. Not to mention I have no experience with threading in C++. 2) I could transfer execution of the engine to the python script, so the script is responsible for calling kernel.update(), but then it is up to the scripter to remember to do this and forces me to make the entire game engine available to python (I don''t want to do this). Also with a hierarchy of kernel.update() calling a python script calling kernel.update() could easily cause recursion problems and get out of control. 3) I could use Python threads to spawn cutscene() in it''s own thread and then return to C++, but again, I have to make all of my objects thread-safe. I like option three the best, but isn''t there an easier, or more important, Better, way? Thanks, Dustin
Advertisement
What I do in my engine is call the function "cutscene", with this code:
# the first bitdef cutscene():camera.orbit(0,0,0) #orbit around the origin'# tells the engine to call the next function after 1 secondg_Kernel.UpdateAfterWait( 1000, "myScript", "cutscene2" )'# the second bitdef cutscene2():actor1.say("The evil prince will kill us all!")'# tells the engine to call another function after 1.5 secondsg_Kernel.UpdateAfterWait( 1500, "myScript", "someOtherFunctionHere")


Though it tends to get a little messy, it's completely flexible and it allows the engine to 'simulate' a sleep() while continuing to update. UpdateAfterWait() means to continue execuation, but put the passed function in the specified script in a waiting area, to be called after the specified time has passed. This is also how I manage my update cycles (so if something doesn't HAVE to be updated every frame, it isn't). Otherwise, I think using the Python micro-threads would be a good idea, as those are easy to use though you'd still have to find a way of calling a sleep()...

Chris Pergrossi
< ctoan >
My Realm

[edited by - c t o a n on July 22, 2003 12:43:33 AM]
Chris PergrossiMy Realm | "Good Morning, Dave"
Python micro threads? what? you mean ''import threading''?

Also, you are calling g_kernel.updateAfterWait() from within Python, no? So you have passed execution of the kernel over to the script?
Ideally the kernel will have its own threading system. This system would allocate time for the scripts to execute, and then pause the script when its time to run another thread for a while. I recently worked on a mac port of a game that used this kind of system and basically they made their sleep() function in the scripts return execution to the thread handler, and then once the time in the call to sleep was over, execution would return to the script. They also made it pause in other places, like inbetween scripts. The scripts were broken down into very small functions and such, so that when one was called it would be done quickly. Also, other scripts that ran for the entire game (like the victory condition script) were very short and so didn''t take much cpu time each frame.
-out
Python micro-threads are like self-contained Python bits of code that have a sort of ''yield'' function that causes the execution to break, and when you call the function again, it resumes from the instruction after the ''yield''. This is an automatic system (as far as I know) and you only need to look it up in the Python docs for more details. The UpdateAfterWait( time, script, func ) is a function from my main Kernel that adds ''func'' to a list (using ''script'' as a pointer to access the function, cause you need to know what module the function is in) and sets ''func'' to be called after ''time'' milliseconds. It then immediately returns execution to the script, which then falls out and returns to the code. Then, after the elapsed time has passed (and the engine has been updating by itself in the native code [e.g. C++]) the Kernel checks it''s function update list and realizes it should call that second function, which it then does. My actual Kernel is alot more complicated and is based somewhat on that Enginuity Part 3 Kernel, though it uses scripts to define tasks. This allows me to ''deactivate'' the task for a certain amount of time and then run it at a certain delta time later, though with things like priority, or dependent functions (like drawing code that depends on BeginScene() being called already) are handled quite easily with a couple extra parameters.

Chris Pergrossi
< ctoan >
My Realm
Chris PergrossiMy Realm | "Good Morning, Dave"

This topic is closed to new replies.

Advertisement