@rbxts/wired
v0.1.12
Published
Lightweight Remote Wrapper for Roblox
Downloads
75
Maintainers
Readme
Wired is a lightweight remote wrapper for Roblox
Wired abstracts roblox remotes for you to use them in Roblox-ts offering fully typed remotes you can use in your project!
Changelog 0.1.0
- Added
FakeFire(player)
for simulating a player firing a ClientEvent for testing purposes - Added
FakeCall(player)
for simulating a player calling a ServerAsync for testing purposes, returns what the server returned - Added
FakeFire()
for simulating the server firing a ServerEvent for testing purposes - Changed function name from
DefineRemotes()
toDeclareRemotes()
- Added
OnPrepared
signal
Declaring your remotes
First declare your remotes with const remotes = DeclareRemotes(name, declaration)
. You might want to export the returned value to be used somewhere else. It's important that the export is available for both Server and Client
import { DeclareRemotes } from "@rbxts/wired";
export const Remotes = DeclareRemotes("Remotes", {
//Your declarations here
});
const ServerRemotes = Remotes.Server;
const ClientRemotes = Remotes.Client;
We can define as much remotes as we want in different files. This can be useful for modularity, but, depending on your project, creating everything in the same file might be easier to manage
Constructing the Roblox instances
After we declared our remotes, it's important that we construct the corresponding roblox RemoteEvent
and RemoteFunction
instances. For this we are gonna call Remotes.Server.Construct()
on the Server.
(If we use DeclareRemotes() on more files, you need to call it on each one)
import { Remotes } from ""; //Remote Declarations path
Remotes.Server.Construct();
//Created instances can be found in ReplicatedStorage._wired
We can use these declarations before the instances have been constructed and anything we do will be queued up until the instances exist. If an action has been queued up for more than 7 seconds, wired will warn about it.
This is mainly so we can get our remotes at the top of our scripts without wired yielding or erroring if the instances haven't been created. It's recommended to call Construct()
as soon as possible.
Replicating Remotes to the Client
When our remotes have been created on the Server, we need the client to wait for these instances before using them. For this we need to call Remotes.Client.Prepare()
this function returns a Promise
that resolves when all the instances are ready to be used
import { Remotes } from ""; //Remote Declarations path
Remotes.Client.Prepare().andThen(() => {
print("Instances are ready!");
});
//Created instances can be found in ReplicatedStorage._wired
Similar to Server, anything we do will be queued up until the instances exist, wired will warn you if it's been waiting for more than 7 seconds. It's recommended to call Remotes.Client.Prepare
as soon as possible. You can use the returned promise for creating a loading screen
- [ WARNING ]
In the Server contextRemotes.Client
will be nil, and similarly In the ClientRemotes.Server
wil be nil. Roblox-ts wont be able to check this
Using your remotes
We can use Remotes.Get(remote: string)
to find a remote
Let's see all the remotes we can create
import { DeclareRemotes, ServerAsync, ServerEvent, ClientEvent, RemoteEvent } from "@rbxts/wired";
export const Remotes = DeclareRemotes("Remotes", {
DoubleNumber: ServerAsync<(num: number) => number>(),
OnDamageTaken: ServerEvent<(damage: number) => void>(),
OnPlayerLoaded: ClientEvent<() => void>(),
//First generic is for server, second one for client
OnMessageSent: RemoteEvent<(from: Player, msg: string) => void, (msg: string) => void>(),
});
- [ WARNING ]
The generic you give for the remotes is useful for type inference, but wired will not typecheck the remotes on runtime. Any check needs to be done by you to avoid exploiters
ServerAsync
RemoteFunction
that clients can call to the server expecting it to return something
import { Remotes } from ""; //Remote Declarations path
const DoubleNumber = Remotes.Get("DoubleNumber");
//Server
DoubleNumber.SetCallback((player, num) => {
return num * 2;
});
//Client
AsyncFunction.CallServer(5).andThen((double) => print(double)); //10
ServerEvent
RemoteEvent
that a server can fire to clients
import { Remotes } from ""; //Remote Declarations path
const OnDamageTaken = Remotes.Get("OnDamageTaken");
//Server
OnDamageTaken.FirePlayer(player, 50);
OnDamageTaken.FireAll(50);
OnDamageTaken.FireExcept(player, 50);
OnDamageTaken.FireFor((p) => {
//return true to fire, false to omit
return p == player;
}, 50);
//Client
const connection = OnDamageTaken.Connect((damage) => {
print("Ouch!", damage);
});
connection.Disconnect();
ClientEvent
RemoteEvent
that clients can fire to the server
import { Remotes } from ""; //Remote Declarations path
const OnPlayerLoaded = Remotes.Get("OnPlayerLoaded");
//Server
const connection = OnPlayerLoaded.Connect((player) => {
print("Player is ready to play!");
});
connection.Disconnect();
//Client
const OnPlayerLoaded = Remotes.Get("OnPlayerLoaded"); //we can do this even if it's not prepared yet
game.IsLoaded() || game.Loaded.Wait();
Remotes.Prepare().await();
OnPlayerLoaded.FireServer();
RemoteEvent
Bidirectional RemoteEvent
that both the Server and Client can Fire or Connect. Methods like FireAll
, FireExcept
, FireFor
are available here for the server too
import { Remotes } from ""; //Remote Declarations path
const OnMessageSent = Remotes.Get("OnMessageSent");
//Server
OnMessageSent.Connect((player, msg) => {
OnMessageSent.FireExcept(player, msg);
});
//Client
OnMessageSent.FireServer("Hello!");
OnMessageSent.Connect((player, msg) => {
print(player.Name, "says:", msg);
});
Namespaces
Namespaces are useful for grouping your remotes, you can create namespaces directly inside of your remote declarations, and you can create namespaces inside namespaces.
You can separate namespaces in different files as an alternative to calling DeclareRemotes() on different files
import { DeclareRemotes, Namespace, ServerAsync } from "@rbxts/wired";
export const Remotes = DeclareRemotes("Remotes", {
ShopRemotes: Namespace({
BuyRequest: ServerAsync(),
}),
GameplayRemotes: Namespace({
//Remotes here
}),
NamespaceRemotes: Namespace({
SubNamespace1: Namespace({
//Remotes here
}),
SubNamespace2: Namespace({
//Remotes here
}),
}),
});
You can access these namespaces with the Remotes.Namespace()
method
import { Remotes } from ""; //Remote Declarations path
//Server
const ShopRemotes = Remotes.Server.Namespace("ShopRemotes");
const BuyRequest = ShopRemotes.Get("BuyRequest");
BuyRequest.SetCallback();
//Client
const ShopRemotes = Remotes.Client.Namespace("ShopRemotes");
const BuyRequest = ShopRemotes.Get("BuyRequest");
BuyRequest.CallServer();