Table of Contents

Class KCCPlatform

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Predicted moving platform on FishNet's own model: every peer runs the same autonomous, deterministic replicate, the server reconciles it to every observer, and FishNet rolls it back and replays it with everything else. Riders inherit its per-tick velocity through KCCPlayer.

public class KCCPlatform : TickNetworkBehaviour, ISceneObject
Inheritance
Object
Component
Behaviour
MonoBehaviour
NetworkBehaviour
TickNetworkBehaviour
KCCPlatform
Implements
Inherited Members
TickNetworkBehaviour.SetTickCallbacks(TickNetworkBehaviour.TickCallback)
TickNetworkBehaviour.TimeManager_OnPreTick()
TickNetworkBehaviour.TimeManager_OnPostTick()
TickNetworkBehaviour.TimeManager_OnUpdate()
TickNetworkBehaviour.TimeManager_OnLateUpdate()
NetworkBehaviour.IsSpawned
NetworkBehaviour.ComponentIndex
NetworkBehaviour.NetworkObject
NetworkBehaviour.MAXIMUM_NETWORKBEHAVIOURS
NetworkBehaviour.UNSET_NETWORKBEHAVIOUR_ID
NetworkBehaviour.ToString()
NetworkBehaviour.Reset()
NetworkBehaviour.OnValidate()
NetworkBehaviour.IsBehaviourReconciling
NetworkBehaviour.ClearReplicateCache()
NetworkBehaviour.Reconcile_Reader<T>(PooledReader, ref T)
NetworkBehaviour.OnStartServerCalled
NetworkBehaviour.OnStartClientCalled
NetworkBehaviour.OnStopNetwork()
NetworkBehaviour.OnStartServer()
NetworkBehaviour.OnStopServer()
NetworkBehaviour.OnOwnershipServer(NetworkConnection)
NetworkBehaviour.OnSpawnServer(NetworkConnection)
NetworkBehaviour.OnDespawnServer(NetworkConnection)
NetworkBehaviour.OnStartClient()
NetworkBehaviour.OnStopClient()
NetworkBehaviour.OnOwnershipClient(NetworkConnection)
NetworkBehaviour.ClearBuffedRpcs()
NetworkBehaviour.ExcludeOwnerFromUnbufferedObserversRpcs
NetworkBehaviour.IsClientOnly
NetworkBehaviour.IsServerOnly
NetworkBehaviour.IsHost
NetworkBehaviour.IsClient
NetworkBehaviour.IsServer
NetworkBehaviour.IsDeinitializing
NetworkBehaviour.NetworkManager
NetworkBehaviour.ServerManager
NetworkBehaviour.ClientManager
NetworkBehaviour.ObserverManager
NetworkBehaviour.TransportManager
NetworkBehaviour.TimeManager
NetworkBehaviour.SceneManager
NetworkBehaviour.PredictionManager
NetworkBehaviour.RollbackManager
NetworkBehaviour.NetworkObserver
NetworkBehaviour.IsClientInitialized
NetworkBehaviour.IsClientStarted
NetworkBehaviour.IsClientOnlyInitialized
NetworkBehaviour.IsClientOnlyStarted
NetworkBehaviour.IsServerInitialized
NetworkBehaviour.IsServerStarted
NetworkBehaviour.IsServerOnlyInitialized
NetworkBehaviour.IsServerOnlyStarted
NetworkBehaviour.IsHostInitialized
NetworkBehaviour.IsHostStarted
NetworkBehaviour.IsOffline
NetworkBehaviour.IsNetworked
NetworkBehaviour.GetIsNetworked()
NetworkBehaviour.IsManagerReconciling
NetworkBehaviour.Observers
NetworkBehaviour.IsOwner
NetworkBehaviour.IsController
NetworkBehaviour.HasAuthority
NetworkBehaviour.Owner
NetworkBehaviour.OwnerId
NetworkBehaviour.ObjectId
NetworkBehaviour.LocalConnection
NetworkBehaviour.OwnerMatches(NetworkConnection)
NetworkBehaviour.Despawn(GameObject, DespawnType?)
NetworkBehaviour.Despawn(NetworkObject, DespawnType?)
NetworkBehaviour.Despawn(DespawnType?)
NetworkBehaviour.Spawn(GameObject, NetworkConnection, Scene)
NetworkBehaviour.Spawn(NetworkObject, NetworkConnection, Scene)
NetworkBehaviour.RemoveOwnership()
NetworkBehaviour.GiveOwnership(NetworkConnection)
NetworkBehaviour.GetInstance<T>()
NetworkBehaviour.TryRegisterInstance<T>(T)
NetworkBehaviour.UnregisterInstance<T>()
NetworkBehaviour.CanLog(LoggingType)
MonoBehaviour.IsInvoking()
MonoBehaviour.CancelInvoke()
MonoBehaviour.StopCoroutine(Coroutine)
MonoBehaviour.StopAllCoroutines()
MonoBehaviour.destroyCancellationToken
MonoBehaviour.useGUILayout
MonoBehaviour.didStart
MonoBehaviour.didAwake
MonoBehaviour.runInEditMode
Behaviour.enabled
Behaviour.isActiveAndEnabled
Component.GetComponent<T>()
Component.TryGetComponent<T>(out T)
Component.GetComponentInChildren<T>()
Component.GetComponentsInChildren<T>()
Component.GetComponentInParent<T>()
Component.GetComponentsInParent<T>()
Component.GetComponents<T>()
Component.GetComponentIndex()
Component.CompareTag(TagHandle)
Component.transform
Component.transformHandle
Component.gameObject
Component.tag
Object.GetEntityId()
Object.GetInstanceID()
Object.GetHashCode()
Object.InstantiateAsync<T>(T)
Object.InstantiateAsync<T>(T, Transform)
Object.InstantiateAsync<T>(T, Vector3, Quaternion)
Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion, Transform)
Object.Instantiate(Object)
Object.Instantiate(Object, Scene)
Object.Instantiate<T>(T, InstantiateParameters)
Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)
Object.Instantiate(Object, Transform)
Object.Instantiate<T>(T)
Object.Instantiate<T>(T, Vector3, Quaternion)
Object.Instantiate<T>(T, Vector3, Quaternion, Transform)
Object.Instantiate<T>(T, Transform)
Object.Destroy(Object)
Object.DestroyImmediate(Object)
Object.DontDestroyOnLoad(Object)
Object.DestroyObject(Object)
Object.FindObjectsOfType<T>()
Object.FindObjectsByType<T>(FindObjectsSortMode)
Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)
Object.FindObjectOfType<T>()
Object.FindFirstObjectByType<T>()
Object.FindAnyObjectByType<T>()
Object.FindFirstObjectByType<T>(FindObjectsInactive)
Object.FindAnyObjectByType<T>(FindObjectsInactive)
Object.FindObjectsByType<T>()
Object.FindObjectsByType<T>(FindObjectsInactive)
Object.name
Object.hideFlags

Remarks

A fork of FishNet's Demos/Prediction/CharacterController/MovingPlatform, and since issue #228 deliberately back ON that model. This platform's NetworkObject is the one kind of scene object in the project with state forwarding ENABLED (pinned by InterestManagementWiringTests.OnlyPlatforms_ShipWithStateForwardingOn), because the argument that keeps forwarding off everywhere else does not apply to it: forwarding a character relays every owner's INPUT to every observer, which is what makes 100-200 players unaffordable — an ownerless platform has no input. Its replicate is an empty struct, and the only wire cost is one delta-encoded reconcile (Vector3 + byte) per observer per tick.

What that buys, in the demo's own words: with the body run in EVERY replicate state, IsFuture included, a client's platform runs AHEAD of the server by that client's ping — where the platform will be by the time the client's input reaches the server — and every reconcile rolls the platform back to the server's state and replays it in lockstep with the rider, so a replayed ground probe meets the deck where it actually stood on that tick.

The previous model — forwarding off, each client stepping the platform itself from a one-shot spawn payload — had neither property. With forwarding off FishNet returns from Replicate_NonAuthoritative before invoking the body and sends no reconcile for an ownerless object, so the client copy was seeded from the payload and dead-reckoned open-loop for the rest of the session: seeded BEHIND the server (aligned to the interpolated observer frame ability objects use, the opposite of what a deck the owner stands on needs), and never rolled back, so a reconcile replay probed a deck up to a round trip downstream of where the rider stood. Riders sank through moving decks, worst at high ping, worst near the edges.

Properties

GameObject

The Unity GameObject associated with this scene object.

public GameObject GameObject { get; }

Property Value

GameObject

ID

Unique identifier for the scene object.

public long ID { get; set; }

Property Value

long

LastCompletedTickVelocity

Velocity of the platform during its most recently completed Step(float), in world units per second. Refreshed by every run of the replicate body — the live tick on both peers, and each replayed tick on a client — so it is the velocity of whatever tick the platform last simulated.

public Vector3 LastCompletedTickVelocity { get; }

Property Value

Vector3

Methods

CreateReconcile()

Override this method to create your reconcile data, and call your reconcile method.

public override void CreateReconcile()

OnStartNetwork()

Called when the network has initialized this object. May be called for server or client but will only be called once. When as host or server this method will run before OnStartServer. When as client only the method will run before OnStartClient.

public override void OnStartNetwork()

ReadPayload(NetworkConnection, Reader)

Called before network start callbacks, but after the object is initialized with network values. This may be used to read information from predicted spawning, or simply have values set before initialization without depending on SyncTypes.

public override void ReadPayload(NetworkConnection connection, Reader reader)

Parameters

connection NetworkConnection

Connection sending the payload. When coming from the server connection.IsValid will return false.

reader Reader

Remarks

A SEED, not a sync. A client arriving mid-cycle would otherwise draw the platform at its authored pose for the tick or two before its first reconcile lands; the reconcile is what places it, and every reconcile after that keeps it placed. The catch-up that used to live here (fast-forwarding the snapshot by its transit) is gone with the reason it existed — the payload is no longer the only word the client ever hears about this platform.

ResetState(bool)

Resets this NetworkBehaviour so that it may be added to an object pool.

public override void ResetState(bool asServer)

Parameters

asServer bool

TimeManager_OnTick()

protected override void TimeManager_OnTick()

Remarks

Identical on every peer, exactly as the FishNet demo has it. The server's call is authoritative and drives the reconcile; a client's routes through Replicate_NonAuthoritative, which — because this object forwards state — runs the body with the server's queued data when it has some and with default, IsFuture data when it does not. The body moves in either case, which is what puts the client's platform ahead of the server by its ping rather than behind it.

TryGetVelocityForTick(uint, out Vector3)

The velocity this platform produced on a specific tick, in the CLIENT tick domain.

public bool TryGetVelocityForTick(uint tick, out Vector3 velocity)

Parameters

tick uint

The tick to look up.

velocity Vector3

The velocity produced on that tick, when still held.

Returns

bool

True when the tick is still in the ring.

Remarks

FishNet promises no tick order across NetworkObjects, so a rider simulating tick T cannot know whether this platform has already stepped T or is still on T-1 when it asks for LastCompletedTickVelocity. The ring answers by tick instead, and is filled wherever the platform runs a tick on a client: from TimeManager_OnTick() keyed by LocalTick for the live tick, and from the replayed replicate keyed by PredictionManager.ClientReplayTick — both the same counter a rider's input carries.

The server fills it too, keyed by ITS local tick, but must not consult it with a rider's input tick: that tick is the owning client's unsynchronised counter, so the lookup is an arbitrary hit or a miss. The server never replays, and reads the live value instead.

WritePayload(NetworkConnection, Writer)

Called when writing a spawn. This may be used to deliver information for predicted spawning, or simply have values set before initialization without depending on SyncTypes.

public override void WritePayload(NetworkConnection connection, Writer writer)

Parameters

connection NetworkConnection

Connection receiving the payload. When sending to the server connection.IsValid will return false.

writer Writer