Search Results for

    Show / Hide Table of Contents

    Standalone Networking

    Note that implementing a custom networking solution is advanced, and for most use cases, utilizing an existing networking framework integration will work perfectly.

    At the lowest level, to implement custom networking using KMPE, use the various send methods and KaijuMultiplayerManager.Receive(ref byte[], out ulong, out int, out bool, int) on the KaijuMultiplayerManager component:

    • KaijuMultiplayerManager.SendSelf(byte[], int, int, bool, bool, bool)
    • KaijuMultiplayerManager.SendSelf(IList<byte[]>, int[], int, bool, bool, bool)
    • KaijuMultiplayerManager.SendOwner(byte[], int, int, bool, bool, bool)
    • KaijuMultiplayerManager.SendOwner(IList<byte[]>, int[], int, bool, bool, bool)
    • KaijuMultiplayerManager.Send(UInt64, byte[], int, int, bool, bool, bool)
    • KaijuMultiplayerManager.Send(ulong, IList<byte[]>, int[], int, bool, bool, bool)
    • KaijuMultiplayerManager.Send(byte[], int, int, bool, bool, bool, bool, ulong[], ISet<ulong>)
    • KaijuMultiplayerManager.Send(IList<byte[]>, int[], int, bool, bool, bool, bool, ulong[], ISet<ulong>)

    The above methods have the following properties for reliable and unreliable methods:

    • Reliable messages are guaranteed to arrive exactly once to a user.
    • Reliable messages sent over a channel are guaranteed to arrive in the same order they were sent. However, there is no guarantee for the order across multiple channels.
      • For example if packet A is sent over channel 0, packet B over channel 0, and packet C over channel 1 to the same user in that order, packet A is guaranteed to arrive before packet B as they are both on the same channel, but packet C may arrive before either or both of them as it was sent on a different channel.
    • Unreliable messages have no guarantees: they may arrive out of order, never at all, or potentially the same packet may arrive multiple times.

    Synchronization

    KMPE provides methods to pack and unpack over the network along with interpolation to smooth values sent between players. Compared to traditional Unity networking libraries such as those integrated with KMPE, these methods are purely code-based, and no components, such as a NetworkTransform, are provided. This is because KMPE makes no assumptions about what you wish to send over the network, allowing for highly efficient low-level networking control with the ease-of-use of common networking features like interpolation.

    To see and example of packing, unpacking, and interpolation, see the sample.

    Packing and Unpacking

    To make custom networking development easier, the KaijuPacker class provides methods to easily pack and unpack packets being sent over the network. There are several general ways to encode all data types:

    1. Standard: This will encode the exact value into a byte array.
    2. Half: All methods with the name Half in them will compress all floating-point variables in half, and the same applies for compund structs built using them like vectors. This will result in a loss of precision, which can become more apparent the further from the origin the player is, so you will need to see if the precision loss is acceptable compared to the network bandwidth you are saving.
    3. Bounded: All methods with the name Bounded in them compress data to the same level as those with Half in their name, but maintain a higher precision by scaling and unscaling the data during the packing and unpacking processes. These methods can be useful if you for instance know the size of a level, and thus are confident players will never go beyond say [-1000, 1000] on any axes.

    There are additional methods dedicated towards quaternion synchronization, useful for if you are synchronizing the entire rotation of objects:

    1. Compressed: Due to the nature of quaternions, these methods compress and uncompress quaternions down to twelve bytes from their usual sixteen with minimal to no loss in precision.
    2. Aggressive: This compression methods reduce the size of quaternions from sixteen bytes down to two with a loss in precision that is typically acceptable.

    Interpolation

    If you are making a standalone networking solution using KMPE, you are free to send data over the network however you want. However, a common practice is to implement a tick-based system into your game, allowing players to synchronize packets between each other which may have arrived out of order to allow for smooth movement. This is what the KaijuInterpolator class does, allowing you to smooth packets between players and even extrapolate them into the future. To utilize it one, you must provide it:

    1. A function to smooth the data and optionally extrapolate into the future.
    2. How long in seconds to interpolate.
    3. How long in seconds to extrapolate movement into the future.

    Then, whenever you receive data for a given KaijuInterpolator over the network, you must call its Add(T, uint, uint) method which takes in the new data, the tick the other player sent it at on their machine, and the local tick of the player who is receiving this data. Then, when you wish to use this data, such as wihtin an Update() loop to update positions, you call the Get(uint) method.

    These "ticks" on players are typically updated at a certain timestep, and the most common method of transmitting a tick to all other players is to simply insert the tick at the start of every message you send. To help with incrementing these ticks, the KaijuTicker class is provided. There are two concrete implementations provided as well:

    1. KaijuTickerRate - Updates at a user-defined tick rate. In most instances, this is the best option to use.
    2. KaijuTickerPhysics - Ticks every physics step, meaning every FixedUpdate(). Unless you are sure your game will not slow down its physics simulations during intensive situations, it is recommended to use the KaijuTickerRate instead.

    To use these methods, you can simply access the Tick property to get your own tick during sending and receiving. Additionally, if you want to send only once a tick, you can listen for OnTick callback.

    Disable

    If you are using a different networking integration in your project, you can disable KMPE's synchronization system by setting the DISABLE_KAIJU_SYNC preprocessor directives in your project. This will strip all code releated to KMPE's synchronization system. You can do this by going to Tools > Kaiju Solutions > Multiplayer Engine > Features > Synchronization > Disable from the top menu, or manually adding or removing it from the preprocessor directives by going to Edit > Project Settings from the top menu, selecting Player, and scrolling down to Scripting Define Symbols.

    Sample

    To access the sample, open the package manager window by going to Window > Package Management > Package Manager. In the In Project tab, click on Kaiju Multiplayer Engine and click the Samples tab. First, import the Common sample followed by the Standalone sample where the scene Kaiju Multiplayer Engine - Standalone.unity can be found. If you ever need to reset your same scene, from the top menu, go to Tools > Kaiju Solutions > Multiplayer Engine > Samples > Standalone to generate the sample scene again.

    The sample utilizes packing and interpoliation for player positions, unless the sychronization features have been disabled entirely, in which case raw positions are sent and recieved directly over the network.

    This sample is the same as the downloadable demo game. This demo is available for Windows. As this uses a placeholder app ID for Steam, certain features such as the invite overlay will not function.

    Note that in the Unity editor, the assembly definition of this sample is not automatically referenced. This is intentional as in most cases, referencing a script from a sample in your project's actual code would likely be a mistake, and this provides an extra layer to avoid that. If you wish to directly use a script from a sample directly in your project, you must do one of the following:

    1. If your project's code is not within its own assembly definition, select the assembly definition file in the imported sample and enable the Auto Referenced field. Lastly, scroll down and click Apply.
    2. If your project's code is within its own assembly definition, select your project's assembly definition file and add the sample's assembly definition file to the Assembly Definition References field. Lastly, scroll down and click Apply.

    Resources

    If you wish to learn more about implementing a custom networking solution, Valve has some great resources, and Gabriel Gambetta has great articles as well.

    Testing

    To test your game's multiplayer functionality locally, check out the testing documentation.

    In This Article
    Back to top © 2025-2026 Kaiju Solutions Inc.