Properties

Owl uses the Comm module under the hood to abstract away networking entirely, you never touch a RemoteEvent or RemoteFunction instance directly. Three abstractions sit on top of it: Property, Signal and Client methods. This page covers Property; see Signals and Client Methods for the other two.

A Property, created with Owl.CreateProperty(initialValue), is persistent state the right tool any time the client needs to read a value at any moment, not just react to it changing: currency, level, game phase and so on.

Server side

Category Method Description
Global :Set(value) Sets the value for every player
:SetTop(value) Sets the global value without overwriting per-player overrides
:Get() Reads the global value
Targeted :SetFor(plr, value) Sets the value for one specific player
:SetForList({plrs}, value) Sets the value for a list of players
:SetFilter(fn, value) Sets the value for every player matching a condition
:GetFor(plr) Reads the value as seen by a given player (their override, or the global value)
Cleanup :ClearFor(plr) Removes a player's override, they fall back to the global value
:ClearFilter(fn) Removes overrides for every player matching a condition
-- > // Global value (every player)
self.Client.GamePhase:Set("Combat")
 
-- > // Per-player value
self.Client.TotalCoins:SetFor(player, 1000)
 
-- > // Value for a group of players
self.Client.TeamScore:SetFilter(function(plr)
    return plr.Team == Teams.Red
end, 42)

Client side

-- > // Instant read
local coins = self.CoinService.TotalCoins:Get()
 
-- > // Observation (fires immediately, then again on every change)
self.CoinService.TotalCoins:Observe(function(value)
    updateCoinLabel(value)
end)

:Get() is a one-off snapshot, use it when you need a value once, right now (validating something before an action, for instance). :Observe(fn) is what you want for anything driving a UI element: it fires immediately with whatever the value already is, then again every time it changes, so the label is never out of sync, this is the same distinction covered in Controllers.

Bandwidth: use :SetFor so each player only ever receives their own data (inventory, personal stats) and reserve :Set for genuinely global state shared by everyone (weather, game phase). Setting per-player values through :Set would replicate every player's private data to every other player.

Where to go next

  • Signals - for one-off events, as opposed to Property's persistent state.
  • Client Methods - for on-demand requests instead of continuous replication.
  • Services - where Owl.CreateProperty is declared, inside a Service's Client table.