Skip to main content

Built-in network components

TSMP includes several TSMPNetworkBehaviour components that cover common VRChat world synchronization cases. They all share networkId, receive interpolation, active-state checks, and setup binding.

Common behaviour​

FeatureMeaning
networkIdStable ID used to match sender and receiver components.
receiveInterpolationNone, Discrete, or Continuous received-value handling.
Active stateDisabled components or inactive GameObjects do not participate.
TSMPBeforeEncode()Captures component state before the encoder reads [TransSync] fields.
OnTSMPVariableReceived()Applies decoded state after a frame is received.

Component overview​

ComponentWhat it synchronizes
TSMPNetworkTransformSyncTransform position, rotation, scale, compression range, and optional Rigidbody state.
TSMPNetworkHumanoidPoseSyncSelected humanoid bones plus root motion position.
TSMPNetworkBlendShapesSyncSelected blendshape weights for one SkinnedMeshRenderer.
TSMPNetworkVrchatAvatarPoseSyncVRChat player tracking pose for avatar-pool playback.
TSMPNetworkAnimatorSyncAnimator parameters and layer-related state supported by the runtime path.
TSMPNetworkTimelineSyncPlayableDirector timeline time/play state where supported by Udon.
TSMPNetworkGameObjectToggleToggle event through TSMP RPC.
TSMPDebugCanvasText UI for frame counters, bitrate, loss, and header metadata.

Timeline controls​

TSMPNetworkTimelineSync exposes four parameterless methods, also callable as Udon custom events:

MethodEffect
Play()Starts the assigned Director and records Playing.
Pause()Pauses a playing Director, including at time zero. Does not create a graph when already stopped.
Resume()Resumes paused playback, or starts a stopped Director. Like Play, does not restart an already playing Director.
Stop()Stops the assigned Director and records Stopped.

Seek(float time) evaluates the requested time without changing Playing or Paused state. From Stopped, it prepares a paused graph. Non-looping timelines clamp to their local duration; looping timelines wrap. Negative, NaN and infinite arguments are ignored. Call Seek from a script with its argument, not as a parameterless custom event. Explicit control calls cancel pending receive corrections; the next valid received packet can take control again.

The timeline.packed field keeps the v1 format: version byte, state byte (0 Stopped, 1 Paused, 2 Playing), Float32 seconds and Float32 duration, both little-endian. It is exactly 10 bytes. Invalid lengths, versions, states, non-finite/negative times or durations, and times beyond the transmitted duration are rejected before playback changes. Warnings are limited to once per second and 16 per enable cycle. Missing or disabled sources clear the captured payload and encodedTimelineBytes rather than retransmitting an old sample. In native Unity, a missing Timeline asset also clears capture.

These calls control local playback; the Encoder transmits the resulting state on its next capture. Native Unity reads director.state and graph validity, including changes made by other scripts. Udon tracks the commands instead: route playback commands through this component and issue an explicit end-of-sequence command. Udon cannot reliably observe external Director commands or automatic completion. Replacing the Director resets tracked state from its playOnAwake setting.

Choosing a component​

Use built-in components when the data model matches your object. Write a custom TSMPNetworkBehaviour when:

  • You need a different packed byte format.
  • You need to synchronize several fields as one packet.
  • You need a custom receive interpolation policy.
  • You need to run logic from a TSMP RPC.

Binding rule​

After adding or removing network components, run Apply Setup. The encoder and decoder do not discover fields every frame in runtime worlds; setup creates explicit binding tables for performance and Udon compatibility.