Network Dormancy
Overview
In this tutorial, you will learn how to manually replicate network objects that can make your games more performant and utilize more networked behavior. You will be changing material colors on an object, and forcing the replication to other clients who will receive the changes.
Disabling a networked object's replication means that the server will not be checking to see if the object has changed, and will not send any new information about that object down to clients, until either the object has replication enabled again, or until you explicitly request the server replicate the object down to each client with a Lua function.
- Completion Time: ~20 minutes
- Knowledge Level: No previous knowledge.
- Skills you will learn:
- How to set a networked object to dormant by default.
- How to force replication with Lua.
- How to change object dormancy using Lua.
Add Objects and set Dormancy
We will need a few objects added to the Hierarchy that will be used to help show off how dormancy works.
Create Volleyball Object
- In Core Content search for
Volleyball
to find the object Ball - Volleyball 01. - Add the volleyball to the Hierarchy and name it
Volleyball
. - Right-click on the volleyball object in the Hierarchy and select Enable Networking.
Create Volleyball Clone Object
Create a copy of the Volleyball object that will be a clone. Any changes made to the other Volleyball will carry over to this object periodically to show when replication has been enabled or disabled.
- In Core Content search for
Volleyball
to find the object Ball - Volleyball 01. - Add the volleyball to the Hierarchy and name it
Volleyball Clone
. - Right-click on the Volleyball Clone object in the Hierarchy and select Enable Networking.
- With the Volleyball Clone selected, in the Properties window enable the Advanced Settings option.
- In the Properties window for the Volleyball Clone object, disable the option Start Replicating under the Network Relevance group.
With the option Start Replicating disabled, the object will only use network bandwidth when it is created, and when replication is forced by using a Lua function.
Create UI Crosshair
To see where you are clicking on an object, you will create some UI to have a crosshair show up.
- Create a Client Context in the Hierarchy.
- Add a UI Container to the Client Context.
- Add a UI Image to the UI Container and set the Anchor and Dock to Middle Center.
- Find a crosshair image for the UI Image.
Create ChangeColorClient Script
Create a new script called ChangeColorClient
and place it into the Client Context folder. This script will check when certain action bindings have been pressed and modify the slot color of the material that was returned by the raycast hit.
Create OnActionPressed Function
Create a function called OnActionPressed
. This function will receive the player who triggered the action and the action name. By dividing the screen size for x
and y
by 2, we get the center position of the screen where the crosshair will be pointing. Using GetHitResult
with the Vector2 passed in, we can check if we have a hit
and check if the object other
is networked.
Left-clicking will set a random color for the material slot returned, and right-clicking will reset the color of the material slot.
A broadcast to the server is done that will send the object reference, the slot name, and the color.
local function OnActionPressed(player, action)
if action == "Shoot" or action == "Aim" then
local screenSize = UI.GetScreenSize()
local hit = UI.GetHitResult(Vector2.New(screenSize.x / 2, screenSize.y / 2))
if hit ~= nil and hit.other.isNetworked then
local materialSlot = hit:GetMaterialSlot()
if materialSlot ~= nil then
local color = nil
if action == "Shoot" then
color = Color.New(math.random(0, 1), math.random(0, 1), math.random(0, 1))
end
Events.BroadcastToServer("ChangeColor", hit.other:GetReference(), materialSlot.slotName, color)
end
end
end
end
Connect actionPressedEvent
Connect the actionPressedEvent
which calls the connected function OnActionPressed
when the player presses a binding.
Input.actionPressedEvent:Connect(OnActionPressed)
The ChangeColorClient Script
ChangeColorClient
local function OnActionPressed(player, action)
if action == "Shoot" or action == "Aim" then
local screenSize = UI.GetScreenSize()
local hit = UI.GetHitResult(Vector2.New(screenSize.x / 2, screenSize.y / 2))
if hit ~= nil and hit.other.isNetworked then
local materialSlot = hit:GetMaterialSlot()
if materialSlot ~= nil then
local color = nil
if action == "Shoot" then
color = Color.New(math.random(0, 1), math.random(0, 1), math.random(0, 1))
end
Events.BroadcastToServer("ChangeColor", hit.other:GetReference(), materialSlot.slotName, color)
end
end
end
end
Input.actionPressedEvent:Connect(OnActionPressed)
Create ChangeColorServer Script
Create a Server Context folder and create a new script called ChangeColorServer
and put that inside the Server Context folder. This script will be responsible for handling the color change, and the replication to all clients to receive the updated colors.
Add Custom Property
The ChangeColorServer
script will need a reference to the Volleyball Clone so that it can update the colors periodically.
- Add the Volleyball Clone object as a custom property on the ChangeColorServer script.
- Name the property
VolleyballClone
.
Edit ChangeColorServer Script
Open up the ChangeColorServer script and add the reference to the custom property and a variable called setReplication
that will keep track of the state of the dormancy for the object.
local VOLLEYBALL_CLONE = script:GetCustomProperty("VolleyballClone"):WaitForObject()
local setReplication = true
Create ChangeColor Function
Create a function called ChangeColor
. This function will receive the object reference, material slot name, and the color the material slot will be changed to.
If the color
is nil
then the material slot will be reset using the ResetColor
function.
The color of the material slot for the VOLLEYBALL_CLONE
is also set so it matches the object being replicated. When the ChangeColor
function is called, at the end after the changes have been done to the obj
, a call to ForceReplication
is done. This will send the changes on the obj
to all clients. This is efficient because you are in control of when replication happens, and how often it happens.
local function ChangeColor(objRef, materialSlot, color)
local obj = objRef:GetObject()
if color ~= nil then
obj:GetMaterialSlot(materialSlot):SetColor(color)
else
obj:GetMaterialSlot(materialSlot):ResetColor()
end
VOLLEYBALL_CLONE:GetMaterialSlot(materialSlot):SetColor(obj:GetMaterialSlot(materialSlot):GetColor())
obj:ForceReplication()
end
Create Task
Create a task that will update the dormancy of the VOLLEYBALL_CLONE
every 3 seconds. By passing either true
or false
to the SetReplicationEnabled
function, the object with either replicate normally or not replicate at all. The setReplication
variable will be flipped each time so that every 3 seconds it changes the dormancy state.
local task = Task.Spawn(function()
VOLLEYBALL_CLONE:SetReplicationEnabled(not setReplication)
setReplication = not setReplication
end, 3)
task.repeatCount = -1
task.repeatInterval = 3
Connect Event
Connect the ChangeColor
event that is broadcasted to the server from the client.
Events.Connect("ChangeColor", ChangeColor)
The ChangeColorServer Script
ChangeColorServer
local VOLLEYBALL_CLONE = script:GetCustomProperty("VolleyballClone"):WaitForObject()
local setReplication = true
local function ChangeColor(objRef, materialSlot, color)
local obj = objRef:GetObject()
if color ~= nil then
obj:GetMaterialSlot(materialSlot):SetColor(color)
else
obj:GetMaterialSlot(materialSlot):ResetColor()
end
VOLLEYBALL_CLONE:GetMaterialSlot(materialSlot):SetColor(obj:GetMaterialSlot(materialSlot):GetColor())
obj:ForceReplication()
end
local task = Task.Spawn(function()
VOLLEYBALL_CLONE:SetReplicationEnabled(not setReplication)
setReplication = not setReplication
end, 3)
task.repeatCount = -1
task.repeatInterval = 3
Events.Connect("ChangeColor", ChangeColor)
Test the Game
Testing network dormancy needs to be done in multiplayer preview. Load multiplayer preview with 2 clients and test clicking on the volleyball and watch as the colors change. You will notice the volleyball clone will change, but after 3 seconds it will stop receiving updates, and then start receiving again.
Summary
Having the ability to change how frequently objects are replicated in your game can greatly improve performance. Updating objects only when they need to be updated allows for a more relaxed approach to networked objects that are dormant.
Learn More
Networking | Network Relevancy