{"id":50621282,"url":"https://github.com/shilo/mimic","last_synced_at":"2026-06-08T14:00:57.335Z","repository":{"id":362172518,"uuid":"1256987957","full_name":"Shilo/mimic","owner":"Shilo","description":"Clone-and-play multiplayer for Godot. Drop in a MimicSync node and make your scenes network-aware, with high-level nodes for connection and gameplay.","archived":false,"fork":false,"pushed_at":"2026-06-06T07:46:25.000Z","size":5498,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T12:21:44.686Z","etag":null,"topics":["client","enet","game-development","gdscript","godot","godot-4","godot-addon","godot-engine","multiplayer","multiplayer-synchronizer","netcode","networking","online-game","replication","rpc","server","synchronization","tcp","udp","websocket"],"latest_commit_sha":null,"homepage":"https://shilo.github.io/mimic/","language":"GDScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Shilo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-02T09:02:58.000Z","updated_at":"2026-06-06T07:46:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Shilo/mimic","commit_stats":null,"previous_names":["shilo/mimic"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Shilo/mimic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shilo%2Fmimic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shilo%2Fmimic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shilo%2Fmimic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shilo%2Fmimic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Shilo","download_url":"https://codeload.github.com/Shilo/mimic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shilo%2Fmimic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34022032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","enet","game-development","gdscript","godot","godot-4","godot-addon","godot-engine","multiplayer","multiplayer-synchronizer","netcode","networking","online-game","replication","rpc","server","synchronization","tcp","udp","websocket"],"created_at":"2026-06-06T12:03:03.096Z","updated_at":"2026-06-07T13:00:53.945Z","avatar_url":"https://github.com/Shilo.png","language":"GDScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"brand/icon/mimic.png\" alt=\"Mimic icon\" width=\"40\"\u003e Mimic Multiplayer\n\n\u003cpicture\u003e\n  \u003csource srcset=\"brand/logo/mimic_m_multiplayer.svg\" type=\"image/svg+xml\"\u003e\n  \u003cimg src=\"brand/logo/mimic_m_multiplayer.png\" alt=\"Mimic Multiplayer\" width=\"700\"\u003e\n\u003c/picture\u003e\n\nClone-and-play multiplayer for Godot. Drop in a MimicSync node and make your scenes network-aware, with high-level nodes for connection and gameplay.\n\nMimic Multiplayer is currently a small connection and configuration addon for Godot 4. It manages a `Mimic` autoload, exposes typed Project Settings, starts ENet and WebSocket peers, reserves `MimicConnector` for connection UI, and provides `MimicSync` for scene-level authoring.\n\nThis project is intentionally smaller than full networking frameworks. Mimic is for developers who want a lightweight helper around Godot's built-in high-level multiplayer API, not a prediction, rollback, interpolation, lag compensation, relay, or full gameplay framework.\n\n## Contents\n\n- [Current Scope](#current-scope)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Configure Connection Defaults](#configure-connection-defaults)\n- [Start Networking From Code](#start-networking-from-code)\n- [Listen For Connection Events](#listen-for-connection-events)\n- [Use MimicConnector](#use-mimicconnector)\n- [Use MimicSync](#use-mimicsync)\n- [Logging](#logging)\n- [Mimic Or NetFox?](#mimic-or-netfox)\n- [Current Limitations](#current-limitations)\n- [Minimal Local Test](#minimal-local-test)\n- [Editor Multi-Instance Testing](#editor-multi-instance-testing)\n\n## Compatibility Policy\n\nMimic keeps the current project shape explicit instead of carrying compatibility layers for older names, behavior, files, scenes, or configuration. After updating Mimic, review your code, scenes, and Project Settings \u003e Mimic Multiplayer against this README and update them to the current model.\n\n## Current Scope\n\nMimic is focused on connection setup, project configuration, and a stable visible component shape.\n\nWorking now:\n\n- Plugin-managed `Mimic` singleton.\n- Project Settings for connection defaults.\n- ENet server/client startup.\n- WebSocket server/client startup.\n- Offline state and an Offline transport selection that intentionally does not start a network peer.\n- WebRTC transport selection reserved for future signaling support, currently unsupported.\n- Optional UPnP port forwarding.\n- Runtime connection state, status helpers, and lifecycle signals.\n- Project Settings auto-connect for startup scenes and local multi-instance testing.\n- `MimicConnector` placeholder for future connection form UI.\n- `MimicSync` component that subclasses Godot's `MultiplayerSynchronizer`.\n\nNot ready yet:\n\n- Automatic dynamic spawn/despawn replication.\n- Late-join spawn replay or spawn-state transfer from `SceneReplicationConfig` spawn properties.\n- Built-in connector UI controls.\n- Prediction, rollback, interpolation, lag compensation, matchmaking, relay services, or raw packet protocols.\n\n## Requirements\n\n- Godot 4.6 or newer.\n- A project using Godot's high-level multiplayer API.\n\n## Installation\n\nCopy the addon into your project:\n\n```text\nres://addons/mimic/\n```\n\nThe scripts developers usually add to scenes live in:\n\n```text\nres://addons/mimic/nodes/\n```\n\nEnable the plugin:\n\n1. Open Project \u003e Project Settings.\n2. Go to the Plugins tab.\n3. Enable `Mimic`.\n\nWhen enabled, the plugin adds a `Mimic` singleton so your scripts can call `Mimic.start_server()`, `Mimic.start_client()`, and related helpers.\n\n## Configure Connection Defaults\n\nOpen Project \u003e Project Settings and search for `Mimic Multiplayer`.\n\nGodot does not currently expose a description field for custom Project Settings added through `ProjectSettings.add_property_info()`, so Mimic documents setting meanings here instead of relying on tooltips.\n\nConnection:\n\n```text\nmimic_multiplayer/connection/transport: Offline, ENet, WebSocket, or WebRTC (Unsupported)\nmimic_multiplayer/connection/editor_auto_connect: Disabled, Server Then Client, Client, or Server\nmimic_multiplayer/connection/address: Client address, default 127.0.0.1\nmimic_multiplayer/connection/port: Server/client port, default 15490\nmimic_multiplayer/connection/max_clients: Max ENet server clients, default 32\n```\n\nWebSocket:\n\n```text\nmimic_multiplayer/websocket/client_use_tls: Use wss:// when joining a WebSocket server, default false\n```\n\nPort Forwarding:\n\n```text\nmimic_multiplayer/port_forwarding/enabled: Try UPnP port forwarding when hosting, default false\n```\n\nAdvanced settings are hidden unless Advanced Settings is enabled in Project Settings.\n\nAdvanced connection settings:\n\n```text\nmimic_multiplayer/connection/bind_address: Local bind address for server sockets and ENet client local binding, default *\n```\n\nAdvanced ENet settings:\n\n```text\nmimic_multiplayer/enet/channel_count: ENet channel count, default 0\nmimic_multiplayer/enet/in_bandwidth: Incoming bandwidth limit in bytes per second, 0 for unlimited\nmimic_multiplayer/enet/out_bandwidth: Outgoing bandwidth limit in bytes per second, 0 for unlimited\nmimic_multiplayer/enet/client_local_port: Local ENet client port, 0 for ephemeral\n```\n\nAdvanced WebSocket settings:\n\n```text\nmimic_multiplayer/websocket/path: Optional path appended to WebSocket client URLs, default empty\nmimic_multiplayer/websocket/handshake_timeout: WebSocket handshake timeout in seconds, default 3.0\n```\n\nAdvanced port forwarding settings:\n\n```text\nmimic_multiplayer/port_forwarding/delete_mapping_on_stop: Delete owned UPnP mappings when networking stops, default true\nmimic_multiplayer/port_forwarding/query_external_address: Query the gateway external address after mapping, default true\nmimic_multiplayer/port_forwarding/protocol: TCP/UDP mapping protocol selection, default Transport Default\nmimic_multiplayer/port_forwarding/duration: UPnP mapping lease duration in seconds, default 7200; 0 requests permanent\nmimic_multiplayer/port_forwarding/discover_timeout_ms: UPnP discovery timeout in milliseconds, default 2000\nmimic_multiplayer/port_forwarding/discover_ttl: UPnP discovery time-to-live hop count, default 2\n```\n\nDebug:\n\n```text\nmimic_multiplayer/debug/log_level: All, Warning, Error, or None, default Warning\n```\n\nUPnP discovery and port mapping run in a background thread so hosting does not block the main thread while the router responds.\n\nPort forwarding depends on the user's router, network, and platform. Treat it as a convenience for local testing, not a guaranteed matchmaking or NAT traversal solution.\n\n## Start Networking From Code\n\nHost a server using the Project Settings defaults:\n\n```gdscript\nvar error := Mimic.start_server()\nif error != OK:\n\tMimicLog.error(\"Failed to start server: %s\" % error_string(error))\n```\n\nJoin a server using the Project Settings defaults:\n\n```gdscript\nvar error := Mimic.start_client()\nif error != OK:\n\tMimicLog.error(\"Failed to start client: %s\" % error_string(error))\n```\n\nOverride the address or port for a single call:\n\n```gdscript\nMimic.start_server(9000)\nMimic.start_client(\"192.168.1.25\", 9000)\n```\n\nStop networking:\n\n```gdscript\nMimic.stop()\n```\n\nCancel an in-progress client connection:\n\n```gdscript\nMimic.cancel_connection()\n```\n\nStart as server if possible, otherwise connect as a client:\n\n```gdscript\nMimic.start_server_or_client()\n```\n\nThis is useful for quick local multi-instance testing. The first running instance usually binds the port and becomes server; later instances fail to bind and fall back to client.\n\nProject Settings auto-connect only runs when Godot has the `editor` feature tag, so exported builds should start connections from game code or UI.\n\n## Listen For Connection Events\n\nConnect to Mimic signals from any script:\n\n```gdscript\nfunc _ready() -\u003e void:\n\tMimic.state_changed.connect(_on_state_changed)\n\tMimic.start_failed.connect(_on_start_failed)\n\tMimic.server_started.connect(_on_server_started)\n\tMimic.client_started.connect(_on_client_started)\n\tMimic.client_connected.connect(_on_client_connected)\n\tMimic.client_connection_failed.connect(_on_client_connection_failed)\n\tMimic.server_disconnected.connect(_on_server_disconnected)\n\tMimic.peer_connected.connect(_on_peer_connected)\n\tMimic.peer_disconnected.connect(_on_peer_disconnected)\n\tMimic.stopped.connect(_on_stopped)\n\tMimic.port_mapping_finished.connect(_on_port_mapping_finished)\n\n\nfunc _on_state_changed(state: Mimic.NetworkState, previous_state: Mimic.NetworkState) -\u003e void:\n\tMimicLog.log(\"State changed from\", previous_state, \"to\", state)\n\n\nfunc _on_start_failed(_attempted_state: Mimic.NetworkState, error: Error, message: String) -\u003e void:\n\tMimicLog.warning(\"%s (%s)\" % [message, error_string(error)])\n\n\nfunc _on_server_started(port: int) -\u003e void:\n\tMimicLog.log(\"Server listening on\", port)\n\n\nfunc _on_client_started(address: String, port: int) -\u003e void:\n\tMimicLog.log(\"Connecting to %s:%d\" % [address, port])\n\n\nfunc _on_client_connected() -\u003e void:\n\tMimicLog.log(\"Connected\")\n\n\nfunc _on_client_connection_failed(message: String) -\u003e void:\n\tMimicLog.warning(message)\n\n\nfunc _on_server_disconnected() -\u003e void:\n\tMimicLog.log(\"Disconnected from server\")\n\n\nfunc _on_peer_connected(peer_id: int) -\u003e void:\n\tMimicLog.log(\"Peer connected:\", peer_id)\n\n\nfunc _on_peer_disconnected(peer_id: int) -\u003e void:\n\tMimicLog.log(\"Peer disconnected:\", peer_id)\n\n\nfunc _on_stopped() -\u003e void:\n\tMimicLog.log(\"Networking stopped\")\n\n\nfunc _on_port_mapping_finished(result: UPNP.UPNPResult, external_address: String) -\u003e void:\n\tMimicLog.log(\"Port mapping result:\", result, external_address)\n```\n\nUseful state helpers:\n\n```gdscript\nMimic.is_offline()\nMimic.is_connecting()\nMimic.is_server()\nMimic.is_client()\nMimic.get_state()\nMimic.get_local_peer_id()\nMimic.get_peer_ids()\nMimic.get_external_address()\n```\n\n## Use MimicConnector\n\n`MimicConnector` is reserved for a future drag-and-drop connection form with an IP field, port field, Host button, Join button, and Stop button. It does not start networking on its own.\n\nFor now, wire your own UI directly to the `Mimic` singleton:\n\n```gdscript\nfunc _on_host_pressed() -\u003e void:\n\tMimic.start_server()\n\n\nfunc _on_join_pressed() -\u003e void:\n\tMimic.start_client()\n\n\nfunc _on_stop_pressed() -\u003e void:\n\tMimic.stop()\n```\n\nUse Project Settings for editor-only startup auto-connect:\n\n```text\nmimic_multiplayer/connection/editor_auto_connect = Disabled\nmimic_multiplayer/connection/editor_auto_connect = Server Then Client\nmimic_multiplayer/connection/editor_auto_connect = Client\nmimic_multiplayer/connection/editor_auto_connect = Server\n```\n\n## Use MimicSync\n\nAdd a `MimicSync` node under a scene/entity you want to prepare for synchronization.\n\n`MimicSync` is a `MultiplayerSynchronizer`, so configure it like Godot's native synchronizer:\n\n1. Add `MimicSync` as a child of the node you want to sync.\n2. Set or confirm its `root_path`.\n3. Assign a `SceneReplicationConfig`.\n4. Choose the properties Godot should replicate.\n\nCurrent note: runtime property replication remains Godot's native `MultiplayerSynchronizer` behavior. Mimic does not yet replace `MultiplayerSpawner` or perform automatic dynamic spawning in the current connection MVP.\n\n## Logging\n\nMimic logs connection attempts, connection results, peer changes, stop events, and UPnP results.\n\nSet log output in Project Settings:\n\n```text\nmimic_multiplayer/debug/log_level: All, Warning, Error, None\n```\n\nExample log line:\n\n```text\n[05-29 22:14:03] [2 mimic._on_connected_to_server] Connected to server.\n```\n\nIn the editor Output panel the bracketed timestamp and source tag are dimmed on informational log lines so the message stands out. The color is applied with Godot's `print_rich()` BBCode, which the editor renders and strips from saved log files, so log files stay plain text. If an informational log message contains `[`, Mimic uses plain output for that line so literal BBCode-like text stays unchanged in both the editor and saved logs.\n\nThe number inside the source tag appears only in editor-launched runs, and only when a connected multiplayer peer has a valid local peer ID. The source tag falls back to `Mimic` when GDScript call stacks are unavailable; release exports need `debug/settings/gdscript/always_track_call_stacks` enabled to include caller names.\n\nUse `MimicLog.log()`, `MimicLog.warning()`, and `MimicLog.error()` for messages that should respect `mimic_multiplayer/debug/log_level`. Use `MimicLog.log_forced()`, `MimicLog.warning_forced()`, and `MimicLog.error_forced()` for diagnostics that should always output logs.\n\nTo route Mimic output yourself, set `MimicLog.output_handler`. The handler receives the plain formatted line without editor color markup:\n\n```gdscript\nvar mimic_log_messages: PackedStringArray = []\n\n\nMimicLog.output_handler = func(level: MimicLog.Level, message: String) -\u003e void:\n\tmimic_log_messages.append(message)\n```\n\n## Mimic Or NetFox?\n\nMimic and NetFox are not trying to be the same thing.\n\nUse Mimic if you want:\n\n- A smaller helper around Godot's built-in high-level multiplayer API.\n- Basic connection setup through project settings.\n- A lightweight host/join/stop workflow.\n- A future path toward simpler `MultiplayerSpawner` and `MultiplayerSynchronizer` authoring.\n- Fewer systems to learn before prototyping.\n\nUse NetFox if you need:\n\n- Consistent network timing.\n- Rollback.\n- Client-side prediction.\n- Server reconciliation.\n- Interpolation helpers.\n- Lag compensation.\n- Noray integration.\n- A more complete networking framework for responsive online games.\n\nNetFox is the better fit when your game needs advanced netcode features. Mimic is intentionally smaller and aims to make the common Godot multiplayer setup easier rather than replacing a full-featured framework.\n\n## Current Limitations\n\n- WebRTC is listed but not implemented.\n- ENet is not available in web exports; use WebSocket for browser clients.\n- WebSocket server TLS is not configured by Mimic yet; terminate `wss://` at a proxy.\n- WebSocket subprotocols and custom handshake headers are not exposed yet.\n- Mimic does not yet perform dynamic spawn/despawn replication.\n- Mimic does not yet package spawn properties from `SceneReplicationConfig`.\n- Mimic does not yet provide built-in UI controls.\n- Mimic does not provide prediction, rollback, interpolation, lag compensation, matchmaking, or relay services.\n\n## Minimal Local Test\n\n1. Set `mimic_multiplayer/connection/transport` to `ENet`.\n2. Set `mimic_multiplayer/connection/editor_auto_connect` to `Server Then Client`.\n3. Set `mimic_multiplayer/connection/address` to `127.0.0.1`.\n4. Set `mimic_multiplayer/connection/port` to `15490`.\n5. Run two game instances.\n\nExpected result:\n\n- The first instance starts as server.\n- The second instance joins as client.\n- Connection events appear in the Godot output.\n\n## Editor Multi-Instance Testing\n\nGodot can launch multiple local game instances from the editor:\n\n1. Open Debug \u003e Customize Run Instances...\n2. Set the number of instances you want.\n3. Run the project.\n\nFor easier window tiling, add `res://addons/mimic/testing/mimic_run_instance_grid.gd` as an AutoLoad named `MimicRunInstanceGrid`.\n\nAlso disable Game \u003e Embedding Options \u003e Embed Game on Next Play so each instance opens in its own window. When multiple editor-launched instances start together, `MimicRunInstanceGrid` arranges them into a grid and appends their instance index to the window title.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshilo%2Fmimic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshilo%2Fmimic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshilo%2Fmimic/lists"}