Skip to content

RemoteEvent

Sends one-way messages between the game server and players’ devices.

  • Inherits: Instance
  • Creatable: Yes: new RemoteEvent(), or Instance.new('RemoteEvent', parent).
  • Replication: Replicated: clients get a copy, and changes the server makes reach them.

Put RemoteEvents somewhere both sides can see, usually ReplicatedStorage, and create them in Rally Studio so they exist before any script runs. A player’s device sends with fireServer; the server sends with fireClient (one player) or fireAllClients (every player who can see the remote).

The server receives the sending player as the first argument, added by Rally. Treat every message from a player as untrusted: check the arguments’ types and ranges, check that the action is allowed right now, and limit how often each player may do it.

What crosses the network: JSON values (numbers, strings, booleans, null, arrays, plain objects), Vector3, Vector2, Color3 and instance references, which arrive as the same instance on the other side, or as null if the receiver can’t see it. Functions and undefined arrive as null, NaN and infinite numbers as null, other objects as plain objects of their own properties, and object keys that start with $ are dropped. Arguments may nest 12 levels deep and hold 5,000 values in total (more throws a RangeError on the sending side); strings longer than 50,000 characters are cut. Each player can send 60 remote calls a second; more are dropped. See Limits.

Inherited from Instance: name, archivable, id, className, parent, destroyed

fireServer(...args: unknown[]): void

Client → server.

Only works on a player’s device.

fireClient(player: Player, ...args: unknown[]): void

Server → one client.

Only works on the server. If the player can’t see the remote (it’s in ServerStorage, say), nothing is sent and a warning goes to the game’s output.

fireAllClients(...args: unknown[]): void

Server → every client.

Only works on the server. Players who can’t see the remote get nothing.

Inherited from Instance: getPropertyChangedSignal, setAttribute, getAttribute, getAttributes, getAttributeChangedSignal, getChildren, getDescendants, findFirstChild, findFirstChildOfClass, findFirstChildWhichIsA, findFirstAncestor, findFirstAncestorWhichIsA, waitForChild, isA, isDescendantOf, isAncestorOf, getFullName, clearAllChildren, destroy, clone, toString

Arguments: player: Player, ...args: unknown[]

Server: fires with the sending player first.

Arguments: ...args: unknown[]

Client: fires with what the server sent.

Inherited from Instance: changed, childAdded, childRemoved, descendantAdded, descendantRemoving, ancestryChanged, destroying, attributeChanged

import { RemoteEvent, ReplicatedStorage, UserInputService, getChild } from '@rally/sdk';
// LocalScript: ask the server to cheer when the player presses C.
const cheer = getChild(ReplicatedStorage, 'Cheer', RemoteEvent);
UserInputService.inputBegan.connect((input, gameProcessed) => {
if (!gameProcessed && input.key === 'KeyC') cheer.fireServer('Go team!');
});
import { Player, RemoteEvent, ReplicatedStorage, getChild, task } from '@rally/sdk';
// Script: check the message, rate-limit it, then tell everyone.
const cheer = getChild(ReplicatedStorage, 'Cheer', RemoteEvent);
const last = new Map<Player, number>();
cheer.onServerEvent.connect((player, text) => {
if (typeof text !== 'string' || text.length > 40) return;
if (task.time() - (last.get(player) ?? -Infinity) < 2) return; // one cheer every 2 seconds
last.set(player, task.time());
cheer.fireAllClients(`${player.displayName}: ${text}`);
});