I watched a youtube video on some gravity simulation, and they let you see the source code, so I had this idea to recreate it in Roblox, but it was created with C# in Unity. Now I was sort of able to figure out what the code does but I wasn't sure so I did a few google searches if I didn't understand something. Now the thing is SOMETHING isn't right with it because the planets just follow each other and speed up over time until you experience floating-point precision errors, so I want to know, how good is my code? Here's the source: https://github.com/SebLague/Solar-System/tree/Episode_01/Assets/Scripts/Planets Here's my code: (I didn't do gravity object because it appeared to do nothing) Universe: (ModuleScript)
local Universe = {
gravitationalConstant = 0.0001;
physicsTimeStep = 0.01;
};
Universe.updateProperties = function(G, T)
Universe.gravitationalConstant = G
Universe.physicsTimeStep = T
end
return Universe
CelestialBody: (ModuleScript)
local Universe = require(script.Parent.Universe)
_G.CelestialBody = {}
newCelestialBody = function()
local this = {}
this.radius = 0
this.surfaceGravity = 0
this.initialVelocity = Vector3.new(0, 0, 0)
this.bodyName = "Unnamed"
this.velocity = Vector3.new(0, 0, 0)
this.mass = 0
this.rb = game.ServerStorage.MeshPart:Clone()
this.rb.Parent = workspace
local mv = Instance.new("IntValue", this.rb)
mv.Name = "mass"
this.Awake = function()
this.rb.mass.Value = this.mass
velocity = this.initialVelocity
end
this.UpdateVelocity = function(allBodies, timeStep)
for i,otherBody in pairs(allBodies) do
if otherBody ~= this then
local sqrDst = (otherBody.rb.Position - this.rb.Position).Magnitude
local forceDir = (otherBody.rb.Position - this.rb.Position).Unit
local acceleration = forceDir * Universe.gravitationalConstant * otherBody.mass / sqrDst
velocity += acceleration * timeStep
end
end
end
this.UpdateVelocity = function(acceleration, timeStep)
velocity += acceleration * timeStep
end
this.UpdatePosition = function(timeStep)
this.rb.Position += (velocity * timeStep)
end
this.OnValidate = function()
this.mass = this.surfaceGravity * this.radius * this.radius / Universe.gravitationalConstant
this.rb.Size = Vector3.new(1, 1, 1)* this.radius
this.rb.Name = this.bodyName
end
this.rb.Changed:Connect(this.OnValidate)
this.RigidBody = function()
return this.rb
end
this.Position = function()
return this.rb.Position
end
table.insert(_G.CelestialBody, this)
return this
end
return newCelestialBody
NBodySimulation: (ModuleScript)
local Universe = require(script.Parent.Universe)
local Time = {fixedDeltaTime = 0}
function newNBodySimulation()
local this = {}
this.bodies = _G.CelestialBody
this.NBodySimulation = Instance.new("Folder", workspace)
this.Awake = function()
this.bodies = _G.CelestialBody
Time.fixedDeltaTime = Universe.physicsTimeStep
print("Setting fixedDeltaTime to: "..Universe.physicsTimeStep)
end
this.FixedUpdate = function()
for i = 1, #this.bodies do
local acceleration = this.CalculateAcceleration(this.bodies[i].Position(), this.bodies[i])
this.bodies[i].UpdateVelocity(acceleration, Universe.physicsTimeStep)
end
for i = 1, #this.bodies do
this.bodies[i].UpdatePosition(Universe.physicsTimeStep)
end
end
this.CalculateAcceleration = function(point, ignoreBody)
local acceleration = Vector3.new(0, 0, 0)
for i,body in pairs(this.bodies) do
if body ~= ignoreBody then
local sqrDst = (body.Position() - point).Magnitude
local forceDir = (body.Position() - point).Unit
acceleration += forceDir * Universe.gravitationalConstant * body.mass / sqrDst
print(acceleration)
end
end
return acceleration
end
this.Bodies = function()
return this.bodies
end
this.NBodySimulation = function(instance)
if instance == nil then
instance = this.NBodySimulation
end
return instance
end
return this
end
return newNBodySimulation
Heres an example script to demonstrate usage:
local CelestialBody = require(script.Parent.CelestialBody)
local NBodySimulation = require(script.Parent.NBodySimulation)
local planet = CelestialBody()
planet.radius = 2.5
planet.surfaceGravity = 10
planet.bodyName = "New planet"
planet.initialVelocity = Vector3.new(0, 0, 0)
planet.OnValidate()
planet.Awake()
local sim = NBodySimulation()
sim.Awake()
wait(10)
while true do
sim.FixedUpdate()
wait()
end

4 comments
The scope of this questions really is way too large. We don't have all the details, and seeing as this is translated code from an OOP language to a scripting language, how are we to know if the problem resides in the source's code that you translated it from or with your translated code, or just that roblox's engine can't handle what you are trying to do.
Instead of asking "How is this code", try to figure out the problem for yourself, and then come back with a few more specific questions.
It's not the source code, it works just fine in the game.
The Unity game, I mean.