DUXPLIMA Documentation

The RPC layer

One RemoteEvent, one RemoteFunction, and a leading type string.

Every system talks over exactly two remotes, found under the runtime copy:

ReplicatedStorage/<package>/Core/<xx>Events/
  RemoteEvent
  RemoteFunction

<xx> is the product's short code, for example drEvents for the Daily Rewards system.

One remote, many messages

Rather than a remote per message, both remotes take a leading type string and dispatch on it:

-- client asks the server a question and waits for the answer
local state = ctx:Invoke("DR_GetState")

-- client tells the server something, no answer
ctx:Fire("SomeAction", payload)
-- server pushes to one client
Net.fire(player, "DR_State", snapshot)

-- server pushes to everyone
Net.fireAll("DR_State", snapshot)

Two remotes instead of thirty keeps the replicated surface small and makes every message visible in one dispatch table rather than scattered across the package.

Where the handlers are

DirectionHandler lives in
Client to server, with a replyServer/ApiHandlers.luau, the Functions table
Server to clientClient/.../Modules/EventDispatch.luau, the Handlers table

ApiHandlers.init() sets RemoteFunction.OnServerInvoke once, looks the type string up in Functions, and returns nil for anything it does not recognise. An unknown type string is therefore harmless: it does not error and it does not reach any product code.

Each product's own page lists its type strings and what they carry.

Calling it from your own code

On the client, the page modules already hold a context object:

ctx:Fire(rtype, ...)
local reply = ctx:Invoke(rtype, ...)

On the server, require the product's own service module rather than going through the remotes. The remotes exist for the interface; server code should call the service directly.

Trust

Everything arriving from a client is untrusted, and the handlers are written that way: the client sends an intent, the server decides. The client asking to claim a reward does not claim it, it asks the server whether the reward is claimable; the answer and the grant both happen server-side.

Do not add a handler that acts on client-supplied numbers

The pattern to avoid when extending a system is a handler that takes an amount, a price or a target and applies it as given. An exploiter can call any RemoteFunction in ReplicatedStorage with any arguments. Read the identity from player, read the value from the server's own state, and use the client's argument only to select between options the server already knows about.