Godot game integration for EVOID — WebSocket, EventBus, WebGL hosting
Connect your Godot games (desktop or web) to an EVOID server. Zero boilerplate, zero coupling.
- EventBus pattern — subscribe/emit like native Godot signals
- State Machine — BOOT → IDLE → CONNECTING → ONLINE → RECOVERING → ERROR
- Auto-reconnect — exponential backoff, hands-free recovery
- Intent System (IOP) — send game actions as Intents, not raw HTTP
- Dual transport — WebSocket (broad compatibility) + UDP (low-latency)
- WebGL support — play in browser with instant loading
- Embed mode — seamless integration in parent websites
- Export optimizations — auto SW injection, manifest generation
- Zero dependencies — pure GDScript, no native builds
Copy evoid_godot/ into your project's addons/ folder:
your-game/
addons/
evoid_godot/
core/
app.gd
client.gd
udp_client.gd
event_bus.gd
config.gd
topics.gd
web_loader.gd
export_plugin.gd
plugin.cfg
plugin.gd
icon.png
Project → Project Settings → Plugins → EVOID → Enable
func _ready():
EvoidApp.connect_to_server("wss://your-server.com", "game-id")EvoidApp.send_intent("player_move", {"x": 10, "y": 20})
EvoidApp.send_intent("player_shot", {"origin": global_position, "direction": aim_direction})func _ready():
EvoidBus.subscribe(EvoidTopics.GAME_EVENT, _on_game_event)
func _on_game_event(payload: Dictionary):
match payload.get("type"):
"player_moved": update_player(payload)
"shot_fired": play_shot_animation(payload)Godot Game
↓
EvoidApp (State Machine)
↓
EvoidClient (WebSocket) or EvoidUDP (UDP)
↓
EVOID Server
↓
Message Bus (in-process, 0ms)
↓
Intent Handlers / Auth / Analytics
| Component | Purpose |
|---|---|
EvoidApp |
State machine + orchestration layer |
EvoidClient |
WebSocket connection |
EvoidUDP |
Low-latency UDP transport (binary protocol) |
EvoidBus |
Pub/sub event bus (zero-coupling) |
EvoidConfig |
Configuration resource (Inspector-friendly) |
EvoidTopics |
Topic constants (mirrors Python server) |
EvoidWebLoader |
WebGL auto-detection + chunk prefetching + embed API |
EvoidExportPlugin |
Export-time optimizations (SW, manifest) |
func _ready():
var config = EvoidConfig.new()
config.server_url = "wss://your-server.com"
config.game_id = "my-game"
EvoidApp.config = config
EvoidApp.connect_to_server()Prerequisites: Godot 4.4+, EVOID server (Python 3.12+)
func _ready():
var config = EvoidConfig.new()
config.game_id = "my-game"
EvoidApp.config = config
EvoidApp.auto_connect() # auto-detects WebGL, resolves same-origin URLPrerequisites: Godot 4.4+ with HTML5 export template, EVOID server with GameHost
<!-- Parent website -->
<iframe src="/game/tic-tac-toe/" width="400" height="600" frameborder="0"></iframe>
<script>
iframe.addEventListener("message", (e) => {
if (e.data.type === "evoid:player_joined") {
showPlayerCount(e.data.player_id);
}
});
// Send intent to game
iframe.contentWindow.postMessage({type: "evoid:send_intent", name: "pause", metadata: {}}, "*");
</script># Game side — receive from parent
func _ready():
EvoidWebLoader.embed_message.connect(_on_embed_message)
func _on_embed_message(message: Dictionary):
match message.get("type"):
"evoid:focus": grab_focus()
"evoid:resize": resize_canvas(message.get("width"), message.get("height"))Prerequisites: Server with GameHost(embed_mode=True), parent page supports postMessage
func _ready():
var config = EvoidConfig.new()
config.udp_address = "your-server.com"
config.udp_port = 9000
EvoidApp.config = config
EvoidApp.connect_udp(config.udp_address, config.udp_port, "Player1")Prerequisites: evoid-transport plugin on server, UDP port open
# ~60% smaller than JSON
EvoidClient.send_intent_binary("player_move", {"x": 10, "y": 20})Built-in. If connection drops:
- State: ONLINE → RECOVERING
- Exponential backoff: 1s, 2s, 4s, 8s, 16s, 20s (cap)
- Auto-retry up to
max_reconnect_attempts
func _ready():
EvoidApp.auto_connect() # auto-detects WebGL, connects to same-originFeatures:
- Instant splash screen (no loading)
- Service Worker caching (instant repeat visits)
- Chunked PCK streaming (256KB chunks)
- Manifest-aware prefetch (uses server manifest for correct chunk count)
- Parent website communication (postMessage API)
var config = EvoidConfig.new()
config.server_url = "wss://your-server.com"
config.game_id = "my-game"
config.auto_connect = true
config.tick_rate = 60
# UDP
config.udp_address = "your-server.com"
config.udp_port = 9000
# Embed mode
config.embed_mode = true
# Export optimizations
config.optimize_web = true
config.binary_intents = false
EvoidApp.config = config
EvoidApp.connect_to_server()Or via Inspector:
@export var evoid_config: EvoidConfigfunc _on_shot_pressed():
EvoidApp.send_intent("player_shot", {
"origin": global_position,
"direction": aim_direction
})func play_card(card_id: String):
EvoidApp.send_intent("card_played", {"card": card_id})func _on_player_moved(payload):
var position = Vector2(payload.x, payload.y)
update_remote_player(payload.player_id, position)EVOID cluster is transparent to the Godot client. The game connects to one node via EvoidApp.connect_to_server(). The server-side cluster plugin handles routing between nodes. The client doesn't know or care how many nodes exist.
Prerequisites (server-side only):
- evoid-cluster plugin installed
- WebSocket ports open between nodes
- evoid-di for service discovery
This plugin uses Godot's native autoload singleton pattern — the equivalent of DI in GDScript. All components (EvoidApp, EvoidClient, EvoidUDP, EvoidBus, EvoidWebLoader) are globally accessible singletons.
On the server side, the Python evoid-godot plugin registers with evoid-di:
di.register("godot", create_game_handler, scope="singleton")| Feature | Godot Dedicated Server | EVOID |
|---|---|---|
| Complexity | High | Simple |
| Setup | Manual | Automatic |
| Reconnect | Manual | Auto |
| EventBus | None | Built-in |
| State Machine | None | Built-in |
| Web Support | Limited | Full |
| Embed in Website | Manual | postMessage API |
| Export Optimizations | None | Auto SW + manifest |
| Latency | 10-50ms | < 1ms (UDP) |
This is the client plugin (GDScript). For the server, see:
- evoid-godot — Python server plugin
- EVOID Runtime — The runtime itself
# Server setup
uv add evoid evoid-godot
# Or with evo CLI
evo plug install godot- Godot 4.4+
- EVOID server (Python 3.12+)
MIT