Skip to content

Instantly share code, notes, and snippets.

@KWKdesign
Last active August 29, 2015 14:14
Show Gist options
  • Save KWKdesign/98082ea34381d401cf13 to your computer and use it in GitHub Desktop.
Save KWKdesign/98082ea34381d401cf13 to your computer and use it in GitHub Desktop.
Schemaverse Galaxy Map Generation
-- example image: http://imgur.com/9eGABd6
/*
-- map generation variable declarations
r numeric;
a numeric;
b numeric;
turns int := 1; -- values >= 1
arms int := 4;
loc point;
*/
-- map generation script
a := coalesce( get_numeric_variable( 'UNIVERSE_CREATOR' ), 6750000 )::numeric;
<<planet>>
while 1=1 loop
r := random() * ( a - ( a / turns / arms ) );
if r > a / 2 / pi() then -- point on spiral
-- get angle from r and seperation ( reverse r = b * theta )
b := r / ( 2 * a / turns / arms ) * pi();
-- convert polar to cartesian
loc := point( r * cos( b ), r * sin( b ) );
-- get random angle for scattering along arm
b := random() * 2 * pi();
-- get random distance from arm
-- cluster towards center of arm by squaring random value
r := pow( random(), 2 ) * a / turns / arms / 2;
-- apply transform
loc := loc + point( r * cos( b ), r * sin( b ) );
-- get angle of rotation for random arm
b := 2 * pi() * ceil( random() * arms ) / arms;
-- apply 2d rotation
loc := point(
loc[0] * cos( b ) - loc[1] * sin( b ),
loc[1] * cos( b ) + loc[0] * sin( b )
);
else -- point on center disc
b := random() * 2 * pi();
loc := point( r * cos( b ), r * sin( b ) );
end if;
loc := point( round( loc[0] ), round( loc[1] ) );
continue when exists (
select 1 from planet
where circle( location, 1 ) <@ circle( loc, 2 * get_numeric_variable( 'MAX_SHIP_RANGE' ) )
);
insert into planet ( id, fuel, mine_limit, difficulty, location, location_x, location_y )
values (
nextval( 'planet_id_seq' ),
greatest( ( random() * 1000000000 )::int, 100000000 ),
greatest( ( random() * 100 )::int, 30 ),
greatest( ( random() * 10 )::int , 2 ),
loc, loc[0], loc[1]
);
-- exit planet when ( select count(1) from planet ) >= ( select count(1) * 1.05 from player );
exit planet when ( select count(1) from planet ) = 2100;
end loop;
-- give names to new planets in non-repeating series
update planet
set name = ( case row_number % 12
when 0 then 'Aethra'
when 1 then 'Mony'
when 2 then 'Semper'
when 3 then 'Voit'
when 4 then 'Lester'
when 5 then 'Rio'
when 6 then 'Zergon'
when 7 then 'Cannibalon'
when 8 then 'Omicron Persei'
when 9 then 'Urectum'
when 10 then 'Wormulon'
when 11 then 'Kepler'
end ) || '_' || ( ( row_number / 12 ) + 1 )::text
from (
select row_number() over ( order by random() ) - 1 row_number, id
from planet
where id <> 1
and name is null
)a
where planet.id = a.id;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment