Networking¶
Vanguard converts service Client definitions into Roblox remotes and builds typed-feeling client proxy objects around them. The network layer supports request/response functions, reliable and unreliable signals, server-owned properties, and server-owned replicated state trees.
All client-to-server traffic passes through the configured Network Security pipeline before service code receives it.
Remote Definition Table¶
local MatchService = Vanguard.CreateService({
Name = "MatchService",
Client = {
GetMatch = function(self, player)
return self.Server:GetMatchFor(player)
end,
ReadyChanged = Vanguard.CreateSignal(),
AimUpdated = Vanguard.CreateUnreliableSignal(),
State = Vanguard.CreateProperty("Waiting"),
Snapshot = Vanguard.CreateReplicator({
Phase = "Waiting",
Score = { Red = 0, Blue = 0 },
}),
},
})
Supported Client values:
| Definition value | Server runtime object | Client proxy object |
|---|---|---|
| Function | RemoteFunction callback |
Promise-returning or yielding method |
CreateSignal() |
Server RemoteSignal | Client RemoteSignal |
CreateUnreliableSignal() |
Server RemoteSignal | Client RemoteSignal |
CreateProperty(value) |
Server RemoteProperty | Client RemoteProperty |
CreateReplicator(value) |
Server Replicator | Client Replicator |
Unsupported values fail server startup with the service and key name. Framework failures include a stable code and a direct link to the Error Reference.
Remote Functions¶
Server Definition¶
Roblox supplies player as the first payload argument after self. The client cannot spoof this Player value.
The self object is a temporary context:
self.Serverreturns the owning server service;self.OtherRemotereads another member fromservice.Client;- assigning
self.Servererrors; - assigning other fields writes to
service.Client.
Errors thrown by the remote method propagate through RemoteFunction and reject the default client promise.
Client Call¶
local MatchService = Vanguard.GetService("MatchService")
MatchService:GetMatch():andThen(function(match)
print(match)
end):catch(function(err)
warn(err)
end)
Dot and colon calls are both accepted on generated service methods:
The proxy removes itself from the outgoing argument list when called with :.
Promise Mode¶
With ServicePromises = true, the default, client calls return a Vanguard Promise. Remote invocation happens inside the promise executor and errors reject it.
Yielding Mode¶
The calling thread yields until Roblox returns or throws. Use pcall when direct error handling is needed.
Remote Signals¶
Signals are bidirectional remote events.
Reliable Signal¶
Uses RemoteEvent.
Unreliable Signal¶
Vanguard attempts to create UnreliableRemoteEvent. On runtimes where that class is unavailable, it falls back to RemoteEvent.
Use unreliable signals for high-frequency, replaceable information such as aim direction or cosmetic motion. Do not use them for purchases, inventory mutations, or events that must arrive.
Server Receiving from a Client¶
function MatchService:VanguardStart()
self.Client.ReadyChanged:Connect(function(player, ready)
self:SetReady(player, ready)
end)
end
Server callbacks receive player, ...payload. The payload passes rate limiting, validation, authentication, and verification once before any connected listener runs.
Client Sending to the Server¶
Server Sending to Clients¶
self.Client.Updated:Fire(player, payload)
self.Client.Updated:FireFor(player, payload) -- Alias of Fire
self.Client.Updated:FireAll(payload)
self.Client.Updated:FireExcept(excludedPlayer, payload)
self.Client.Updated:FireWhere(function(candidate)
return candidate.Team == team
end, payload)
FireWhere evaluates the predicate for each current Player.
Client Receiving from the Server¶
Client callbacks receive only the server payload.
Shared Signal Methods¶
local connection = signal:Connect(callback)
local onceConnection = signal:Once(callback)
local values = table.pack(signal:Wait())
signal:Destroy()
Destroying a server RemoteSignal destroys its underlying remote Instance. Treat framework-owned remote objects as service-lifetime resources and normally leave destruction to framework teardown.
Remote Properties¶
Remote properties are server-owned values with an optional per-player override.
Definition¶
The initial value may be nil. Vanguard internally packs values so nil is preserved.
Server Set¶
Updates the global value, fires the change remote to every client, and fires the server-side Changed signal with nil, value.
Per-Player Override¶
The override applies only to that Player. The server-side Changed signal fires with player, value.
Clear Override¶
Removes the override and sends the current global value to that Player.
Per-player entries are removed automatically when Players leave.
Server Get¶
local globalValue = self.Client.State:Get()
local effectiveValue = self.Client.State:Get(player)
local sameValue = self.Client.State:GetFor(player)
When a Player has no override, Get(player) returns the global value.
Server Observe¶
local connection = self.Client.State:Observe(function(player, value)
if player == nil then
print("Global value changed", value)
else
print("Override changed", player, value)
end
end)
The returned value is an RBXScriptConnection.
Client Get¶
This invokes the server and passes through property network authentication and verification rules.
Client Observe¶
local subscription = MatchService.State:Observe(function(value)
print("Current or changed value", value)
end)
subscription:Disconnect()
Observe connects to future changes and starts an asynchronous fetch of the current value. Fetch failures are warned. The return value is a small object exposing Disconnect.
Dot and Colon Calls¶
Remote property methods are bound to their instances. Both forms work:
This applies to the server and client property methods exposed by Vanguard.
Replicators¶
Replicators are server-owned state trees for larger current-state payloads.
They are available in network protocol 2.
Definition¶
Server Updates¶
Server methods include Get, Set, SetPath, Patch, SetFor,
SetPathFor, PatchFor, ClearFor, and Observe.
Client Reads¶
local state = MatchService.State:Get()
local redScore = MatchService.State:Get("Score.Red")
local subscription = MatchService.State:ObservePath("Score.Red", function(value)
print(value)
end)
Client methods include Get, Observe, and ObservePath. The first Get or
observer hydration invokes the server and passes through normal network rules
with RemoteType = "Replicator".
Read Replicators for path syntax, per-player state, change payloads, and design guidance.
Service Proxy Construction¶
The first client GetService(name):
- waits for
_VanguardRemoteswithinRemoteTimeout; - checks the server network protocol;
- warns when server and client Vanguard package versions differ;
- waits for the named service folder;
- maps each child remote to a proxy member;
- caches and returns the proxy.
Later calls return the same proxy table.
Only services with at least one Client remote receive a server remote folder. Looking up a service with no client remotes from the client therefore times out and errors; such a service is intentionally server-only.
Protocol Information¶
On the server this immediately returns protocol and server version. On the client fields are populated when the remote container is first resolved.
Current network protocol: 2.
Protocol 2 is more than a version attribute: it defines the replicated
_VanguardRemotes hierarchy, service folders, function and signal call shapes,
property and replicator _Get and _Changed children, remote-kind metadata,
Roblox-supplied Player identity, guard timing, rejection transport, and client
discovery handshake.
Read the complete Network Protocols reference
for the wire contract, compatibility matrix, publication timeline, legacy
protocol 1, and rules for future protocol bumps.
Security Boundary¶
Roblox networking identifies the sending Player, but payload values remain attacker-controlled. Validate structure, authenticate server-owned session state, and verify action permissions for every sensitive inbound remote.
Continue with Network Security and Validator.