Samples

Best samples

Sample Design Work

Fishing

CustomReplicator

CustomReplicator.lua

1local Players = game:GetService("Players")
2local RunService = game:GetService("RunService")
3
4local CustomReplicator = {}
5CustomReplicator.__index = CustomReplicator
6CustomReplicator.Tag = "CustomReplicator"
7
8local CONTAINER_NAME = "CustomReplicatorContainer"
9local CLONE_HOST_NAME = "CustomReplicatorClones"
10local REMOTE_FOLDER_NAME = "CustomReplicator"
11local CLIENT_TAG = "CustomReplicatorClient"
12local DEFAULT_INTERVAL = 0.1
13local DEFAULT_PROXIMITY_DISTANCE = 250
14local PROXIMITY_DISTANCE_ATTR = "ReplicatorProximityDistance"
15local INT16_MIN = -32768
16local INT16_MAX = 32767
17local YAW_SCALE = 10000
18
19local liveComponents = {}
20local container = nil
21local remotes = nil
22
23local function ensureContainer()
24	if container and container.Parent then
25		return container
26	end
27	container = workspace:FindFirstChild(CONTAINER_NAME)
28	if not container then
29		container = Instance.new("Camera")
30		container.Name = CONTAINER_NAME
31		container.Parent = workspace
32	end
33	return container
34end
35
36local function cloneHostFor(player)
37	local playerGui = player:FindFirstChildOfClass("PlayerGui")
38	if not playerGui then return nil end
39	local host = playerGui:FindFirstChild(CLONE_HOST_NAME)
40	if not host then
41		host = Instance.new("Folder")
42		host.Name = CLONE_HOST_NAME
43		host.Parent = playerGui
44	end
45	return host
46end
47
48function CustomReplicator.Start()
49	ensureContainer()
50
51	local sharedRemote = CustomReplicator.BaseClass.sharedRemote
52	remotes = {
53		UpdateTransform = sharedRemote(REMOTE_FOLDER_NAME, "UpdateTransform"),
54		UpdateCFrame = sharedRemote(REMOTE_FOLDER_NAME, "UpdateCFrame"),
55		AnimationStart = sharedRemote(REMOTE_FOLDER_NAME, "AnimationStart"),
56		AnimationStop = sharedRemote(REMOTE_FOLDER_NAME, "AnimationStop"),
57	}
58
59	RunService.Heartbeat:Connect(function()
60		for component in liveComponents do
61			component:_update()
62		end
63	end)
64
65	CustomReplicator.Observers.observePlayer(function(player)
66		player:WaitForChild("PlayerGui", 10)
67		cloneHostFor(player)
68		for component in liveComponents do
69			component:playerAdded(player)
70		end
71		return function()
72			for component in liveComponents do
73				component:playerRemoved(player)
74			end
75		end
76	end)
77end
78
79function CustomReplicator.new(instance, options)
80	local self = setmetatable({}, CustomReplicator)
81	options = options or {}
82
83	self.trove = CustomReplicator.Trove.new()
84	self.instance = instance
85	self.formerParent = instance.Parent
86	self.clientInstances = {}
87	self.playingAnimations = {}
88	self.lastStamp = 0
89	self.interval = instance:GetAttribute("ReplicationInterval") or DEFAULT_INTERVAL
90	self.priority = instance:GetAttribute("Priority") == true
91	self.proximityDistance = instance:GetAttribute("ProximityDistance") or DEFAULT_PROXIMITY_DISTANCE
92
93	if options.replicateTargets then
94		self:_setTargetsFromList(options.replicateTargets)
95	else
96		local ownerUserId = instance:GetAttribute("OwnerUserId")
97		if typeof(ownerUserId) == "number" then
98			self.targetUserIds = { [ownerUserId] = true }
99		end
100	end
101
102	ensureContainer()
103	instance.Parent = container
104
105	self:_hookAnimations()
106	liveComponents[self] = true
107
108	for _, player in Players:GetPlayers() do
109		self:playerAdded(player)
110	end
111
112	return self
113end
114
115function CustomReplicator:_setTargetsFromList(players)
116	self.targetUserIds = {}
117	for _, player in players do
118		self.targetUserIds[player.UserId] = true
119	end
120end
121
122function CustomReplicator:_isTargeted()
123	return self.targetUserIds ~= nil
124end
125
126function CustomReplicator:_eligible(player)
127	if self.targetUserIds then
128		return self.targetUserIds[player.UserId] == true
129	end
130	return true
131end
132
133function CustomReplicator:setReplicateTargets(players)
134	if players == nil then
135		self.targetUserIds = nil
136	else
137		self:_setTargetsFromList(players)
138	end
139
140	for _, player in Players:GetPlayers() do
141		local eligible = self:_eligible(player)
142		local hasClone = self.clientInstances[player] ~= nil
143		if eligible and not hasClone then
144			self:playerAdded(player)
145		elseif not eligible and hasClone then
146			self:_removeClone(player)
147		end
148	end
149end
150
151function CustomReplicator:playerAdded(player)
152	if self.clientInstances[player] then return end
153	if not self:_eligible(player) then return end
154
155	local host = cloneHostFor(player)
156	if not host then return end
157
158	local clone = self.instance:Clone()
159	clone:RemoveTag(CustomReplicator.Tag)
160	clone:PivotTo(self.instance:GetPivot())
161	if not self:_isTargeted() then
162		clone:SetAttribute(PROXIMITY_DISTANCE_ATTR, self.proximityDistance)
163	end
164	clone:AddTag(CLIENT_TAG)
165	clone.Parent = host
166
167	self.clientInstances[player] = clone
168
169	for _, animData in self.playingAnimations do
170		remotes.AnimationStart:FireClient(player, clone, animData)
171	end
172end
173
174function CustomReplicator:_removeClone(player)
175	local clone = self.clientInstances[player]
176	if not clone then return end
177	self.clientInstances[player] = nil
178	if clone.Parent then
179		clone:Destroy()
180	end
181end
182
183function CustomReplicator:playerRemoved(player)
184	self:_removeClone(player)
185end
186
187function CustomReplicator:getClientInstance(player)
188	return self.clientInstances[player]
189end
190
191function CustomReplicator:_update()
192	local instance = self.instance
193	if not instance or not instance.Parent then return end
194
195	local now = os.clock()
196	if not self.priority and (now - self.lastStamp) < self.interval then
197		return
198	end
199	self.lastStamp = now
200
201	local pivot = instance:GetPivot()
202
203	if self.priority then
204		for player, clone in self.clientInstances do
205			remotes.UpdateCFrame:FireClient(player, clone, pivot)
206		end
207		return
208	end
209
210	local position = pivot.Position
211	local _, yaw = pivot:ToEulerAnglesYXZ()
212
213	local transform = buffer.create(8)
214	buffer.writei16(transform, 0, math.clamp(math.floor(position.X), INT16_MIN, INT16_MAX))
215	buffer.writei16(transform, 2, math.clamp(math.floor(position.Y), INT16_MIN, INT16_MAX))
216	buffer.writei16(transform, 4, math.clamp(math.floor(position.Z), INT16_MIN, INT16_MAX))
217	buffer.writei16(transform, 6, math.clamp(math.floor(yaw * YAW_SCALE), INT16_MIN, INT16_MAX))
218
219	for player, clone in self.clientInstances do
220		remotes.UpdateTransform:FireClient(player, clone, transform)
221	end
222end
223
224function CustomReplicator:_hookAnimations()
225	local animator = self.instance:FindFirstChildWhichIsA("Animator", true)
226	if not animator then return end
227
228	local ok, connection = pcall(function()
229		return animator.AnimationPlayed:Connect(function(track)
230			self:_onAnimationPlayed(track)
231		end)
232	end)
233
234	if ok and connection then
235		self.trove:Add(connection)
236	end
237end
238
239function CustomReplicator:_onAnimationPlayed(track)
240	local animation = track.Animation
241	if not animation or animation.AnimationId == "" then return end
242
243	local animData = {
244		id = animation.AnimationId,
245		name = animation.Name,
246		looped = track.Looped,
247		priority = track.Priority,
248	}
249
250	self.playingAnimations[animData.name] = animData
251
252	for player, clone in self.clientInstances do
253		remotes.AnimationStart:FireClient(player, clone, animData)
254	end
255
256	track.Stopped:Once(function()
257		self.playingAnimations[animData.name] = nil
258		for player, clone in self.clientInstances do
259			remotes.AnimationStop:FireClient(player, clone, animData.name)
260		end
261	end)
262end
263
264function CustomReplicator:destroy()
265	liveComponents[self] = nil
266
267	for _, clone in self.clientInstances do
268		if clone.Parent then
269			clone:Destroy()
270		end
271	end
272	self.clientInstances = {}
273
274	local instance = self.instance
275	if instance then
276		if self.formerParent then
277			instance.Parent = self.formerParent
278		else
279			instance:Destroy()
280		end
281	end
282end
283
284return CustomReplicator
285

More samples

Color The World

Turret
Portal gun
Rocket

Needoh Go

Jackpot tile
needoh crate tile
wheelspin
mutate tile

Foam Shot

NEW RELEASE
Foam Shot on Roblox
Foam Shot on Roblox