{"id":13786611,"url":"https://github.com/debox-dev/Teleport","last_synced_at":"2025-05-11T22:31:43.690Z","repository":{"id":184819531,"uuid":"242792022","full_name":"debox-dev/Teleport","owner":"debox-dev","description":"A fast, lightweight, pure C# Unity realtime-game-networking framework","archived":false,"fork":false,"pushed_at":"2020-05-07T12:51:41.000Z","size":429,"stargazers_count":58,"open_issues_count":2,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-08-03T19:09:59.508Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/debox-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-02-24T16:56:59.000Z","updated_at":"2024-07-03T16:12:16.000Z","dependencies_parsed_at":"2023-07-30T12:48:10.557Z","dependency_job_id":null,"html_url":"https://github.com/debox-dev/Teleport","commit_stats":null,"previous_names":["debox-dev/teleport"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debox-dev%2FTeleport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debox-dev%2FTeleport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debox-dev%2FTeleport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debox-dev%2FTeleport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/debox-dev","download_url":"https://codeload.github.com/debox-dev/Teleport/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225101327,"owners_count":17421074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-03T19:01:19.174Z","updated_at":"2024-11-17T22:32:26.939Z","avatar_url":"https://github.com/debox-dev.png","language":"C#","readme":"# Teleport\n### A fast, lightweight, pure C# Unity realtime-game-networking framework.\n\nTeleport is a real-time multiplayer framework for Unity.\n\n## Installation instructions\n- Open your project manifest file (`MyProject/Packages/manifest.json`).\n- Add `\"com.debox.teleport\": \"https://github.com/debox-dev/Teleport.git\"` to the `dependencies` list.\n- Open or focus on Unity Editor to resolve packages.\n\n\n## Requirements\n- Unity 2019 or higher.\n\n## Features\n* Easy to set-up\n* Unlimited client connections (As much as your network can handle)\n* Up to 4 channels per Transport\n* Multiple transports per project (If you need more than 4 channels)\n* CRC checking\n* Sequencing\n* Retransmitting missing packets\n* Packet buffering\n* Built-in Server-Time synchronization to clients\n* Client-side delayed interpolation\n* Prefab spawning mechanism\n* State synchronization mechanism\n* Tests\n\n## Simple Setup\nTeleport allows us to test the client and server simultaneously in the same scene, we will use this ability to quickly set up a working network scene\n\n1. Open your project\n2. Add `\"com.debox.teleport\": \"https://github.com/debox-dev/Teleport.git\"` to the `dependencies` list. of your `manifest.json`, see \"Installation instructions\" for more information\n3. Add an empty GameObject to your scene and name it \"TeleportManager\"\n4. Add the \"TeleportManager\" componend to the empty GameObject\n5. Choose a prefab you'd like to synchronize. Any prefab will do. There is no need to add anything to the prefab.\n6. Drag the prefab to the **Prefab Spawners** list of the `TeleportManager` component\n7. Create a connection script `NetworkStarter.cs` (See example below)\n8. Create a new empty GameObject in your scene and name it \"NetworkStarter\"\n9. Place the `NetworkStarter` component on the \"NetworkStarter\" GameObject\n10. Drage your prefab to the `NetworkStarter` component in the inspector\n11. Press play to see your prefab spawned for both server and client\n\n\n```\n// NetworkStarter.cs\nusing System.Collections;\nusing UnityEngine;\nusing DeBox.Teleport.Unity;\nusing DeBox.Teleport;\n\npublic class NetworkStarter : MonoBehaviour\n{\n   [SerializeField] private GameObject _spawnedPrefab = null;\n\n   private IEnumerator Start()\n   {\n        yield return new WaitForSeconds(1);\n\tTeleportManager.Main.StartServer();\n        TeleportManager.Main.ConnectClient();\n        Debug.Log(\"Waiting for client to authenticate...\");\n        while (TeleportManager.Main.ClientState != TeleportClientProcessor.StateType.Connected)\n        {\n             yield return null;\n        }\n        Debug.Log(\"Client to authenticated!\");\n        for (var i = 0; i \u003c 10; i++)\n        {\n            var spawnPosition = Vector3.one * i;        \n            TeleportManager.Main.ServerSideSpawn(_spawnedPrefab, spawnPosition);\n        }\n   }\n}\n```\n\n## Server Time Prediction\nTeleport automagically syncs the server time to the clients\n#### Server time on the server\n```\nDebug.Log(\"Actual server time is \" + TeleportManager.Main.ServerSideTime);\n```\n#### Server time on the clients\n```\nDebug.Log(\"Predicted server time is \" + TeleportManager.Main.ClientSideServerTime);\n```\n\n## Simple Data Messages\nYou can and should create your own data messages. Teleport supplies an API for common events in the lifetime of the message\nUse the `DeBox.Teleport.BaseTeleportMessage` class\n\n**Example**\n```\npublic class MyMessage : BaseTeleportMessage\n{\n    public Vector3 Position { get; private set; }\n    public override byte MsgTypeId { get { return TeleportMsgTypeIds.Highest + 1; } }\n\n    // Deserialization constructor\n    public MyMessage() {}\n\n    // Actual constructor\n    public MyMessage(Vector3 position)\n    {\n        Position = position;\n    }\n\n    public override void Serialize(DeBox.Teleport.Core.TeleportWriter writer)\n    {\n        base.Serialize(writer);\n\t// Write a compressed Vector3\n        writer.Write(Position, FloatCompressionTypeShort.Short_Two_Decimals);\n    }\n\n    public override void Deserialize(DeBox.Teleport.Core.TeleportReader reader)\n    {\n        base.Deserialize(reader);\n\t// Read a compressed Vector3\n        Position = reader.ReadVector3(FloatCompressionTypeShort.Short_Two_Decimals);\n    }\n\n    public override void OnArrivalToClient()\n    {\n        base.OnArrivalToClient();\n        Debug.Log(\"The sent position is \" + Position);\n        GameObject.FindObjectOfType\u003cActor\u003e().transform.position = Position;\n    } \n}\n```\n\n#### Registering messages\nOn the client\n```\nTeleportManager.Main.RegisterClientMessage\u003cMyMessage\u003e();\n```\nOn the server\n```\nTeleportManager.Main.RegisterClientMessage\u003cMyMessage\u003e();\n```\nOn both\n```\nTeleportManager.Main.RegisterTwoWayMessage\u003cMyMessage\u003e();\n```\n\n\n#### Message events\n* PreSendServer - Called before the server sends the message, use this for setup of the message\n* PreSendClient - Called beofer the client sends the message, use this for setup of the message\n* PostSendServer - Called after the server sent the message, use this for sending follow up messages or any clean-up actions\n* PostSendClient - Called after the client sent the message, use this for sending follow up messages or any clean-up actions\n* OnArrivalToClient - Called as soon as the client receives the message, after it was deserialized\n* OnArrivalToServer - Called as soon as the server receives the message, after it was deserialized\n\n#### Sending Messages Sever =\u003e Client\n1. To all clients\n```\nTeleportManager.Main.SendToAllClients(new MyMessage(Vector3.one));\n```\n2. To a specific client\n```\nTeleportManager.Main.SendToClient(clientId, new MyMessage(Vector3.one));\n```\n3. To multiple, specific clients\n```\nTeleportManager.Main.SendToClients(new MyMessage(Vector3.one), channelId: 0, clientIdsArray);\n```\n4. To all clients, except specific clients\n```\nTeleportManager.Main.SendToAllExcept(new MyMessage(Vector3.one), channelId: 0, clientIdsArray);\n```\n\n#### Sending Messages Client =\u003e Server\n```\nTeleportManager.Main.SendToServer(new MyMessage(Vector3.one), channelId: 0);\n```\n\n## Packet structure\n#### Packet structure overview\n##### 1. Fixed packet prefix (2 bits)\nThe fixed packet prefix is a fixed value that always prepends the packet header\nThis value is used by Teleport to identify where a packet may start in case of data consistency errors.\n\nFor example - If a packet arrived with a header error, there is no way to know where the next packet starts, so Teleport must search for the fixed prefix to understand where the next packet is. If it finds something that looks like a packet, but is now - we expect it to fail the CRC check and so Teleport will continue to search onward.\n\n##### 2. Channel Id (2 bits)\nThis is the channel id of the packet. Each channel may process the packet data differently so it is important for the system to know which channel should handle this packet\n\n##### 3. Data CRC (4 bits)\nThis is the CRC of the data. Teleport sums up the bytes of the data, modded by the number 15 (0b1111) - resulting in a 4 bit number.\n\n##### 4. Header CRC (4 bits) \nThe header of the packet is critical as it tells the system how long the packet is. If the packet header is damaged, Teleport may try to read an infinetly long packet.\nBecause the data CRC depends on reading the entire packet, we CRC the header separately in order to quickly check if we can receive the data, or immediately dispose this packet.\n\nThe header CRC is the sum of the bytes of the following items\n1. Fixed packet prefix\n2. Channel Id\n3. Data CRC\n4. Data Length (With the Header CRC bits set to zero)\n\n##### 5. Data Length (12 bits, trimmed ushort, max=4096)\nThis is the length of the data. It is a ushort trimmed to 1.5 bytes (12 bit). This results in a maximum of 4096 bytes (4K) per packet. This is sufficient enougth and even if it is not, this can be resolved by breaking down data to smaller packets at the channel level (See AggregatingTeleportChannel, not yet tested)\n\n##### 6. Actual data (Variable, according to value of Data Length)\nThis is the actual data of the packet. If the CRC mismatches we will dispose the data altogether\n\n### Illustration of the header structure\n```\nBYTE 1  +-+[] FIXED PACKET PREFIX (2 bits)\n        |  []\n        |\n        |  [] CHANNEL ID (2 bits)\n        |  []\n        |\n        |  [] DATA CRC (4 bits)\n        |  []\n        |  []\n        +-+[]\n\nBYTE 2  +-+[] HEADER CRC (4 bits)\n        |  []\n        |  []\n        |  []\n        |\n        |  [] DATA LENGTH (12 bits)\n        |  []\n        |  []\n        +-+[]\nBYTE 3  +-+[]\n        |  []\n        |  []\n        |  []\n        |  []\n        |  []\n        |  []\n        +-+[]\n```\n\n## Float compression\n\nTeleport hands out a simple way to compress your floats, Vector2, Vector3, Vector4 and Quaternions\n\n### Float to Short compression\nUse this to shorten 4 byte floats to 2 bytes\n\n#### FloatCompressionTypeShort.Short_One_Decimal\n```FloatCompressionTypeShort.Short_One_Decimals``` converts a float to a short with one decimal.\nGood for rough numbers that do not require too much accuracy, and can be large (4 digits.)\n\nFor example: ```4.12551f =\u003e 41 =\u003e 4.1```\n\nMinimum Value: -3276.8\nMaximum Value: 3276.7\n\n#### FloatCompressionTypeShort.Short_Two_Decimals\n```FloatCompressionTypeShort.Short_Two_Decimals``` converts a float to a short with two decimals\nThe resulting number can be a most three digits long before the decimal.\nFor example: ```4.12551f =\u003e 412 =\u003e 4.12```\n\nMinimum Value: -327.68\nMaximum Value: 327.67\n\n#### FloatCompressionTypeShort.Short_Three_Decimals\n```FloatCompressionTypeShort.Short_Three_Decimals``` converts a float to a short with three decimals.\nGood for Vectors that have at most the magnitude of 1; for example directions.\n\nFor example: ```4.12551f =\u003e 4125 =\u003e 4.1245```\n\nMinimum Value: -32.768\nMaximum Value: 32.767\n\n### Char compression\nUse char compression for really really small floats in order to trim 4 bytes to 1 byte\n\n#### FloatCompressionTypeChar.Char_One_Decimal\n```FloatCompressionTypeChar.Char_One_Decimal``` \n\nMinimum Value: -12.7\nMaximum Value: 12.8\n\n#### FloatCompressionTypeChar.Char_Two_Decimals\n```FloatCompressionTypeChar.Char_Two_Decimals``` \n\nGood for Vectors that have at most the magnitude of 1; for example directions.\n\nMinimum Value: -1.27\nMaximum Value: 1.28\n\n\n### Serializing with compression\n```\nwriter.Write(Position, FloatCompressionTypeShort.Short_Two_Decimals);\nwriter.Write(Rotation, FloatCompressionTypeShort.Short_Two_Decimals);\n```\n\n### Deserializing with compression\n```\nPosition = reader.ReadVector3(FloatCompressionTypeShort.Short_Two_Decimals);\nRotation = reader.ReadQuaternion(FloatCompressionTypeShort.Short_Two_Decimals);\n```\n\n\n## Per-client message serialization\nYou may serialize a message personally for each client\n\n1. Override GetDeliveryTarget\n\n1.1. return DeliveryTargetType.PerConnection\n\n2. Override SerializeForClient\n\n2.1. Make sure to return true for clients that should receive this message\n\n2.2. Make sure to return false for clients that should not receive this message\n\n3. Optionally override PreSendServerForClient\n\n3.1. Make sure to return true for clients that should receive this message\n\n3.2. Make sure to return false for clients that should not receive this message\n\n```\npublic class MyMessage : BaseTeleportMessage\n{\n    public Vector3 Position { get; private set; }\n    public override byte MsgTypeId { get { return TeleportMsgTypeIds.Highest + 1; } }\n\n    // Deserialization constructor\n    public MyMessage() {}\n\n    // Actual constructor\n    public MyMessage(Vector3 position)\n    {\n        Position = position;\n    }\n\n    public override DeliveryTargetType GetDeliveryTarget()\n    {\n        return DeliveryTargetType.PerConnection;\n    }\n\n    // We don't have to implement Serialize now that we are PerConnection\n    public override void Serialize(DeBox.Teleport.Core.TeleportWriter writer)\n    {\n        throw new Exception(\"Don't expect this to be called!\");\n    }\n\n    public override bool SerializeForClient(TeleportWriter writer, uint clientId)\n    {\n        // Only the second client\n        if (GameUtils.CanPlayerSeeObjects(clientId))\n        {\n            writer.Write(Position);\n            return true;\n        }\n        return false;\n    }\n\n    public override void Deserialize(TeleportReader reader)\n    {\n        Position = reader.ReadVector3();\n    }\n}\n```\n\n","funding_links":[],"categories":["Open Source Repositories","Multiplayer"],"sub_categories":["Networking"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebox-dev%2FTeleport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdebox-dev%2FTeleport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebox-dev%2FTeleport/lists"}