Library / SDK
Open-Industry-Project/Open-Industry-Project-Godot avatar
Open-Industry-Project/Open-Industry-Project-Godot

Open Industry Project for Godot: a warehouse simulator that talks to real PLCs

Free and Open-source warehouse/manufacturing development framework and simulator

862 stars127 forksGDScriptMIT

At a glance

What is it?
Open Industry Project for Godot is a manufacturing development framework and simulator built on a custom Godot fork, with parts you drag into a scene that read and write tags over OPC UA, EtherNet/IP, Modbus TCP, Siemens Put/Get, Beckhoff ADS, Universal Robots RTDE and MQTT. The important caveat is at the top of its own README: the Godot version is no longer maintained.
Who is it for?
Adopt the Godot build of Open Industry Project only if you have a specific reason to need a desktop simulator in the Godot editor, since the project itself directs you to the browser and desktop successor at openindustryproject.org. Do not start new work against the Godot version.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
No. The owners have archived the repository on GitHub, so it is read-only and no longer receives changes.
What is it written in?
Mainly GDScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What this repository is, and the warning at the top of it

Open Industry Project for Godot is described as a free and open-source warehouse and manufacturing development framework and simulator. The stated goal is to provide an open framework to create software and simulations using industrial equipment and devices, and for people to be able to test their ideas or educate themselves while using standard industrial platforms.

The first thing in the README, marked as important, changes how you should read everything else. This is the Godot version of Open Industry Project, and it is no longer maintained. Its successor runs in the browser and as a desktop app, and the README points to openindustryproject.org to try it and to a separate Open-Industry-Project/Open-Industry-Project repository for the code.

That is a significant fact and it should come first in any evaluation. What follows describes a capable and still readable codebase that has been superseded.

The technical shape is a Godot project with a custom engine fork. The top level holds project.godot, a src/ directory for the GDScript sources, a parts/ directory holding the equipment you place in a scene, an addons/ directory, an assets/ directory, an oip-plc.js file that is presumably the compiled piece talking to the PLC side, and trim.py, which is presumably a helper for stripping the build down before distribution.

The licence is MIT and there is a Discord server. The releases are pre-release builds, v4.7-rc1 from 2026-07-14, v4.7-beta1 from April and v4.7-dev5 from April, with the last push on 2026-10-19.

So the project is a Godot-based simulator with a maintained upstream in a different form, and the Godot repository is the place to read the design if you want to understand how the successor works.

The protocol list and the libraries behind it

The supported communication protocols are the substance of the project, because a simulator that only simulates its own devices is a game rather than a tool.

OPC UA is supported via open62541. EtherNet/IP is supported via libplctag. Modbus TCP is supported via the same libplctag library, which is efficient because one library covers two protocols. Siemens S7 1200 and 1500 Put/Get protocol is supported directly. Beckhoff ADS comes through the Beckhoff ADS library for TwinCAT 2 and 3 runtimes. Universal Robots RTDE, the Real-Time Data Exchange version 2, is supported with a link to the official RTDE guide, and the protocol dropdown specifies port 30004 for UR cobots and URSim. MQTT is supported via the Eclipse Paho MQTT C library, and the README is precise about the limits: plaintext TCP, MQTT 3.1.1, no TLS, QoS 0 only.

That MQTT caveat is worth noting. A simulator that talks plaintext MQTT with no TLS and no quality of service is a laboratory convenience, not something you would point at a production broker. The project states the restriction rather than hiding it, which is the right way to do it.

The protocol dropdown in the editor offers seven options, and the identifiers are the ones you will see in configuration: ab_eip for Ethernet/IP, modbus_tcp, opc_ua, siemens put/get, ads, rtde and mqtt.

The choice of libraries is also informative. open62541 is a C implementation of the OPC UA stack, libplctag is a C library covering EtherNet/IP and Modbus, and Paho MQTT C is the reference MQTT client in C. All of them are native libraries, which means the custom Godot fork exists to link them into the engine rather than to implement the protocols in GDScript.

Installation, creating a simulation and placing parts

Installation is three steps and involves a custom engine build, which is the main reason the successor moved to the browser.

Download the latest package from the Releases page, which includes both the project files and the custom Godot fork. Extract the archive and open the included Godot editor. Then use the Project Manager to open or create a new project.

That second step is the significant one. You are not installing a plugin into your Godot; you are using a Godot build that ships with the project, because the native protocol libraries have to be linked into the engine.

Creating a simulation follows a path that is more like a visual editor than a game engine workflow. All objects used in a simulation scene are in the Parts tab. A simulation is created by adding a new scene and selecting New Simulation, which creates a scene with the top node labelled Simulation.

Parts are then dragged into the viewport to instantiate them, and once in the scene they can be modified.

The snapping gesture is specified precisely: to snap parts together, select the parts you want to move, then Ctrl+Click the target part to make it the active selection, and press Ctrl+Shift+C. The selected parts snap to the target.

The README's worked example makes the point about real equipment: most parts have properties that can be configured to communicate with a PLC or an OPC UA server, and in the example given, Ignition was used as an OPC server to write to the conveyor tag. That is a real integration, with a real industrial server driving a simulated conveyor.

Comms, tag groups and the polling model

Communication is configured through the Comms panel at the bottom of the editor, and the first requirement is easily missed. The simulator will not communicate with any device until the Enable Comms checkbox is checked.

Tag Groups are the logical way to organise sets of tags. Each Tag Group is associated with one PLC or one OPC UA client, and when connecting to multiple PLCs or OPC UA endpoints you create a separate tag group for each one. That is a clean model: it prevents one group's polling cycle from blocking another's, and it maps the tag namespace onto the controller that owns it.

The Polling (ms) setting indicates how often OIPComms reads all the tags that are part of that tag group. The important architectural detail follows: the simulation does not read directly from the devices, it reads from a thread-safe data buffer that holds the value retained from the last poll. Writing values from the simulation occurs as soon as possible and is also thread-safe.

So there are two paths with different latencies. Reads come from the last poll, so they are at most one polling interval old. Writes go out as soon as possible. The buffer is what makes the simulator safe to run on multiple threads while a poll is in flight.

There is one documented interaction worth knowing about. If a write operation is queued by the simulation and a poll is halfway through completing, for example 100 out of 200 tags in the group have been read, the write operation will not complete until the poll completes. So the poll interval sets a floor on write latency, and a long polling interval on a large tag group will make writes feel slow.

Device-level settings are Enable Comms, Tag Group and Tag Name, with a Diffuse Sensor shown as the example.

Per-protocol configuration and the OPC UA browser

The configuration surface changes with the protocol, which is the right design for something that spans seven very different protocols.

The Gateway is the IP address of the target controller, and the path is typically the rack and slot location of the PLC. Those two fields are S7-shaped, which tells you that the shared connection panel started from the Siemens case and grew to accommodate the others.

When the protocol is changed to opc_ua, the options change to reflect the connection parameters for an OPC UA endpoint, and the Endpoint is the OPC UA protocol address which includes the IP address and port of the server.

The MQTT options are the most detailed in the README, which is unusual and useful. The Broker field accepts host, host:port, or a full tcp://host:port URI, with the port defaulting to 1883. The Client ID field is optional and auto-generated if empty. The Auth field accepts user:password for brokers that require authentication, and should be left empty for anonymous brokers.

The README also documents an OPC UA Browser, in a section that is cut off in the text available. The existence of an in-editor browser is the notable thing about it, since it means you can explore a server's address space from inside the simulator and pick the node to bind a tag to, rather than reading a tag list out of a separate client.

Taken together, the tag model is: a device has a tag name, a tag group places it against one controller or endpoint, and the protocol determines how that name is resolved. The tag name format has its own section in the table of contents, which suggests it is the part that carries the per-protocol differences.

Limits: an unmaintained branch, a custom engine and a self-hosted data layer

The limits are significant and mostly follow from the project's own position.

The first is that this branch is not maintained, and the README says so without hedging. New work belongs on the successor, which runs in the browser and as a desktop app. The Godot build is worth reading for the design and worth using only if you have a specific reason to stay in the Godot editor.

The second is the custom engine fork. Installation involves downloading a Godot build alongside the project rather than adding a plugin to an existing Godot installation. That is a heavy dependency: you are pinned to the fork's engine version, you cannot easily move the project to a newer Godot, and the native protocol libraries are compiled into the engine rather than loaded as extensions.

The third is that the simulator holds the live state. It reads from a thread-safe buffer of last-polled values and writes to real controllers, so a simulation is capable of moving a physical conveyor. The README's example writes to a conveyor tag on a live OPC server, which is the point and also the hazard. There is no simulation-only mode described, no dry-run switch, and no obvious way to point the whole thing at a virtual controller instead of a real one.

The fourth is the protocol coverage limits that are stated rather than hidden: MQTT is plaintext TCP with no TLS and QoS 0 only, which rules out a production broker. The other protocols carry their own vendor constraints, notably that the Siemens support is Put/Get rather than the newer symbolic access, and that Beckhoff ADS is tied to TwinCAT 2 and 3.

The fifth is the release shape. The tags are release candidates and development builds rather than stable versions, with the newest at v4.7-rc1 from July 2026, and the repository has no GitHub release notes to read.

Finally, the licence of the project is MIT, but the industrial equipment it drives, and the terms under which you point a simulator at a live controller, are a question for your own organisation rather than for the repository.

Open Industry Project against a commercial simulator and against a DIY Godot scene

Two comparisons make the choice clearer.

The first is against a commercial industrial simulator, of which there are several aimed at exactly this purpose, with high-fidelity 3D plant models, realistic process dynamics and support contracts. The difference in approach is scope and certainty. Those products model process behaviour: tanks filling, levels rising, temperatures settling. Open Industry Project models the communication, not the process. It gives you a part that reads and writes a tag and a scene you can lay out, and the physics is whatever the connected controller does.

That is not a weakness, it is a different question. If you are learning how a PLC and a scanner talk to each other, or you are building a plugin or an integration that needs a PLC on the other end, a simulator that speaks the real protocols is more useful than a beautiful model of a plant that talks to nothing.

The second comparison is against building a Godot scene yourself. GDScript can open sockets, and Godot can be told to talk to a Modbus server by hand, so a simple integration is achievable without any framework. The difference in approach is that the framework has already solved the parts that are tedious rather than difficult: tag grouping per controller, a polling model with a consistent read path, the thread-safe buffer between the simulation and the device thread, and a native client for each of seven protocols.

That last point is the strongest argument for the project. The protocol clients are the part you would never want to write, particularly the OPC UA stack and the Beckhoff ADS implementation, and the fact that they are C libraries linked into a custom engine shows that they are the real implementations rather than approximations.

So the honest recommendation is to use the successor for anything new, and to treat the Godot branch as a reference implementation with a readable account of how a protocol-driven simulation is put together.

Editorial conclusion

Adopt the Godot build of Open Industry Project only if you have a specific reason to need a desktop simulator in the Godot editor, since the project itself directs you to the browser and desktop successor at openindustryproject.org. Do not start new work against the Godot version. Verify first that the successor covers the protocol you need, that your controller is reachable on the network the simulator runs on, and that your OPC UA endpoint or PLC path is configured before you expect values to move.

Frequently asked questions

Is the Godot version of Open Industry Project still maintained?

No, and the README says so in a callout at the top. This is the Godot version of Open Industry Project and it is no longer maintained. Its successor runs in the browser and as a desktop app, available at openindustryproject.org, with the code in the separate Open-Industry-Project/Open-Industry-Project repository.

Which industrial protocols does Open Industry Project support?

Seven: OPC UA via open62541, EtherNet/IP via libplctag, Modbus TCP via libplctag, Siemens S7 1200 and 1500 Put/Get, Beckhoff ADS for TwinCAT 2 and 3, Universal Robots RTDE on port 30004, and MQTT via Eclipse Paho over plaintext TCP with MQTT 3.1.1, no TLS and QoS 0 only.

How does the simulator read and write PLC values?

Each Tag Group is associated with one PLC or one OPC UA client, and the Polling setting controls how often all the tags in that group are read. The simulation does not read from devices directly; it reads from a thread-safe buffer holding the value retained from the last poll, while writes are sent as soon as possible. Nothing is communicated until the Enable Comms checkbox is checked.

Official sources

  1. Issues
  2. License: MIT
  3. Open-Industry-Project/Open-Industry-Project-Godot on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/open-industry-project-open-industry-project-godot.svg)](https://hysenlabs.com/projects/open-industry-project-open-industry-project-godot)

Was this useful?