@mistscale/godot-sdk
v0.0.1-beta
Published
MistScale Godot SDK — a Godot 4.3+ addon for NPC chat, voice, and spatial context over the MistScale REST and WebSocket APIs. Published on npm for versioned/CDN distribution; Godot itself installs this by copying addons/mistscale_sdk/ into your project (s
Maintainers
Readme
MistScale Godot SDK
A Godot 4.3+ addon for NPC chat, voice, and spatial context over the same MistScale REST and
WebSocket APIs @mistscale/web-sdk uses. Same wire contract, same event model, GDScript-native
surface (signals instead of callbacks/promises).
Full raw protocol reference: ../web/docs/rest-api.md and
../web/docs/websocket-api.md — not duplicated here since the
contract is identical across every MistScale client.
Install
Copy addons/mistscale_sdk/ into your project's own addons/ folder (Godot has no package
manager for this — this is the standard way addons are distributed, including via the Asset
Library). Then in Project Settings → Plugins, enable "MistScale SDK". This registers
MistscaleSDK as a global autoload, reachable from any script without an explicit preload.
Quick start
func _ready() -> void:
var config_error = MistscaleSDK.configure("ms_...") # Project Settings → API Keys
if config_error != null:
push_error(config_error.message)
return
var result = await MistscaleSDK.list_npcs()
if not result["ok"]:
push_error(result["error"].message)
return
var connection = MistscaleSDK.connect_npc(result["npcs"][0]["id"])
connection.chat_chunk.connect(func(chat_id, delta): print(delta)) # streamed tokens
connection.chat_message.connect(func(chat_id, text, _f, _m): print("\n[final] ", text))
connection.opened.connect(func(): connection.send_chat("Hello there!"))Public API
MistscaleSDK (autoload singleton)
configure(api_key, control_plane_url = DEFAULT, npc_service_url = DEFAULT, player_id = "", request_timeout_seconds = 15.0) -> MistscaleError(ornullon success)list_npcs() -> Dictionary—{"ok": true, "npcs": Array}or{"ok": false, "error": MistscaleError}verify_key() -> Dictionary—{"ok": true, "verified": bool}or{"ok": false, "error": MistscaleError}connect_npc(npc_id, player_id = "", instance_id = "", auto_reconnect = true, max_reconnect_delay_ms = 30000) -> MistscaleNPCConnection
list_npcs()/verify_key() are coroutines — call with await.
MistscaleNPCConnection (Node, returned by connect_npc)
Methods: send_chat(message, sender_id = ""), send_voice_chunk(data: PackedByteArray, end = false, sender_id = ""), set_spatial_context(location, time_of_day = "", weather = ""), get_evolution_status(), get_quota_status(), close(). Property: state (CONNECTING/OPEN/CLOSING/CLOSED).
Signals:
| Signal | Args | When |
|---|---|---|
| opened | — | socket connected |
| closed | code, reason, expected | socket closed |
| sdk_error | error: MistscaleError | transport-level error |
| chat_chunk | chat_id, delta | one streamed token — append |
| chat_revision | chat_id, text | grounding rewrote the reply — replace |
| chat_message | chat_id, text, finalized_by_metadata, metadata | turn settled |
| transcript | text | voice message transcribed |
| chat_blocked | chat_type, reason, limit, used | quota exceeded |
| quota_status | text_status, voice_status | reply to get_quota_status() |
| evolution_status | metadata | reply to get_evolution_status() |
| audio | bytes: PackedByteArray | synthesized speech (voice replies) |
| reconnecting | attempt, delay_ms | auto-reconnect about to fire |
Same streaming contract as the Web SDK: append chat_chunk deltas, replace on chat_revision,
chat_message is the settled state.
MistscaleError
kind (CONFIG/API/AUTH/RATE_LIMIT/TIMEOUT/CONNECTION — see MistscaleError.Kind),
message, status, code, retry_after_seconds. GDScript has no exception hierarchy, so this
is returned/emitted rather than thrown — same information the TypeScript SDK's error classes
carry.
Why signals, not the TS SDK's on()/emit()
GDScript's built-in signal keyword is idiomatic Godot and already does exactly what a custom
event emitter would — connection.chat_chunk.connect(my_handler) reads naturally to a Godot
developer and needs no extra abstraction on top.
Validation note
Verified against a real Godot 4.7.1 install, headless: the addon's scripts (including both
class_name classes) compile and load cleanly with zero errors, the autoload initializes
correctly, and a live REST call through MistscaleSDK.verify_key() — the exact HTTPRequest +
await-on-signal pattern used throughout — successfully executed against the real network and
returned a correctly-parsed error object on a non-2xx response. That covers script correctness
and the REST path.
Not yet verified: a live WebSocket chat session end-to-end in the editor (NPCConnection's
WebSocketPeer usage), since that needs a real project API key and a live NPC to talk to. Test
that in-editor against a real key before relying on it in production.
