module interruption
I'm using angelscript for each character's AI routine.
Once every 10-15 game frames, the script module activates, giving the character a chance to set a new target / new waypoint / new behavior / etc.
AI script will also be user defineable - a feature that I want, so my code should be able to handle their bad coding practices.
If a chuggy script is taking longer than say, 10 milliseconds, I should be able to automatically suspend it's operation, and 15 game frames later, let it resume from where it left off.
How can I do that?
View the examples in the SDK, there are Co-Routines, Concurrent Scripts and events that should give you an example of what you should do.
Thanks, I didn't study the "events" example long enough.
I suppose the events example works because AL engines run in their own thread?
I don't expect players to use Yield() and Sleep() properly, but I don't want to punish them by obliterating their script either.
I think I can use "coroutines" controlled by "events". The C timer resets every time a new coroutine is called. If the timer is reached, Yield() is forced. If the same script gets 20 yields in a row, Abort() is forced, and that character reverts to some default C behavior.
Now I need to find a way to cap the memory usage for each script.
I suppose the events example works because AL engines run in their own thread?
I don't expect players to use Yield() and Sleep() properly, but I don't want to punish them by obliterating their script either.
I think I can use "coroutines" controlled by "events". The C timer resets every time a new coroutine is called. If the timer is reached, Yield() is forced. If the same script gets 20 yields in a row, Abort() is forced, and that character reverts to some default C behavior.
Now I need to find a way to cap the memory usage for each script.
You don't want to have the scripts call Yield() or Sleep() for this, although it may be a useful feature.
What you need is to implement a timeout for your scripts, so that they are only allowed to execute a certain maximum amount of time. Take a look at how the LineCallback() from the Events sample is used. What it does is that it suspends the script once the time is up. The LineCallback() function is called once per script statement, which ought to be often enough for you.
The memory cap is a bit more difficult. The first thing you can do is to set a maximum size for the stack, using the SetDefaultContextStackSize() method. Then you probably need to find a way to block the number of objects allocated by the each script. This could be done by registering the asBEHAVE_ALLOC and asBEHAVE_FREE behaviours for each registered type. Currently there is no way of overriding the memory routines for built-in types, but that will be implemented for version 2.4.0.
Regards,
Andreas
What you need is to implement a timeout for your scripts, so that they are only allowed to execute a certain maximum amount of time. Take a look at how the LineCallback() from the Events sample is used. What it does is that it suspends the script once the time is up. The LineCallback() function is called once per script statement, which ought to be often enough for you.
The memory cap is a bit more difficult. The first thing you can do is to set a maximum size for the stack, using the SetDefaultContextStackSize() method. Then you probably need to find a way to block the number of objects allocated by the each script. This could be done by registering the asBEHAVE_ALLOC and asBEHAVE_FREE behaviours for each registered type. Currently there is no way of overriding the memory routines for built-in types, but that will be implemented for version 2.4.0.
Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
LineCallback is exactly what I had in mind. :)
Thanks for the THOROUGH example/tutorial programs and documentation.
Also, the EASIEST installation ever! This is why I went with AS, and nothing else. (Also, the C-syntax is easy on the eyes.)
Just one request:
Could you add a minimalist "hello world" example which demonstrates how to read from an external .as file?
SetDefaultContextStackSize() is exactly what I need. (I'd better go re-read the manual!)
After I get this AI framework going, I'll have to write an AI programmers guide to help users write clean, fast, non memory-leaky code.
Maybe with AS 2.4, I could show percentile status bars for each scripts' memory usage and processor time. But that's not as important as the guide.
[Edited by - fuzinavl on August 3, 2005 8:24:35 AM]
Thanks for the kind words. [grin]
You have a good point there, I'll need to add a sample that shows how to load scripts from disk as well. Thanks for the idea.
You only have to worry about memory leaks, if you allow manual allocation and deallocation of memory in the scripts. You may also want to read up on the GarbageCollect() method, which you'll probably have to call every once in a while (don't worry it's incremental so it shouldn't cause your game to stutter).
Regards,
Andreas
You have a good point there, I'll need to add a sample that shows how to load scripts from disk as well. Thanks for the idea.
You only have to worry about memory leaks, if you allow manual allocation and deallocation of memory in the scripts. You may also want to read up on the GarbageCollect() method, which you'll probably have to call every once in a while (don't worry it's incremental so it shouldn't cause your game to stutter).
Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Along these lines, I'm curious about something I've wanted to add to our simulation, but I don't know if I can with a scripting language.
Basically, I want to do something akin to interrupt handling. I'd like to detect an external event, halt execution, then call a function within the script when it occurs. When the function returns, continue execution.
Seeing this thread on the line callback, would almost work. I could use the callback, check if an event occurred, and if nothing, continue with execution. However, what do I do if I detect an event?
Given the following pseudo-code:
Elsewhere in myLineCallback:
Is it unsave to to call a script function from the line callback? I imagine it is, but I'm curious about how you would handle such an case. Any ideas on how this can be done?
Basically, I want to do something akin to interrupt handling. I'd like to detect an external event, halt execution, then call a function within the script when it occurs. When the function returns, continue execution.
Seeing this thread on the line callback, would almost work. I could use the callback, check if an event occurred, and if nothing, continue with execution. However, what do I do if I detect an event?
Given the following pseudo-code:
CreateEngine();LoadScript();SetLineCallback(myLineCallback);ExecuteScript():
Elsewhere in myLineCallback:
if ( ExternalEvent() ){ CallScriptFunction();}else{ ContinueExecution();}
Is it unsave to to call a script function from the line callback? I imagine it is, but I'm curious about how you would handle such an case. Any ideas on how this can be done?
I suggest you take a look at the Events sample in the AngelScript zip file you downloaded. It implements exactly what you're describing.
You ought to be able to call other script functions from the line callback, as the line callback is always executed when the context is in a "safe" location. It would have to be in another script context though.
With a safe location I mean that no unprotected pointers are floating around on the stack, so that when the execution is resumed once more everything is guaranteed to be working.
Regards,
Andreas
You ought to be able to call other script functions from the line callback, as the line callback is always executed when the context is in a "safe" location. It would have to be in another script context though.
With a safe location I mean that no unprotected pointers are floating around on the stack, so that when the execution is resumed once more everything is guaranteed to be working.
Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement