LogoLogo
HomeOnline DashboardAPIDiscordForums
SDK 1.7 Preview
SDK 1.7 Preview
  • Welcome
  • Overview
    • Features
    • Roadmap
  • Getting started
    • Get the Unity SDK
    • Setup a project
      • 1. Scene setup
      • 2. Prefab setup
      • 3. Test your game locally
        • Local testing using builds
        • Local testing via Unity's Multiplayer Play Mode
        • Local testing via ParrelSync
      • 4. Test in the cloud
        • Deploy a Replication Server
        • Share builds
    • How to... ?
    • Single-player to multiplayer
    • Video tutorials
    • Samples and tutorials
      • Package samples
      • Sample Connection UIs
      • First Steps tutorial
        • 1. Basic syncing
          • 1.1 Animation parameters
          • 1.2 Sending commands
        • 2. Physics / Authority transfer
        • 3. Areas of interest
        • 4. Parenting entities
        • 5. Complex hierarchies
        • 6. Persistence
      • Campfire project
        • Game mechanics
        • Leveraging object pooling
        • Remote interactions: Chairs
        • Remote interactions: Trees
        • A unique object with complex state
        • Custom instantiation and destruction
        • Running a server-side NPC
        • Playing audio and particles
        • A simple text chat
      • Beginner's guide to networking
    • Troubleshooting
  • Manual
    • Unity Components
      • CoherenceSync
      • CoherenceBridge
      • CoherenceLiveQuery
      • CoherenceTagQuery
      • CoherenceGlobalQuery
      • CoherenceInput
      • CoherenceNode
      • PrefabSyncGroup
      • Order of execution
    • Networking state changes
      • Instantiate and Destroy Objects
      • Supported types
      • Messaging with Commands
      • Syncing child GameObjects
      • Animation
      • CoherenceSync references
      • [Sync] and [Command] Attributes
      • [OnValueSynced] Attribute
      • Creating your own syncable member
      • Custom Component Actions
      • Rigid Bodies
      • Interpolation
    • Authority
      • Authority transfer
      • Server-authoritative setup
    • Lifetime
      • Persistence
      • Uniqueness
      • Example: A global counter
    • Parenting network entities
      • Direct children CoherenceSyncs
      • Deeply-nested CoherenceSyncs
      • Nesting Prefabs at Edit time
    • Asset management
      • Instantiating from CoherenceSyncConfig
      • Instantiate via
      • Load via
    • Scene management
    • Multiple Connections within a Game Instance
    • Baking (code generation)
      • Conditional compilation
    • Replication Server
      • Rooms and Worlds
      • Replication Server API
    • Simulators (Servers)
      • Scripting: Client vs Simulator
      • Run local Simulators
      • World Simulators
      • Room Simulators
      • Advanced Simulator Authority
      • Simulator slugs
      • Build and Deploy
      • Command-line arguments
    • Client Connections
    • Optimization
      • Areas of Interest
      • Level of Detail (LOD)
      • Profiling
      • Simulation Frequency
    • Project Settings
    • Advanced topics
      • Big worlds
        • World Origin Shifting
        • Load balancing
      • Competitive games
        • Simulation Frame
        • Determinism, Prediction and Rollback
      • Team workflows
        • Version Control integration
        • Continuous Integration
      • Schema explained
        • Specification
        • Field settings
        • Archetypes
      • Code stripping
      • Replication Server CLI
      • Single-player gameplay
    • Scripting API
  • Hosting
    • Choosing where to host
    • coherence Cloud
      • Online Dashboard
      • Manage Worlds
      • Configure Rooms
      • Player Accounts
      • Game Services
        • Lobbies
        • Cloud Storage
        • Key-Value Store (Legacy)
      • APIs
        • Worlds
        • Rooms
        • Lobbies
        • Cloud Storage
        • Key-Value Store (Legacy)
    • Peer-to-peer
      • Implementing Client hosting
        • Steam Relay
        • Epic Online Services (EOS) Relay
        • Azure PlayFab Relay
  • Support
    • Release notes
    • Glossary
    • Unreal Engine support
    • WebGL support
    • ECS / DOTS support
    • Known issues
    • Upgrade guide
      • Upgrade 1.6 -> 1.7
      • Upgrade 1.5 -> 1.6
      • Upgrade 1.4 -> 1.5
      • Upgrade 1.3 -> 1.4
      • Upgrade 1.2 -> 1.3
      • Upgrade 1.1 -> 1.2
      • Upgrade 1.0 -> 1.1
      • Upgrade 0.10 -> 1.0
      • Upgrade 0.9 -> 0.10
    • Credit cost & pricing
    • Report a bug
Powered by GitBook
On this page
  • In this scene
  • How it's set up
  • Simulating lifetime without a Simulator
  • Destroying other Clients' flowers

Was this helpful?

Export as PDF
  1. Getting started
  2. Samples and tutorials
  3. First Steps tutorial

6. Persistence

Was this helpful?

We have seen a lot of examples where objects belonging to a Client would disappear with them when they disconnect. We call these objects session-based entities.

But coherence also has a built-in system to make objects survive the disconnection of a Client, and be ready to be adopted by another Client or a Simulator. We call these objects persistent. Persistent objects stay on the Replication Server even if no Client is connected, creating the feeling that the game world is alive beyond an individual player session.

Persistence | Simulator | Requesting authority

  • WASD or Left stick: Move character

  • Hold Shift or Shoulder button left: Run

  • P or Right shoulder button: Plant a flower (hold to preview placement)

In this scene

Players can plant flowers in this little valley. Each flower has 3 phases: starts as a bud, blooms into a full flower, and then withers after some time.

Creating a flower generates a new, persistent network entity. Even if the Client disconnects, the flower will persist on the server. When they reconnect, they will see the flower at their correct stage of growth (this is a little trick we explain later).

Planting too many flowers starts erasing older flowers. A button in the UI allows clearing all flowers (belonging to any player) at any time.

How it's set up

When using the plant action, any connected player instantiates a copy of the Flower Prefab (located in the /Prefabs/Nature folder).

By selecting the Prefab asset, we can see its CoherenceSync component is set up like this:

In particular, notice how the Lifetime property is set to Persistent. This means that when the Client who plants a flower disconnects, the network entity won't be automatically destroyed. Auto-adopt Orphan set to on makes it so the next player who sees the flower instantly adopts it, and keeps simulating its growth.

Opening coherence's Configuration window, you will see that we sync position, rotation, and a variable called timePlanted:

When it gets instantiated, the flower writes the current UNIX timestamp into the timePlanted variable. This variable never changes after this, and is used to reconstruct the phase in which the flower is in (see below). Similarly, as the flower is not moving, position and rotation are only synced at the time of planting.

Once a flower has spawned, all of its logic runs locally (no coherence involved). An internal timer calculates what phase it should be in by looking at the timePlanted property and doing the math, and playing the appropriate animations and particles as a result.

Simulating lifetime without a Simulator

coherence supports the ability to have an instance of the game active in the cloud, running some logic all the time (we call this a Simulator). However, this might be an expensive setup, and it's good advice to think things through differently to keep the cost of running your game lower.

To achieve this, the flowers of this scene store the Flower.timePlanted value on the Replication Server. A Replication Server with no connected Clients is dormant, and has a very low cost to run. So when nobody's connected the flowers are not actually simulating, they are just waiting.

When a new Client comes online and this value is synced to them, they immediately fast-forward the phase of the flower to the correct value, and then they start simulating locally as normal.

This gives the players the perception that things are still running even when they are not connected.

This setup is not bulletproof, and could be easily cheated if a player comes online with a modified Client, changing the algorithm calculating the flowers' phase.

But for a game in which this calculation is not critical, especially if it doesn't affect other player's experience of the game, this can be a nice setup to cut some costs.

Destroying other Clients' flowers

Every Client can, at any time, remove all flowers from the scene by clicking a button in the UI.

It's important to remember that you shouldn't call Destroy() on a network entity on which the Client doesn't have authority on. To achieve this, we first request authority on remote flowers and listen for a reply. Once obtained it, we destroy them.

Check the code at the end of the Flower script:

// Flower.cs
public void DestroyRemote()
{
    _sync = GetComponent<CoherenceSync>();
    _sync.OnStateAuthority.AddListener(DestroyThis);
    _sync.RequestAuthority(AuthorityType.Full);
}

private void DestroyThis()
{
    _sync.OnStateAuthority.RemoveListener(DestroyThis);
    Destroy(gameObject, .1f);
}

As we discussed in the Physics lesson, switching authority is a network operation that is asynchronous, so we need to wait for the reply from the player who currently has authority.

A player about to plant a new flower, surrounded by flowers in different stages.
The Flower Prefab's CoherenceSync.
The setup of the Flower Prefab.
The button to clear the flowers.