This guide covers the simplest working replication setup for feces. It uses plain RobloxDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/NeonD00m/feces/llms.txt
Use this file to discover all available pages before exploring further.
RemoteEvents and is suitable for most games that don’t replicate extremely large amounts of data frequently. If you’re just getting started, this is the recommended approach.
Overview
There are three pieces to this setup:- Full snapshot on join — when a client connects, it requests the current world state and receives it all at once.
- Delta loop — every frame (or however frequently you choose), the server computes what has changed and sends only those changes to each player.
- Client-side apply — the client receives packets and applies them to its local feces instance.
Full Setup
Create your RemoteEvents
You will need two
RemoteEvent instances in ReplicatedStorage:requestFullPacket— fired by the client to ask for a full world snapshot on join.remote— the general replication event used for both full and delta packets.
Server and client wiring
Place this code in a shared module or split it across a server Script and a LocalScript. The
RunService:IsServer() guard selects the correct branch at runtime.Server replicate() function
Call
replicate() at the end of each server frame to compute and send per-player delta packets.Hook replicate() into your game loop
Call
replicate() from your server-side heartbeat or scheduler so it runs once per frame.You can call
replicate() at any point in your frame — at the end is typical so all ECS
systems have already run and all component changes for that frame are captured in a single
delta pass.How Each Part Works
requestFullPacket and feces.full()
When a fresh client connects it has no world state. Firing requestFullPacket to the server triggers feces.full(), which returns a complete snapshot of everything currently marked as replicated. The server fires this snapshot back to just that player via remote:FireClient(player, ...).
On the client, the same OnClientEvent handler that processes deltas also processes this initial full snapshot — both call feces.apply(data), so no special-case code is needed.
feces:delta()
feces:delta() returns two tables:
changes— a map of components to per-player entity data that has changed since the last call.deleted— a map of players to arrays of entity lookup keys that have been deleted since the last call.
feces.combine(changes, deleted)
feces.combine() merges the raw changes and deleted tables into a single per-player packet map. Iterating over its result gives you (player, packet) pairs, where each packet contains only the data that specific player needs to receive.
feces.apply(data) (client)
On the client, feces.apply(data) takes any packet — whether a full snapshot or a delta — and reconciles it with the local jecs world. It creates new local entities, updates changed component values, removes components, and deletes entities as directed by the packet. Any hooks you have registered will fire during this process.