Well, just how Spacechem, Infinifactory and other Zachtronics games are a fun way to learn about basic programming technics and test one's logic at competition-grade tasks, one can try learning about industrial control tools via puzzles as well.
The whole idea is to make Godot simulate industrial devices and expose them as network ports so you can use any modbus-capable industrial control suite out there, including PLCs and even your own python scripts to try and make the puzzle work.
It doesn't even matter if tools are opensource or not, they just need to be able to send packets. ^^
So if you are really into industrial control and want to see how hard are different tools to get into /use you can try different tools for your favourite puzzle and decide what tool makes your day easier! Kind of a convenience benchmark really.
No actual levels are there yet though, it is just a technical demo, but it is not hard to make both devices and levels of your own if you know Godot. This is all very simple really.
## Ok, how this works?:
To be able to connect via modbus, libmodbus is used as the lowest level.
For Godot engine, ability to use libmodbus is added by writing a shared object compiled against GDNative API - this allows Godot to call C functions from its usual GDscript internal scripting interface without the need to recompile the whole engine (unlike C/C++ modules that need to be compiled into engine itself).
Inside a shared object it is barebones modbus functionality like register and coil IO and starting a server which listens on a socket.
In Godot, this functionallity is then called from the base GDscript class `ModbusServer`, which for cleaner configuration is then used by `ModbusSpatial` which inherits a `Spatial` node (i.e. is placeable on the scene) and exposes bind IP and port settings so they are editable from the editor when you place it.
`ModbusSpatial` is then inherited by all controllable devices which use this inheritance to send or receive data via modbus protocol. Connection parameters of every one of them can be set by just clicking on sensor/actuator and editing bind IP and port fields.
Aside from using ModbusSpatial to send and receive some data, controllable devices are perfectly normal godot game objects, and also demo includes a conveyor and box spawner that are not modbus-controllable.
## Modbus demostrating devices
***Sensor** is a distance sensor that outputs distance in units x 100 (game scene is grid-based in this demo)
* It writes the resulting distance integer to the holding register of offset 0.
***Pusher** is a simple modbus coil driven device. It tries to extends when coil (at offset 0) is 1 and tries to contract when coil is 0.
## Setting stuff up!
### 1. Install godot and libmodbus on your host machine.
**Alternatively** you can do the same by opening scene file in vim or your other (blasphemy!) favourite editor.
For example, the pusher looks like this, so you can just edit 2 last lines, adding lines if sth is missing (godot does not save settings that are set to their default values, for example default ip is 127.0.0.1)
_(TODO: address should really be called sth like bind-ip but i am not sure this is intuitive)_
However, even if you're going text route, last time i checked there was no CLI option for Godot to reimport assets (at least a direct one, which is a shame) so you might have trouble if trying running without doing `godot -e Main.tscn` (it does reimporting by itself).
### 5. Run
Run with f5 with editor open or from terminal `godot Main.tscn`
_Note: cd into the 'simple' folder if necessary - something inside Godot depends on terminal calling these commands from the folder and giving subtle errors in other cases, so you can't always do simple/Main.tscn from godot-modbus-demo_
Devices don't do anything by themselves, but `lsof -i` should report related ports as listening.
You can then use any tool to connect and try do sth interesting.