Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/MKSQD/Cube

Scalable high level network library for Unity
https://github.com/MKSQD/Cube

eventual-consistency networking replication udp unity3d

Last synced: about 1 month ago
JSON representation

Scalable high level network library for Unity

Lists

README

        

# Cube
Cube tries to do eventual consistency based object replication for [Unity](https://unity.com/) and nothing more.

Eventual consistency means unreliable packets only - inspired by [GDC Vault: I Shot You First! Gameplay Networking in Halo: Reach](http://www.gdcvault.com/play/1014345/I-Shot-You-First-Networking),
which makes it scalable, robust to bad network conditions and simple.

Apart from replication, basic features required by every network game are provided, such as low level network api abstraction, rpcs-as-method-calls via Cecil assembly patching and level loading.
In editor, single instance, client+server development is possible.

## State
Far from production ready. Networking is hard. The library works, it's simple, robust and hackable. But there are a lot of spots were it's far from good enough.
All patches, pull requests and feedback welcome.

## Getting Started
Clone the git repository into your **Assets** folder.

Put CubeClient and CubeServer components on 2 GameObjects in the scene.

## Replication
A **Replica** is replicated from the server to all clients. Replicas must always be instances of prefabs for Cube to be able to create client instances of them.

Create a new *GameObject* in the scene. Add the *Cube/Replica* component to mark it as an Replica.
Add the *Cube/ReplicaTransform* component to keep their transforms synchronized.

Then create a prefab *TestReplica* from it by dragging the GameObject into the project explorer. Delete the original instance.

Create a new script TestServerGame:
```C#
using Cube.Networking;
using Cube.Replication;
using Cube.Transport;
using UnityEngine;

public class TestServerGame : ServerGame {
public GameObject prefab;

protected override void OnNewIncomingConnection(Connection connection, BitStream bs) {
// Create a new ReplicaView for this Connection
var view = new GameObject("ReplicaView " + connection);
view.transform.parent = transform;

var rw = view.AddComponent();
rw.connection = connection;

server.replicaManager.AddReplicaView(rw);

// Instantiate some Replica
server.replicaManager.InstantiateReplica(prefab);
}
}
```
Replace the *ServerGame* component on the ServerGame scene GameObject. Assign TestReplica to it's prefab field.

A **ReplicaView** observes Replicas for a connection. Its position and settings is used to scope and priorize which Replicas to send. Without a ReplicaView the client will not receive any Replicas.

Start the game now and you should see the Replica prefab being replicated. Try to move around the server-side instance in the editor.

For the client to instantiate a different prefab, rename your prefab to *Server_TestReplica*
and create a new prefab variant *Client_TestReplica* (The name prefixes **Server_** and **Client_** are important).

#### ReplicaBehaviour instead of MonoBehaviour
ReplicaBehaviour derives from MonoBehaviour and is used to implement multiplayer related functionaly on a Replica.
The server/client members can be used to access the Cube instance the Replica is part of. Rpcs are only available for ReplicaBehaviours.

```C#
using Cube.Replication;
using UnityEngine;

public class Test : ReplicaBehaviour {
void DoTest() {
if (!isServer)
return;

RpcTest();
}

[ReplicaRpc(RpcTarget.Client)]
void RpcTest() {
Debug.Log("Client rpc called");
}
}
```

#### Replica ownership
Each Replica has an owning (Replica.owner) connection. Assign ownership with **Replica.AssignOwnership** and take it away with **Replica.TakeOwnership**. Only the server can set and remove ownership. Ownership information is sent to the owning client.

### ReplicaRpc
ReplicaBehaviours can send **unreliable** rpcs. Rpcs are prioritized aggressively, so never rely on these to transmit actual gameplay state. Instead, these should be used for additional, optional effects and cues.

Rpcs can only be private functions with an \[ReplicaRpc(...)] attribute and its name starting with Rpc.

```C#
using Cube.Replication;
using UnityEngine;

public class TestReplica : ReplicaBehaviour {
void Update() {
if (!isServer)
return;

RpcTest();
}

[ReplicaRpc(RpcTarget.Client)]
void RpcTest() {
Debug.Log("Client rpc called");
}
}
```