Unity Communication Protocol
Last reviewed: 2026-07-05
Communication Model
The Unity protocol uses ZeroMQ with JSON envelopes.
| Channel | Direction | Socket model | Current binding expectation | Source |
|---|---|---|---|---|
| Command | Python to Unity | Python REQ, Unity REP |
Python connects to tcp://{host}:{command_port}; Unity binds |
src/anuva_python_server/unity/zmq_client.py |
| Status events | Unity to Python | Unity PUSH, Python PULL |
Python binds tcp://{host}:{status_port}; Unity connects |
src/anuva_python_server/unity/zmq_client.py |
| Heartbeat events | Unity to Python | Unity PUSH, Python PULL |
Python binds tcp://{host}:{heartbeat_port}; Unity connects |
src/anuva_python_server/unity/zmq_client.py |
Default ports are command 5560, status 5561, and heartbeat 5562, all on 127.0.0.1.
Message Envelope
Status: Implemented in src/anuva_python_server/unity/protocol.py.
All protocol messages use a JSON object with these common fields:
| Field | Required | Notes |
|---|---|---|
id |
Yes | Non-empty message id. |
type |
Yes | Command or event type string. |
timestamp |
Yes | Timezone-aware timestamp. |
payload |
Yes | Message-specific object. |
jobId |
No | Present for render job messages. |
workerId |
No | Included by Python commands when configured. |
unityInstanceId |
No | Used by Unity identity events if available. |
correlationId |
No | Used to connect command replies/events. |
protocolVersion |
No | Python commands default to 1.0. |
Tests: tests/unit/test_unity_protocol.py, tests/integration/test_unity_zmq_client.py.
Implemented Commands
| Type | Direction | Payload shape in code/tests | Status |
|---|---|---|---|
render.start |
Python to Unity | configPath, configUrl, outputPath, jobType, render |
Implemented |
render.cancel |
Python to Unity | reason |
Implemented |
unity.shutdown |
Python to Unity | reason |
Implemented |
unity.ping |
Python to Unity | Empty object | Implemented |
Command replies are decoded as generic ProtocolMessage, not a strict command-ack enum. Tests use reply types such as unity.commandAck, render.cancel.reply, and payload values like {"accepted": true}.
Implemented Events
| Type | Direction | Payload fields observed in tests/code | Status |
|---|---|---|---|
unity.ready |
Unity to Python | unityInstanceId, appVersion, protocolVersion |
Implemented |
render.accepted |
Unity to Python | unityJobId optional |
Implemented |
render.progress |
Unity to Python | progress, message or phase |
Implemented |
render.completed |
Unity to Python | outputPath, optional durationSec, frameCount, fileSizeBytes |
Implemented |
render.failed |
Unity to Python | errorCode, errorMessage |
Implemented |
unity.heartbeat |
Unity to Python | state, fps, currentJobId observed in tests |
Implemented |
Lifecycle Order
Typical order:
- Unity emits
unity.ready. - Python sends
render.start. - Unity command socket replies with an accepted command response.
- Unity emits
render.accepted. - Unity emits zero or more
render.progressevents. - Unity emits
render.completedorrender.failed. - Python validates/uploads/completes or fails the job.
Cancellation order:
- Python detects or receives a cancellation condition.
- If Unity is rendering, Python sends
render.cancel. - Python treats replies with
accepted,cancelled, or statusaccepted,acknowledged,cancelled, orokas acknowledged. - If cancellation is not acknowledged and
unity.terminate_on_cancel_ack_timeoutis true, the supervisor stops Unity.
Source Files To Inspect
src/anuva_python_server/unity/protocol.pysrc/anuva_python_server/unity/zmq_client.pysrc/anuva_python_server/unity/supervisor.pysrc/anuva_python_server/jobs/runner.pytests/unit/test_unity_protocol.pytests/integration/test_unity_zmq_client.pytests/unit/test_output_and_completion.py
Operational map: UnityProtocolMap.