Josiahiscool73

Server pos shower from client script

Sep 28th, 2026
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.60 KB | None | 0 0
  1. -- server position shower from client
  2. -- i recommend using it 3-5 times and getting a ms that isnt constantly changing
  3. -- for example 500 and then 502 or 550 on the next test is fine but 500 to 600 or 400 is bad
  4. local Players = game:GetService("Players")
  5. local RunService = game:GetService("RunService")
  6. local TweenService = game:GetService("TweenService")
  7. local UserInputService = game:GetService("UserInputService")
  8. local Stats = game:GetService("Stats")
  9. local CoreGui = game:GetService("CoreGui")
  10.  
  11. local LocalPlayer = Players.LocalPlayer
  12. local mouse = LocalPlayer:GetMouse()
  13.  
  14. -- Variables
  15. local showingGhost = false
  16. local ghostClone = nil
  17. local positionHistory = {} -- Stores past positions and timestamps
  18. local baseDelayOffset = 0 -- Manual delay offset (seconds)
  19. local calculatedPhysicsPing = 0 -- Total round-trip from the tool
  20.  
  21. -- GUI Setup
  22. local ScreenGui = Instance.new("ScreenGui")
  23. ScreenGui.Name = "ServerGhostGUI"
  24. ScreenGui.ResetOnSpawn = false
  25.  
  26. local success, uiParent = pcall(function() return gethui() or CoreGui end)
  27. if not success then uiParent = LocalPlayer:WaitForChild("PlayerGui") end
  28. ScreenGui.Parent = uiParent
  29.  
  30. local MainFrame = Instance.new("Frame")
  31. MainFrame.Size = UDim2.new(0, 200, 0, 190)
  32. MainFrame.Position = UDim2.new(0.5, -100, 0.5, -95)
  33. MainFrame.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
  34. MainFrame.BorderSizePixel = 0
  35. MainFrame.Parent = ScreenGui
  36.  
  37. local UICorner = Instance.new("UICorner")
  38. UICorner.CornerRadius = UDim.new(0, 8)
  39. UICorner.Parent = MainFrame
  40.  
  41. local Title = Instance.new("TextLabel")
  42. Title.Size = UDim2.new(1, 0, 0, 30)
  43. Title.BackgroundTransparency = 1
  44. Title.Text = "Server Ghost"
  45. Title.TextColor3 = Color3.fromRGB(255, 255, 255)
  46. Title.Font = Enum.Font.GothamBold
  47. Title.TextSize = 14
  48. Title.Parent = MainFrame
  49.  
  50. -- Delay Offset Input
  51. local DelayBox = Instance.new("TextBox")
  52. DelayBox.Size = UDim2.new(0.9, 0, 0, 30)
  53. DelayBox.Position = UDim2.new(0.05, 0, 0, 40)
  54. DelayBox.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
  55. DelayBox.TextColor3 = Color3.fromRGB(255, 255, 255)
  56. DelayBox.PlaceholderText = "Manual Offset (e.g. 0)"
  57. DelayBox.Text = "0"
  58. DelayBox.Font = Enum.Font.Gotham
  59. DelayBox.TextSize = 14
  60. DelayBox.Parent = MainFrame
  61.  
  62. -- Ghost Toggle Button
  63. local GhostButton = Instance.new("TextButton")
  64. GhostButton.Size = UDim2.new(0.9, 0, 0, 35)
  65. GhostButton.Position = UDim2.new(0.05, 0, 0, 85)
  66. GhostButton.BackgroundColor3 = Color3.fromRGB(0, 150, 255)
  67. GhostButton.TextColor3 = Color3.fromRGB(255, 255, 255)
  68. GhostButton.Text = "Show Server Ghost"
  69. GhostButton.Font = Enum.Font.GothamBold
  70. GhostButton.TextSize = 14
  71. GhostButton.Parent = MainFrame
  72.  
  73. -- Ping Checker Button
  74. local PingButton = Instance.new("TextButton")
  75. PingButton.Size = UDim2.new(0.9, 0, 0, 35)
  76. PingButton.Position = UDim2.new(0.05, 0, 0, 135)
  77. PingButton.BackgroundColor3 = Color3.fromRGB(255, 100, 100)
  78. PingButton.TextColor3 = Color3.fromRGB(255, 255, 255)
  79. PingButton.Text = "Get Ping Tool"
  80. PingButton.Font = Enum.Font.GothamBold
  81. PingButton.TextSize = 14
  82. PingButton.Parent = MainFrame
  83.  
  84. -- Make GUI Draggable
  85. local dragging, dragInput, dragStart, startPos
  86. MainFrame.InputBegan:Connect(function(input)
  87. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  88. dragging = true
  89. dragStart = input.Position
  90. startPos = MainFrame.Position
  91. input.Changed:Connect(function()
  92. if input.UserInputState == Enum.UserInputState.End then dragging = false end
  93. end)
  94. end
  95. end)
  96. MainFrame.InputChanged:Connect(function(input)
  97. if input.UserInputType == Enum.UserInputType.MouseMovement then dragInput = input end
  98. end)
  99. UserInputService.InputChanged:Connect(function(input)
  100. if input == dragInput and dragging then
  101. local delta = input.Position - dragStart
  102. MainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
  103. end
  104. end)
  105.  
  106. -- Update Offset manually
  107. DelayBox.FocusLost:Connect(function()
  108. local val = tonumber(DelayBox.Text)
  109. if val then
  110. baseDelayOffset = val
  111. else
  112. DelayBox.Text = tostring(baseDelayOffset)
  113. end
  114. end)
  115.  
  116. -- Safely get Network Ping actively
  117. local function getNetworkPing()
  118. local activePing = 0
  119. local success, result = pcall(function()
  120. local label = CoreGui.RobloxGui.PerformanceStats:GetChildren()[6].StatsMiniTextPanelClass.ValueLabel
  121. return label.Text
  122. end)
  123. if success and type(result) == "string" then
  124. local numStr = string.match(result, "[%d%.]+")
  125. if numStr then return tonumber(numStr) end
  126. end
  127.  
  128. local statSuccess, statResult = pcall(function()
  129. return Stats.Network.ServerStatsItem["Data Ping"]:GetValue()
  130. end)
  131. if statSuccess and type(statResult) == "number" then
  132. return statResult
  133. end
  134.  
  135. return activePing
  136. end
  137.  
  138. -- Create Ghost Function
  139. local function createGhost()
  140. if ghostClone then ghostClone:Destroy() end
  141. local char = LocalPlayer.Character
  142. if not char then return end
  143.  
  144. char.Archivable = true
  145. local clone = char:Clone()
  146. char.Archivable = false
  147.  
  148. clone.Name = "ServerGhost"
  149. -- Fixes the sinking bug by explicitly locking the center of the model to the HRP
  150. clone.PrimaryPart = clone:FindFirstChild("HumanoidRootPart")
  151.  
  152. for _, v in ipairs(clone:GetDescendants()) do
  153. if v:IsA("Script") or v:IsA("LocalScript") then
  154. v:Destroy()
  155. elseif v:IsA("BasePart") then
  156. -- Strip completely of physics
  157. v.CanCollide = false
  158. v.CanTouch = false
  159. v.CanQuery = false
  160. v.Massless = true
  161. v.Anchored = true
  162. v.Material = Enum.Material.ForceField
  163. v.Color = Color3.fromRGB(0, 255, 255) -- Cyan color
  164. v.CastShadow = false
  165. if v.Name == "HumanoidRootPart" then
  166. v.Transparency = 1
  167. else
  168. v.Transparency = 0
  169. end
  170. elseif v:IsA("Decal") or v:IsA("Texture") then
  171. v:Destroy()
  172. end
  173. end
  174.  
  175. -- Paralyze the ghost's Humanoid so it doesn't force collision states
  176. local hum = clone:FindFirstChild("Humanoid")
  177. if hum then
  178. hum.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
  179. hum.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOff
  180. hum.PlatformStand = true
  181. for _, state in pairs(Enum.HumanoidStateType:GetEnumItems()) do
  182. pcall(function() hum:SetStateEnabled(state, false) end)
  183. end
  184. end
  185.  
  186. clone.Parent = workspace
  187. ghostClone = clone
  188. end
  189.  
  190. -- Toggle Logic
  191. GhostButton.MouseButton1Click:Connect(function()
  192. showingGhost = not showingGhost
  193. if showingGhost then
  194. createGhost()
  195. GhostButton.Text = "Hide Server Ghost"
  196. GhostButton.BackgroundColor3 = Color3.fromRGB(255, 50, 50)
  197. else
  198. if ghostClone then
  199. ghostClone:Destroy()
  200. ghostClone = nil
  201. end
  202. GhostButton.Text = "Show Server Ghost"
  203. GhostButton.BackgroundColor3 = Color3.fromRGB(0, 150, 255)
  204. Title.Text = "Server Ghost"
  205. end
  206. end)
  207.  
  208. -- Re-create ghost if character respawns while enabled
  209. LocalPlayer.CharacterAdded:Connect(function()
  210. positionHistory = {} -- clear history
  211. if showingGhost then
  212. task.wait(0.5)
  213. createGhost()
  214. end
  215. end)
  216.  
  217. -- Loop: Record History & Update Ghost
  218. RunService.Heartbeat:Connect(function()
  219. local char = LocalPlayer.Character
  220. local hrp = char and char:FindFirstChild("HumanoidRootPart")
  221. if not hrp then return end
  222.  
  223. -- 1. Log Current Position
  224. table.insert(positionHistory, {
  225. t = os.clock(),
  226. cf = hrp.CFrame
  227. })
  228.  
  229. -- 2. Clean up history older than 3 seconds (prevent memory leaks)
  230. while #positionHistory > 0 and (os.clock() - positionHistory[1].t) > 3 do
  231. table.remove(positionHistory, 1)
  232. end
  233.  
  234. -- 3. Update Ghost if toggled
  235. if showingGhost and ghostClone and ghostClone.PrimaryPart then
  236.  
  237. -- OVERRIDE ENFORCER: Absolutely ensure Roblox didn't turn collisions back on
  238. for _, v in ipairs(ghostClone:GetDescendants()) do
  239. if v:IsA("BasePart") and v.CanCollide then
  240. v.CanCollide = false
  241. end
  242. end
  243.  
  244. local currentNetPing = getNetworkPing()
  245. local delayMs = currentNetPing -- Default to raw network ping
  246.  
  247. -- Use our Physics test minus Network ping if available
  248. if calculatedPhysicsPing > 0 then
  249. delayMs = math.max(0, calculatedPhysicsPing - currentNetPing)
  250. end
  251.  
  252. Title.Text = string.format("Delaying by %dms", delayMs)
  253.  
  254. -- Target time we want to show (current time minus delay)
  255. local targetDelaySeconds = (delayMs / 1000) + baseDelayOffset
  256. local targetTime = os.clock() - targetDelaySeconds
  257.  
  258. local targetCFrame = hrp.CFrame
  259.  
  260. -- Interpolate to find exact CFrame in the past
  261. if #positionHistory >= 2 then
  262. for i = #positionHistory, 2, -1 do
  263. local current = positionHistory[i]
  264. local previous = positionHistory[i-1]
  265.  
  266. if current.t >= targetTime and previous.t <= targetTime then
  267. local alpha = (targetTime - previous.t) / (current.t - previous.t)
  268. targetCFrame = previous.cf:Lerp(current.cf, alpha)
  269. break
  270. elseif i == 2 and targetTime < previous.t then
  271. targetCFrame = previous.cf
  272. end
  273. end
  274. end
  275.  
  276. -- Pivot directly to the calculated CFrame (safe from ground-sinking due to PrimaryPart lock)
  277. ghostClone:PivotTo(targetCFrame)
  278. end
  279. end)
  280.  
  281. -- Ping Checker Script Implementation
  282. PingButton.MouseButton1Click:Connect(function()
  283. if LocalPlayer.Backpack:FindFirstChild("PingCheck") then
  284. PingButton.Text = "Already have Tool!"
  285. task.wait(1)
  286. PingButton.Text = "Get Ping Tool"
  287. return
  288. end
  289.  
  290. local tool = Instance.new("Tool")
  291. tool.Name = "PingCheck"
  292. tool.RequiresHandle = false
  293. tool.Parent = LocalPlayer.Backpack
  294.  
  295. local function getHRP(p)
  296. local c = p and p.Character
  297. return c and c:FindFirstChild("HumanoidRootPart")
  298. end
  299.  
  300. local function noCollide(c)
  301. for _, d in ipairs(c:GetDescendants()) do
  302. if d:IsA("BasePart") then d.CanCollide = false end
  303. end
  304. end
  305.  
  306. local function slide(part, goal, dur)
  307. local tw = TweenService:Create(part, TweenInfo.new(dur, Enum.EasingStyle.Linear), { CFrame = goal })
  308. tw:Play()
  309. tw.Completed:Wait()
  310. end
  311.  
  312. local function run(target)
  313. local th = getHRP(target)
  314. local mh = getHRP(LocalPlayer)
  315. if not th or not mh then return end
  316.  
  317. noCollide(LocalPlayer.Character)
  318. task.wait(0.2)
  319.  
  320. local last = th.Position
  321. local still = 0
  322. while still < 30 do
  323. RunService.Heartbeat:Wait()
  324. th = getHRP(target) or th
  325. local p = th.Position
  326. if (p - last).Magnitude > 0.15 then still = 0 else still += 1 end
  327. last = p
  328. end
  329.  
  330. mh = getHRP(LocalPlayer) or mh
  331. th = getHRP(target) or th
  332. slide(mh, th.CFrame * CFrame.new(0, 0, 10), 1.2)
  333. task.wait(0.5)
  334.  
  335. local t0 = nil
  336. local p0 = nil
  337. local moved = false
  338. local ms = 0
  339. local done = false
  340. local endT = nil
  341.  
  342. task.spawn(function()
  343. local m = getHRP(LocalPlayer) or mh
  344. local t = getHRP(target) or th
  345. slide(m, t.CFrame * CFrame.new(0, 0, -10), 1.2)
  346. done = true
  347. endT = os.clock()
  348. end)
  349.  
  350. while not moved do
  351. RunService.Heartbeat:Wait()
  352. mh = getHRP(LocalPlayer) or mh
  353. th = getHRP(target) or th
  354.  
  355. if not t0 then
  356. if (mh.Position - th.Position).Magnitude <= 3 then
  357. t0 = os.clock()
  358. p0 = th.Position
  359. elseif done and endT and (os.clock() - endT) > 5 then
  360. break
  361. end
  362. else
  363. ms = (os.clock() - t0) * 1000
  364. if (th.Position - p0).Magnitude > 0.05 then
  365. moved = true
  366. elseif ms > 5000 then
  367. break
  368. end
  369. end
  370. end
  371.  
  372. if moved then
  373. print(string.format("Calculated Physics Ping: %.6f ms", ms))
  374. -- Sync it with the ghost script
  375. calculatedPhysicsPing = ms
  376. end
  377. end
  378.  
  379. tool.Activated:Connect(function()
  380. local hit = mouse.Target
  381. if not hit then return end
  382. local model = hit:FindFirstAncestorOfClass("Model")
  383. if not model then return end
  384. local plr = Players:GetPlayerFromCharacter(model)
  385. if plr and plr ~= LocalPlayer then
  386. run(plr)
  387. end
  388. end)
  389.  
  390. PingButton.Text = "Tool Given!"
  391. task.wait(1)
  392. PingButton.Text = "Get Ping Tool"
  393. end)
Advertisement
Add Comment
Please, Sign In to add comment