Skip to content

Engine Adapters

← E2E Client | Table Of Contents | Next: Packaging →


An engine adapter owns the core connector as a private implementation, exposing only a surface that fits each engine's types and thread rules. Core types like result_t<T>, connector_t aren't revealed in the adapter's public header. See the C++ contract §7 for main thread delivery, callbacks registered by packet name, and per-call request completion.


Unreal Engine

Distribution

Distributed in .uplugin format. Placed under Plugins/ZLinkStreamConnector/.

Plugins/
└── ZLinkStreamConnector/
    ├── ZLinkStreamConnector.uplugin
    └── Source/
        ├── ZLinkStreamConnector/      ← Runtime module
        └── ZLinkStreamConnectorTests/ ← Automation Test module

Basic Usage

The Engine Lobby sample's Actor creates the connector, registers a delegate for the server push ChatNotify, and connects.

Unreal/Source/EngineLobby/Private/EngineLobbyClientActor.cpp
void AZLinkClientActor::BeginPlay ()
{
    Super::BeginPlay ();
    Connector = NewObject<UZLinkStreamConnector> (this);
    PacketHandle =
      Connector->On (PacketName (engine_lobby::packet::chat_notify),
                     [this] (const FZLinkStreamPacket &Packet) { HandlePacket (Packet); });
    SetStatus (TEXT ("Engine Lobby: connecting"));
    Connector->Connect (Endpoint);
    if (!Connector->IsConnected ()) {
        SetStatus (TEXT ("Engine Lobby: connection failed"), FColor::Red);
        return;
    }
    SendPing ();
}

Pumping the connector from Tick runs the delegates on the Game Thread.

Unreal/Source/EngineLobby/Private/EngineLobbyClientActor.cpp
void AZLinkClientActor::Tick (float DeltaSeconds)
{
    Super::Tick (DeltaSeconds);
    if (Connector != nullptr) {
        Connector->Tick (DeltaSeconds);
    }
}

Using It From Blueprint

Connect, Close, SendJson, RequestJson, On, Dispatch are all BlueprintCallable. On(PacketName, Delegate) returns a subscription handle, and RequestJson(..., OnCompleted) delivers that request's result to its delegate.

Close() is called automatically on PIE shutdown, map unload, and game instance shutdown.

Running Automation Tests

UnrealEditor-Cmd MyProject.uproject \
  -ExecCmds="Automation RunTests ZLink.StreamConnector; Quit" \
  -unattended -NullRHI

Godot 4

Distribution

Distributed as a GDExtension source package. Placed under the Godot project's addons/zlink_stream_connector/.

The .gdextension file registers the built shared library.

Basic Usage (C++)

The Engine Lobby sample's node registers a callback for ChatNotify and connects.

Godot/cpp/src/engine_lobby_node.cpp
void EngineLobbyNode::_ready ()
{
    status_ = get_node<Label> ("Status");
    chat_subscription_ =
      connector_.on (chat_notify, [this] (const auto &packet) { handle_packet (packet); });
    const CharString endpoint = endpoint_.utf8 ();
    connector_.connect (std::string (endpoint.get_data (), endpoint.length ()));
    if (connector_.state () != zlink::godot_stream_connector::connection_state_t::connected) {
        fail ("connection failed");
        return;
    }
    connector_.request_json (ping_req, encode_field ("sentAtUnixMs", "1000"), 5.0,
                             [this] (const auto &result) { handle_ping_response (result); });
    set_process (true);
}

It pumps the connector from _process on the Godot main thread.

Godot/cpp/src/engine_lobby_node.cpp
void EngineLobbyNode::_process (double)
{
    if (!failed_) {
        connector_.dispatch ();
    }
}

Axmol Engine

Distribution

Distributed as a CMake source package. Include it in the Axmol project's CMakeLists.txt, or install core via vcpkg/Conan.

add_subdirectory(third_party/zlink_axmol_connector)
target_link_libraries(${APP_NAME} PRIVATE zlink_axmol_connector)

Basic Usage

The Engine Lobby sample's Scene registers a callback for ChatNotify and connects.

Axmol/Source/EngineLobbyScene.cpp
chat_subscription_ = connector_.on (engine_lobby::packet::chat_notify,
                                    [this] (const auto &packet) { handle_packet (packet); });
connector_.connect (endpoint);
if (connector_.state () != zlink::axmol_stream_connector::connection_state_t::connected) {
    set_status ("Engine Lobby: connection failed");
    return true;
}
send_ping ();

It pumps the connector from the Axmol scheduler update.

Axmol/Source/EngineLobbyScene.cpp
schedule ([this] (float) { connector_.dispatch (); }, "engine-lobby-pump");

Common Engine Adapter API Mapping

Operation Unreal Godot Axmol
Connect Connect(Endpoint) connect(endpoint) connect(endpoint)
Terminate Close() close() close()
One-way send SendJson(Name, Json) send_json(name, json) send_json(name, json)
Request/reply RequestJson(Name, Json, Timeout, OnCompleted) request_json(name, json, timeout, callback) request_json(name, json, timeout, callback)
Register push On(PacketName, Delegate) → handle on(packet_name, callback) → handle on(packet_name, callback) → handle
Dispatch Dispatch() (called from Tick) dispatch() (called per frame) dispatch() (called per frame)
Status change OnConnectionStateChanged delegate on_connection_state_changed callback on_connection_state_changed callback