Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Custom planetary gravity = slowly enlarging orbits?

Asked by
thebayou 441 Moderation Voter
5 years ago
Edited 5 years ago

Intro

For an upcoming space game I've scripted a basic custom universal gravity simulator. I've set the workspace's gravity value to 0 and decided to use BodyForces to simulate gravitational attraction.

The Problem

I've gotten pretty far on the grav sim, but I've encountered an issue regarding the trajectories of the parts. Namely, when a part starts orbiting another part, its orbit inexplicably gets larger each revolution. An example: https://imgur.com/gallery/G4h1sd4

As you can see, the orbits get progressively wider, and yes, there's only two bodies involved.

Code

Force Updater

runService.Stepped:Connect(function()

    local parts = {}

    for _, part in pairs(workspace:GetDescendants()) do
        local mass = getMass(part)
        if part ~= workspace.Terrain and not part:FindFirstChild("DoNotBeAttracted") and mass > 0 then
            parts[part] = {["pos"] = getPos(part), ["mass"] = mass}
        end
    end

    for part, attr in pairs(parts) do

        local pos = attr.pos
        local mass = attr.mass

        -- Calculate the net gravitational forces
        local netGForce = Vector3.new(0, 0, 0)          -- Possible bottleneck

        for _, otherpart in pairs(workspace:GetDescendants()) do

            if part ~= otherpart and otherpart ~= workspace.Terrain and not part:FindFirstChild("DoNotAttract") then

                local otherpartMass = getMass(otherpart)
                if otherpartMass > 0 then

                    local otherpartPos = getPos(otherpart)

                    local attraction = gravityModule.calculateGravitationalAttraction(pos, mass, otherpartPos, otherpartMass)
                    local directionVector = (otherpartPos - pos).Unit
                    netGForce = netGForce + attraction * directionVector
                end
            end
        end

        -- Make/update BodyForce
        updateForces(part, netGForce)
    end

    -- Loop through all parts and apply velocity change
    for _, part in pairs(workspace:GetDescendants()) do
        if part ~= workspace.Terrain and not part:FindFirstChild("DoNotBeAttracted") then
            if part:FindFirstChild("GravityForce") and part:FindFirstChild("GravityForceValue") then
                part.GravityForce.Force = part.GravityForceValue.Value
            end
        end
    end
end)

Gravitation Calculation Function

function module.calculateGravitationalAttraction(pointA, massA, pointB, massB)
    return module.gravitationalConstant*massA*massB/(pointB-pointA).Magnitude^2
end

Theories

Could the forces not be updating frequently enough, leading to a delayed gravity, in a sense, which would allow the bodies to drift more than they should? If so, how should I fix this?

Could this be similar to what's happening in real life to the Earth and Moon (very very doubtful)?

Any help is appreciated

Answer this question