Black Holes, Orbiting Bodies, and Anomalies -- Oh my!

Greetings all -

I'm fairly new to lua scripting, but am excited about the possibilities of doing so for Empty Epsilon. One of the cool things I discovered with EE was the ability to have space bodies in motion - because of course space is a lot more fun when you have things moving around! So I started experimenting with what could be done, and thought maybe others might like to use as well. I will add snippets here as I'm able.

First up, I wanted to try planets orbiting a black hole at different rates, that had moons that also had moons themselves. Here's what I came up with:


function init()

   	-- BLACK HOLE ORBITING SYSTEM TEST
		-- initial alignment of objects is along the X axis (X value is the same; Y changes for distance from center)
		-- the center object
		center_blackhole = BlackHole():setPosition(0, 0)
		-- "on the edge" planet orbiting just outside the event horizon, very fast
		cbh_event_horizon1 = Planet():setPosition(0, -6000):setPlanetRadius(500)
			:setDistanceFromMovementPlane(-2000)
			:setPlanetSurfaceTexture("planets/planet-1.png")
			:setPlanetCloudTexture("planets/clouds-1.png")
			:setPlanetAtmosphereTexture("planets/atmosphere.png")
			:setPlanetAtmosphereColor(0.2,0.2,1.0)
		cbh_event_horizon1:setOrbit(center_blackhole, 5)
		-- "near the edge" planet orbiting near the event horizon, fast
		cbh_event_horizon2 = Planet():setPosition(0, -10000):setPlanetRadius(1000)
			:setDistanceFromMovementPlane(-2000)
			:setPlanetSurfaceTexture("planets/planet-1.png")
			:setPlanetCloudTexture("planets/clouds-1.png")
			:setPlanetAtmosphereTexture("planets/atmosphere.png")
			:setPlanetAtmosphereColor(0.2,0.2,1.0)
		cbh_event_horizon2:setOrbit(center_blackhole, 15)

		-- planetary orbital sub-system 1, to the 'north' of sun1
			cbh_main_planet1 = Planet():setPosition(0, -30000):setPlanetRadius(3000)
				:setDistanceFromMovementPlane(-2000):setAxialRotationTime(30)
				:setPlanetSurfaceTexture("planets/planet-1.png")
				:setPlanetCloudTexture("planets/clouds-1.png")
				:setPlanetAtmosphereTexture("planets/atmosphere.png")
				:setPlanetAtmosphereColor(0.2,0.2,1.0)
			cbh_main_planet1:setOrbit(center_blackhole, 300)
			-- orbiting bodies for cbh_main_planet1, inner to outer
				mp1_satelite1 = Planet():setPosition(0, -24000):setPlanetRadius(500)
					:setDistanceFromMovementPlane(-2000):setAxialRotationTime(30)
					:setPlanetSurfaceTexture("planets/planet-1.png")
					:setPlanetCloudTexture("planets/clouds-1.png")
					:setPlanetAtmosphereTexture("planets/atmosphere.png")
					:setPlanetAtmosphereColor(0.2,0.2,1.0)
				mp1_satelite1:setOrbit(cbh_main_planet1, 10)
				
				mp1_satelite2 = Planet():setPosition(0, -20000):setPlanetRadius(1000)
					:setDistanceFromMovementPlane(-2000):setAxialRotationTime(30)
					:setPlanetSurfaceTexture("planets/planet-1.png")
					:setPlanetCloudTexture("planets/clouds-1.png")
					:setPlanetAtmosphereTexture("planets/atmosphere.png")
					:setPlanetAtmosphereColor(0.2,0.2,1.0)
				mp1_satelite2:setOrbit(cbh_main_planet1, 60)

				mp1s2_satelite1 = Planet():setPosition(0, -18000):setPlanetRadius(200)
					:setDistanceFromMovementPlane(-2000):setAxialRotationTime(10)
					:setPlanetSurfaceTexture("planets/planet-1.png")
					:setPlanetCloudTexture("planets/clouds-1.png")
					:setPlanetAtmosphereTexture("planets/atmosphere.png")
					:setPlanetAtmosphereColor(0.2,0.2,1.0)
				mp1s2_satelite1:setOrbit(mp1_satelite2, 5)

				mp1_satelite3 = Planet():setPosition(0, -16000):setPlanetRadius(500)
					:setDistanceFromMovementPlane(-2000):setAxialRotationTime(30)
					:setPlanetSurfaceTexture("planets/planet-1.png")
					:setPlanetCloudTexture("planets/clouds-1.png")
					:setPlanetAtmosphereTexture("planets/atmosphere.png")
					:setPlanetAtmosphereColor(0.2,0.2,1.0)
				mp1_satelite3:setOrbit(cbh_main_planet1, 60)
end

Because all the code in init() follows the constructs already established in EE, no additional code is needed in the update() function.

Enjoy!

Comments

  • Next, I wanted to create a binary black hole system. EE doesn't provide for BH's orbiting other bodies natively, so I came up with my own. 8-)

    And for good measure, I added a planet orbiting one of the BH's and a huge space station orbiting the other! (Yes, this is how you can have stations orbiting other entities.)

    Please note that I've hard coded the orbital speed to something that's easy to observe for a test. You may want to slow the speed down a bit… otherwise the people inhabiting the space station might be crushed to goo from the G forces… ;]

    Note that you create the bodies in the init() function, then move them in the update(delta) function.

    Also note that you must "require("utils.lua")"
    
    require("utils.lua")
    
    function init()
    	-- BINARY BLACK HOLE AROUND A SINGLE STAR TEST
    		cs_x_coord = 0
    		cs_y_coord = 0
    		obh1_distance = 40000
    		obh2_distance = 40000
    		
    		center_star = Planet():setPosition(cs_x_coord, cs_y_coord)
    			:setPlanetRadius(1000):setDistanceFromMovementPlane(-2000)
    			:setPlanetAtmosphereTexture("planets/star-1.png")
    			:setPlanetAtmosphereColor(1.0,1.0,1.0)
    		orbiting_blackhole_1 = BlackHole():setPosition(cs_x_coord, cs_y_coord + obh1_distance)
    		orbiting_blackhole_2 = BlackHole():setPosition(cs_x_coord, cs_y_coord - obh2_distance)
    		
    		-- for this test, set the orbital speed to 1 orbit/min; because the update function is called 
    		--approximately 60 times a second, that means we'd update the position around the orbit 
    		-- (60 calls/sec * 60 sec = 3600 calls)
    		-- 360 degrees / 3600 calls = 0.1 degree of arc per call (go to the update function for movement calculations)
    		orbiting_blackhole1_angle = 180
    		orbiting_blackhole2_angle = 0
    	
    		-- set up some planets to orbit the orbiting black holes
    		local x, y = orbiting_blackhole_1:getPosition()
    		obh1_orbiting_planet1 = Planet():setPosition(x, y-10000):setPlanetRadius(1000)
    			:setDistanceFromMovementPlane(0):setAxialRotationTime(20)
    			:setPlanetSurfaceTexture("planets/planet-1.png")
    			:setPlanetCloudTexture("planets/clouds-1.png")
    			:setPlanetAtmosphereTexture("planets/atmosphere.png")
    			:setPlanetAtmosphereColor(0.2,0.2,1.0)
    		obh1_orbiting_planet1:setOrbit(orbiting_blackhole_1, 8)
    		
    		-- test to have a station orbit the orbiting black holes
    		local x, y = orbiting_blackhole_2:getPosition()
    		obh2_orbiting_station1_orbit_distance = 10000
    		obh2_orbiting_station1 = SpaceStation():setPosition(x, y + obh2_orbiting_station1_orbit_distance)
    			:setTemplate('Huge Station'):setFaction("Human Navy"):setRotation(random(0, 360))
    		obh2_orbiting_station1_angle = 0
       	
    end
    

    Add the following in the update() function.
    
    function update(delta)
    	-- move the binary black holes in orbit around the shared star
    		
    		orbiting_blackhole1_angle = orbiting_blackhole1_angle + 0.1
    		if orbiting_blackhole1_angle > 360 then orbiting_blackhole1_angle = 0.1 end
    		
    		orbiting_blackhole2_angle = orbiting_blackhole2_angle + 0.1
    		if orbiting_blackhole2_angle > 360 then orbiting_blackhole2_angle = 0.1 end
    		
    		obh2_orbiting_station1_angle = obh2_orbiting_station1_angle + 0.5
    		if obh2_orbiting_station1_angle > 360 then obh2_orbiting_station1_angle = 0.5 end
    		
    		setCirclePos(orbiting_blackhole_1, cs_x_coord, cs_y_coord, orbiting_blackhole1_angle, obh1_distance)
    		setCirclePos(orbiting_blackhole_2, cs_x_coord, cs_y_coord, orbiting_blackhole2_angle, obh2_distance)
    		
    		-- note that because station objects don't have a built-in function to have them orbit something else, 
    		-- then we must take care of it ourselves
    		local x, y = orbiting_blackhole_2:getPosition()
    		setCirclePos(obh2_orbiting_station1, x, y, obh2_orbiting_station1_angle, obh2_orbiting_station1_orbit_distance)
    		
    end
    
    
    Enjoy!
  • edited November 6
    Ok, now let's get a little funky! Let's create a system with an orbiting planet, and the planet has a moon. It just so happens that there's another system with a planet whose orbit passes close to the first one. So close in fact, that the moon of the first planet decides to "hop" over to the second planet. Yea, kinda funky. I wouldn't want to see what would happen to this system in real life, but this is a game so it's kinda fun! ;]

    Note that you create the bodies in the init() function, then move them in the update(delta) function.

    Also note that you must "require("utils.lua")"
    
    require("utils.lua")
    
    function init()
    	-- STEAL AN ORBITING MOON TEST
    		-- the general idea is that there are two large planets orbiting two separate suns; there is one moon orbiting one of the planets; 
    		-- because the orbits of the two planets come close to one another, if the moon of the first planet passes closer to the second 
    		-- planet than the first, the idea is that it should "hop" planets and begin orbiting the second planet
    		-- crazy, yes
    		-- set up all on the same y value, separated along the x axis value
    		
    		-- establish a flag to state which planet the shared_moon is currently orbiting; 
    		-- 1 means planet 1 on the left side; 2 means planet 2 on the right side
    			moon_orbit_owner = 1
    			
    		-- first side (left)
    			star1_x_position = 0                        
    			star1_y_position = 0                         
    			planet1_x_start_position = star1_x_position - 40000
    			planet1_y_start_position = star1_y_position
    			shared_moon_x_start_position = planet1_x_start_position - 10000
    			shared_moon_y_start_position = planet1_y_start_position
    			
    			star1 = Planet():setPosition(star1_x_position, star1_y_position)
    				:setPlanetRadius(5000)
    				:setDistanceFromMovementPlane(-2000)
    				:setPlanetAtmosphereTexture("planets/star-1.png")
    				:setPlanetAtmosphereColor(1.0,1.0,1.0)
    			
    			planet1 = Planet():setPosition(planet1_x_start_position, planet1_y_start_position)
    				:setPlanetRadius(3000)
    				:setDistanceFromMovementPlane(-2000)
    				:setPlanetSurfaceTexture("planets/planet-1.png")
    				:setPlanetCloudTexture("planets/clouds-1.png")
    				:setPlanetAtmosphereTexture("planets/atmosphere.png")
    				:setPlanetAtmosphereColor(0.2,0.2,1.0)
    			
    			planet1:setOrbit(star1, 120)
    			
    			shared_moon = Planet():setPosition(shared_moon_x_start_position, shared_moon_y_start_position)
    				:setPlanetRadius(1000)
    				:setDistanceFromMovementPlane(-2000)
    				:setPlanetSurfaceTexture("planets/planet-1.png")
    				:setPlanetCloudTexture("planets/clouds-1.png")
    				:setPlanetAtmosphereTexture("planets/atmosphere.png")
    				:setPlanetAtmosphereColor(0.2,0.2,1.0)
    			shared_moon:setOrbit(planet1, 15)
    		
    		-- second side (right)
    			star2_x_position = star1_x_position + 95000                
    			star2_y_position = star1_y_position                        
    			planet2_x_start_position = star2_x_position + 40000
    			planet2_y_start_position = star2_y_position
    		
    			star2 = Planet():setPosition(star2_x_position, star2_y_position)
    				:setPlanetRadius(5000)
    				:setDistanceFromMovementPlane(-2000)
    				:setPlanetAtmosphereTexture("planets/star-1.png")
    				:setPlanetAtmosphereColor(1.0,1.0,1.0)
    			
    			planet2 = Planet():setPosition(planet2_x_start_position, planet2_y_start_position)
    				:setPlanetRadius(3000)
    				:setDistanceFromMovementPlane(-2000)
    				:setPlanetSurfaceTexture("planets/planet-1.png")
    				:setPlanetCloudTexture("planets/clouds-1.png")
    				:setPlanetAtmosphereTexture("planets/atmosphere.png")
    				:setPlanetAtmosphereColor(0.2,0.2,1.0)
    			
    			planet2:setOrbit(star2, 120)
    		
    end
    

    Add the following in the update() function.
    
    function update(delta)
    	-- moon hop between planet check
    		
    		-- get distance to planet 1
    		distance_to_planet1 = distance(planet1, shared_moon)
    		-- get distance to planet 2
    		distance_to_planet2 = distance(planet2, shared_moon)
    		
    		if moon_orbit_owner == 1 and distance_to_planet2 < distance_to_planet1 then
    			moon_orbit_owner = 2
    			shared_moon:setOrbit(planet2, 15)
    		elseif moon_orbit_owner == 2 and distance_to_planet1 < distance_to_planet2 then
    			moon_orbit_owner = 1
    			shared_moon:setOrbit(planet1, 15)
    		end
    
    end
    
    

    Give that a try! Enjoy!
  • edited November 6
    Next, I wanted to experiment with a black hole being able to capture a body a little further away and then draw it into itself like a whirlpool. I intend to expand on this basic idea, but here's at least the first part. And I definitely want the objects to accelerate as they get closer to the black hole; currently they appear as if to slow down. Will hopefully get to that soon.

    Note that you create the bodies in the init() function, then move them in the update(delta) function.

    Also note that you must "require("utils.lua")"
    
    require("utils.lua")
    
    function init()
    	-- WHIRLPOOL OF DEATH TEST
    		-- the basic idea is to create a curving "whirlpool" that captures stuff and spirals them inward towards a black hole 
    		
    		whirlpool_bh_x_position = 0
    		whirlpool_bh_y_position = 0
    		
    		whirlpool_blackhole = BlackHole():setPosition(whirlpool_bh_x_position, whirlpool_bh_y_position)
    		
    		-- the travel time is the number of seconds that a single nebula should take from the start position to get to the black hole
    		travel_time = 30
    		
    		-- tt_iterations is simply the travel time multiplied to account for the number of times that the update function is called per second
    		tt_iterations = travel_time * 60
    		
    		-- the degree of coverage is the heading where the nebula begins the spiral journey; for now, must remain < 360 to keep the math simple
    		degree_of_coverage = 315
    		current_degree_angle = degree_of_coverage
    		
    		-- the radius distance will be calculated from the whirlpool_blackhole position
    		radius_distance_to_start = 80000
    		current_radius_distance = radius_distance_to_start
    		
    		-- the delta_radius_distance is the amount of radius shrinkage that needs to occur for each call of update in order for the nebula to 
    		-- arrive at the blackhole in the travel_time specified
    		delta_radius_distance = radius_distance_to_start / tt_iterations
    		
    		-- delta_degrees is the amount of travel around the spiral that the nebula must travel each call of update in order for the nebula to arrive 
    		-- at the blackhole in the travel_time specified
    		delta_degrees = degree_of_coverage / tt_iterations
    		
    		test_traveling_nebula = Nebula()
    		
    		-- it appears that the 'setCirclePosition' function treats the X axis of the unit circle as the 0-180 axis, with 0 being to the right; not sure why this is
    		-- 0 should be straight up the Y axis (need to consider adding a corrected function to utils.lua)
    		setCirclePos(test_traveling_nebula, whirlpool_bh_x_position, whirlpool_bh_y_position, degree_of_coverage, radius_distance_to_start)
    	
    end
    

    Add the following in the update() function.
    
    function update(delta)
    	-- WHIRLPOOL TRAVELING NEBULA update
    		
                    if test_traveling_nebula:isValid() then
    			-- first decrement both the radius distance and the degree angle
    			current_radius_distance = current_radius_distance - delta_radius_distance
    			current_degree_angle = current_degree_angle - delta_degrees
    			-- setCirclePos(obj, x, y, angle, distance)
    			setCirclePos(test_traveling_nebula, whirlpool_bh_x_position, whirlpool_bh_y_position, current_degree_angle, current_radius_distance)		
    		end
    end
    
    

    Give that a try and watch a nebula spiral into a black hole. Quite satisfying! Enjoy!
  • Awesome, I stealing this to go with my Plasma Storm :)
  • edited November 7
    Question - I'm not sure about the "DistanceFromMovementPlane" attribute, and I'm probably using it wrong in the examples above. Can anyone help me out and give me a clue? I searched this site as well as the wiki and couldn't find anything definitive on it.

    Thanks in advance!
  • That's simply the "z" position. Hench, the distance from the plane where the other objects move.
  • Aha! Yes, now that makes sense. Thanks Daid!
Sign In or Register to comment.