-
Notifications
You must be signed in to change notification settings - Fork 9
BlockingScripts
You will see some commands listed as "blocking", where control does not return to the script until the command finishes. But what does this mean, exactly?
In order to better understand this, we need to explore a little about the way that the AGS script engine works. In an AGS game, there are three script threads that can be running at once. Think of a thread as a mini-CPU that executes your scripts.
At the start of the game, the threads are all idle (not running any scripts):
Now, as and when your scripts need to be run, AGS will try to run them on the appropriate thread (the Room thread for local scripts, and the Global thread for global scripts).
So, on the first game loop, your global scripts' repeatedly_execute will be run:
That's fine, and when it finishes running the thread becomes idle again.
But, suppose that within repeatedly_execute, you make a call to the Character.Say command. Say is a blocking command and does not return until the character finishes talking:
The global thread is now blocked, waiting for the character to finish talking. This means that none of your global script functions such as repeatedly_execute, on_event and on_key_press will be run while the character is talking, since the thread is busy.
Now, AGS does queue up to 5 script functions to be run on the thread as soon as it is free; but if you have a lot of things happening within your script, it's possible that you will lose some events such as on_events and keypresses if you script is blocked for a long time.
Let's explore the most common situation in which this causes confusion. Suppose you have a Player looks at inventory event on a Key inventory item, which runs a script to display a message.
Let's also suppose that you have some code at the end of your on_mouse_click function to make the character stand still after running mouse click events.
What you'll find is that the code at the end of on_mouse_click actually gets called before the inventory item's event. Let's look at why:
Remember that AGS does not run events automatically; rather, the on_mouse_click script function handles the mouse click and calls ProcessClick to run the appropriate event. When it does so, it finds that the key's Look At Item event has a script function associated with it.
But oh no! Inventory item scripts are in the global script, and the global thread is already blocked because of the mouse click. Therefore, the inventory event script gets added to the thread's queue, and on_mouse_click then finishes running. The inventory event script will follow on afterwards.
Now you might think that this means that object and hotspot events can run within on_mouse_click, since they use the room thread, like this:
However, this is not the case. It is still the global thread that is calling ProcessClick, so the room script will actually be run on the global thread once it is free.
Finally, we come onto the No-Block thread. This thread is only used to run the repeatedly_execute_always and late_repeatedly_execute_always functions. Because these two are not allowed to run any blocking functions, this ensures that the thread never gets blocked and so it will always run, even when the other threads are busy:
I hope that helps explain blocking in terms of AGS scripting. If there's anything that you don't think is clear, please suggest amendments on the Technical forum.
Getting Started in AGS
Editor
- New Game templates
- Editor Preferences
- General Settings
- Default Setup
- Colours Editor
- Room Editor
- Character Editor
- Cursor Editor
- Dialog Editor
- Font Preview
- GUI Editor
- Inventory Items Editor
- View Editor
- Sprite Manager
- Music and sound
- Voice speech
- Script Modules
- System limits
- Log Panel
- Plugins
- Other Features
Engine
Scripting
- Scripting Tutorial
- Scripting Language
-
Scripting API
- Script API Overview
- Standard Constants
- Standard Enumerated Types
- Standard Types
- Game variables
- Global arrays
- Global event handlers
- repeatedly_execute / repeatedly_execute_always
- Custom dialog options rendering
- Global functions: general
- Global functions: message display
- Global functions: multimedia actions
- Global functions: palette operations
- Global functions: room actions
- Global functions: screen effects
- Global functions: wait
- AudioChannel functions and properties
- AudioClip functions and properties
- Camera functions and properties
- Character functions and properties
- DateTime functions and properties
- Dialog functions and properties
- DialogOptionsRenderingInfo functions and properties
- Dictionary functions and properties
- DrawingSurface functions and properties
- DynamicSprite functions and properties
- File functions and properties
- Game functions and properties
- GUI functions and properties
- GUI control functions and properties
- GUI Button functions and properties
- GUI InvWindow functions and properties
- GUI Label functions and properties
- GUI List Box functions and properties
- GUI Slider properties
- GUI Text Box functions and properties
- Hotspot functions and properties
- Inventory item functions and properties
- Maths functions and properties
- Mouse functions and properties
- Object functions and properties
- Overlay functions and properties
- Parser functions
- Region functions and properties
- Room functions and properties
- Screen functions and properties
- Set functions and properties
- Speech functions and properties
- String functions
- System functions and properties
- TextWindowGUI functions and properties
- ViewFrame functions and properties
- Viewport functions and properties
- Obsolete Script API
- Event Types
- Key code table
- Audio in script
Legal Notice
Getting in touch
Misc