I want to be able to pause the physics in Roblox without any minute changes occurring. I am creating a physics-based casual puzzle game, where you fire a projectiles to knock over a building, and want to create a Pausing System. However, stress testing by cycling pause and resume showed unwanted results.
The issue is when trying to do the Pausing by anchoring all the parts, and then unanchoring all the parts on resume, the parts end up moving slightly and this adds up overtime leading to undesirable outcomes.
Video is sped up by 4x
Here is the code used for the Pausing and Resuming as well as the Stress Test code
function LevelController:Pause()
if self.LevelFastCast.Simulation == nil then return end
print("Pause")
local PausedBaseParts = {}
for i,Instance in self.LevelRoot.Structures:GetChildren() do
if Instance:IsA("Model") then
table.insert(PausedBaseParts, Instance.PrimaryPart)
elseif Instance:IsA("BasePart") then
table.insert(PausedBaseParts, Instance)
end
end
for i,Mob in self.LevelRoot.Mobs:GetChildren() do
if Mob:IsA("Model") then
table.insert(PausedBaseParts, Mob.PrimaryPart)
end
end
for i,Cast in self.LevelFastCast.Simulation.StateInfo.Casts do
table.insert(PausedBaseParts, Cast.RayInfo.ServerBulletObject)
end
task.spawn(function()
task.delay(0,function()
self.LevelFastCast.Simulation:Pause()
end)
end)
task.spawn(function()
self.LevelInfo.PausedBaseParts = {}
for _,BasePart in PausedBaseParts do
task.delay(0,function()
print("Anchored Part")
BasePart.Anchored = true
table.insert(self.LevelInfo.PausedBaseParts, BasePart)
end)
end
end)
task.spawn(function()
for i,Cast in self.LevelFastCast.Simulation.StateInfo.Casts do
task.delay(0,function()
Cast.RayInfo.ServerBulletObject.CFrame = Cast.UserData.BulletSkin.CFrame
end)
end
end)
end
function LevelController:Resume()
if self.LevelFastCast.Simulation == nil then return end
if GuiService.MenuIsOpen or self.PlayerInfo.GUI.LevelMenu.Visible or PI.WindowFocusState == "Released" then return end
print("Resume")
task.delay(0,function() self.LevelFastCast.Simulation:Start() end)
for _,BasePart in self.LevelInfo.PausedBaseParts do
task.delay(0,function()
print("Unanchored Part")
BasePart.Anchored = false
end)
end
end
-- STRESS TEST BASIC CODE --
while on do
self:Pause()
wait(0.2)
self:Resume()
wait(0.2)
end
I have tried saving the data for the BasePart on Pause, its CFrame and AssemblyLinearVelocity, and on Resume copying that data over immediately, after a very small delay, and after RunService Waits, but all led to the same results.
I believe ideally Roblox needs to add more control over the physics engine to allow for more creativity with said engine. I have some knowledge with Physics Engines as FastCast itself is one, albeit very basic. Simple things like slowing down physics time and being able to completely stop it would be ideal and allow for some very cool projects to be made. Even better would be deterministic physics, allowing for things like replay systems.