Sunday, November 7, 2021

Driving the GODOT game engine with OSC messages - part 2

Using a thread instead of a busy loop

As a quick follow-up to part I, where I basically used a while (1) { ... } loop which tends to make the CPU run at 100% (unless you use the OS.set_low_processor_usage_mode which is not portable across platforms, and which may actually cause the rest of your game/sketch to run badly, here's an alternative that parses the OSC messages whenever a timer expires.

In the rootnode script _ready function, a timer is instantiated that calls a function _on_timeout and reschedules itself after it timed out:

timer = Timer.new()
timer.autostart = true
timer.one_shot = false
timer.wait_time = 0.1
timer.connect("timeout", self, "_on_timeout")
add_child(timer)

Then also in the rootnode script, you can implement the _on_timeout function to perform the parsing of the osc information and distribution to the observers.

Instead of trying to explain everything in this post, it's probably much easier for you to clone my github example and play with it: https://github.com/shimpe/example_godot_gdscript_osc

The game listens for OSC messages like "/$index/set/color min max val" where $index is a number between 0 and 15, and min represents a value for which the sensor will color black, max represents a value for which the sensor will color maximally red  and val represents a value between min and max. Val will be used to adapt the sensor color between black and maximally red, based on where it is located between min and max. So if you send /5/set/color 0 100 50 to the sketch, then the color of sensor number 5 will be changed to be halfway between black and bright red.

For testing, I used a simple supercollider program to send OSC messages to the game and which lights up the sensors randomly like some Christmas tree, but you can use whatever program you have that supports sending OSC messages. 
(
b = NetAddr.new("127.0.0.1", 4242); // create the NetAddr
fork {
       1000.do {
               |idx|
               b.sendMsg("/"++15.rrand(0)++"/set/color",0,100,100.rrand(0));
               0.1.wait;
       }
};
)