• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Procedural generation problem

This question is a bit complicated.
Basically, I'm trying to make a game where you can explore a randomly generated galaxy, kind of like No Man's Sky, only in 2D and it's more turn based strategy instead of real-time.

Currently, I have the game randomly place 200 star systems around a map.
I'm storing the data for each system in an array so I can reference certain properties in other places.
There are 5 variables for each system that define their name, position, and whether or not you have discovered them.
Code:
global.map_seed = random_get_seed();
/*
Systems Array 
0 - System Name
1 - x
2 - y
3 - visited
4 - seen
5 - System seed
*/
//Generate Galaxy (place systems)
for (i=0 ; i<200 ; i++)
    {
    global.systems[i,0]="System "+string(i);
    global.systems[i,1]=round(random_range(64,4096-64));
    global.systems[i,2]=round(random_range(64,4096-64));
    global.systems[i,3]=false;
    global.systems[i,4]=true;
    }
The 6th variable is the random seed dedicated to the system. When I assign the seed to a system, it will load this seed and generate the same planets in that system every time you go there.
Code:
//Set System Generation Seeds
for (i=0 ; i<200 ; i++)
    {
    randomize();
    global.systems[i,5]=random_get_seed();
    }

random_set_seed(global.map_seed);
All of that happens at the start of the game before anything else.

After it generates the systems, another object places them in the room using this code:
Code:
//Place Systems
for (i=0 ; i<200 ; i++)
    {
    sys = instance_create(global.systems[i,1],global.systems[i,2],obj_icon_system);
    sys.name=global.systems[i,0];
    sys.discovered=global.systems[i,3];
    sys.sys_id = i;
    sys.seen=global.systems[i,4];
    }
Now, the map screen looks like this:

That arrow represents your ship and you can move around by clicking.
When you go to a system, it takes you to a different room where it generates the planets inside the system. Before taking you there, it sets a variable global.current_system to the variable sys_id of that system. This way, it will be able to find the correct random seed in the array global.systems.
Here's the code I'm using to generate the planets. Right now I'm not really sure if I need to use another array for the planets, but whatever.
Code:
//Get system Seed
random_set_seed(global.systems[global.current_system,5]);

//set number of planets
planet_num = choose(1,2,2,3,3,3,4,4);

/*
Planet Properties
0 - Name
1 - Type 0=terrestrial 1=gas giant
2 - Landscape 0=forest 1=jungle 2=desert 3=ice 4=volcanic
3 - radius
*/

//Generate planets
for (i=0 ; i<planet_num ; i++)
    {
    planets[i,0] = "Planet "+string(global.current_system)+string(i); //name
    planets[i,1] = choose(0,0); //type
    if (planets[i,1]==0) //landscape
    planets[i,2]=choose(0,1,2,3,4);
    planets[i,3]=112+(76*i);
    }
   
//Place planets
for (i=0 ; i<planet_num ; i++)
    {
    n = instance_create(obj_sun.x,obj_sun.y,obj_planet);
    n.radius=planets[i,3];
    n.orbit_speed=choose(0.05,0.1,0.12);
    n.dir=round(random(360));
    n.x+=lengthdir_x(n.radius,n.dir);
    n.y+=lengthdir_y(n.radius,n.dir);
    n.image_speed=0;
    //choose image
    if (planets[i,1]==0)
    n.image_index=planets[i,2];
    }
It uses dir to basically pick a random rotation around the sun so the planets don't all spawn in a straight line.
So after generating the planets, the room would look something like these:

So each star system generates a different arrangement of planets, and if you leave one and come back it will generate the same planets it had before.

Here's where my problem starts.
Most of the time, it works exactly how I want it to. But sometimes it generates the same planets no matter which system I go to. What happens is I'll run the game, and it will generate everything as expected. After closing and running the game again, every system will generate the same arrangement of planets. After running and ending the game a few more times or clearing the asset compiler cache, it will go back to normal, but it never stays normal.
Every time this happens it uses the same seed: 2147483648.

I thought maybe the game was saving the same seed to the array global.systems in the beginning where it generates the system data, so I displayed a list of the seeds on the screen while the game was generating the same system over and over, but all the seeds were different like I expected.
I also considered the possibility that the game thinks you're trying to go to the same system, so it continues to pick the same seed. But if that's the case, then why would it always pick 2147483648?.

The most frustrating thing about this is that the game works as expected half the time and the other half it does not.

So do any of you have any ideas on why this might be happening? I hope I was clear on everything and provided enough information.

And feel free to constructively criticize my coding techniques. I don't call myself a good programmer and there are probably way simpler ways to do this!
 

johnwo

Member
Every time this happens it uses the same seed: 2147483648.
Like it says in the manual:
NOTE: This function will return the same value every time the game is run afresh due to the fact that GameMaker: Studio generates the same initial random seed every time to make debugging code a far easier task. To avoid this behaviour use randomize at the start of your game.
([I might have misunderstood the part above] If the the problem occurs ONLY when this seed is used, then I apoligize. If the seed is the ONLY seed that is used, then I refer to the documentation.)

The most frustrating thing about this is that the game works as expected half the time and the other half it does not.
Have you tried creating an executable and checking if the results are consistent when using the exe?

I get what you are trying to do, but I would strongly suggest that you just randomize, generate, then store and load the systems/map from an array or list accordingly.
Saving/loading the map and systems within the map would get rid of the need to generate them each time you visit them, and it would ensure that the systems/map stays consistent, as the map_seed would be the only factor involved with the generation, and it would only be done once at the start of a new game.

Cheers!
 
Thanks for the reply!
So I have it set up so the first seed that Game Maker uses is used to generate the map (global.map_seed). It's easier to test that way. But then it randomly picks a seed for each of the systems. The problem is that SOMETIMES it only uses that one seed to generate planets instead of the seed assigned to that system, and other times it works properly. So it might work properly when I run the game one time (the game will load the correct seed before generating the planets), but if I exit and restart it might only generate according to 2147483648 (it's always that seed), but it will still use the first seed to generate the map, which is 0 because I did not tell Game Maker to randomize(). What's strange to me is how this happens very inconsistently.

Generating the planets and then storing them was actually the first thing I tried to do, but when I tried to run the game it instantly crashed with no error. I might have to store them in a .ini or something, but I'd like to figure out why this method isn't working before I rewrite a lot of code.
I also just tried exporting and running the .exe but that didn't change anything.
 
M

MasterGrey

Guest
You have some nice code there

Im trying to see if i could try and combine it together with this script

Code:
galaxy_radius = 20000;
num_arms = 6;
num_stars = 2000;

spiral_tightness = -4; //higher number = more tight, negative reverses direction of spiral

//the nearest any 2 stars can be to each other
//danger of infinite loop if this number is too high
min_star_seperation = 5;

//the maximum distance a star can be from its spiral arm
max_star_displacement = 20;

//how much stars bunch toward center of galaxy
//lower numbers bunch toward edge, higher toward middle, 0.5 = no bunching
bunching = 1;

//how much stars bunch toward the spiral arm they are in
//lower numbers bunch toward edge, higher toward middle, 0.5 = no bunching
bunching_2 = 5.8;

//no need to touch these
arm_radial_spacing = 360 / num_arms;
random_interval = power(galaxy_radius,1/bunching);
random_interval_2 = power(max_star_displacement,1/bunching_2);

randomize();
var star_placed, arm, dist, dist2, angle, xx, yy, nearest_star;
repeat (num_stars)
{
    star_placed = false
    do
    {
        arm = irandom(num_arms-1);
        dist = power(random(random_interval),bunching);
        angle = (dist + dist) * spiral_tightness + arm * arm_radial_spacing;
      
        xx = random_range(-1,1);
        yy = random_range(-1,1);
        dist2 = power(random(random_interval_2),bunching_2) / point_distance(0,0,xx,yy);
  
        xx = x + lengthdir_x(dist,angle) + xx * dist2;
        yy = y + lengthdir_y(dist,angle) + yy * dist2;
        nearest_star = instance_nearest(xx,yy,object_star_universe_new1);
        if (instance_number(object_star_universe_new) == 0) or (point_distance(xx,yy,nearest_star.x,nearest_star.y) > min_star_seperation)
        {
            instance_create(xx,yy,object_star_universe_new1);
            star_placed = true;
        }
    }
    until (star_placed)
}

So what im trying to do is that everytime the player ship moves in the universe he has to discover stars and there will be speical names to them

So what im trying to do here is that everytime you find a star and click on it it will generate the system and planets .


If its fine with you can i please use this code...............................


Plus its a galaxy generation code feel free to use it you only have to ask or so.................

another plus any help would be nice again i think your on to something here but im trying to see if i could imply it to my own galaxy generation code.
 
Last edited by a moderator:
Yeah it's probably a good idea to put it in scripts. I've since decided to basically start from scratch in GMS2 at a later time because basically my entire project is a mess. A lot of the code I used to draw menu screens is inconsistent and should be using scripts to draw similar elements. It was an ambitious project that I know I can do, but it needs more planning and organization. I planned on having turn based combat elements and all kinds of upgrades for your ship and stuff too. I'm working on other stuff now while also figuring out what is going to work for this game, what I need to replace, and what I need to scrap.

Edit: Also yeah you can use the code. I'm probably going to rewrite it anyway
 
M

MasterGrey

Guest
Do you know how i can add this together with my script because my script generates the galaxy but it dosent store it and it dosent have a name for the stars

Im working on the planet random terrain but this is confuseing me if you could tell me how i can combine it together it will appreciated.

my galaxy
29qGMLZ13131.png
 
I think you can have each solar system generate a new random seed from the seed used to generate the galaxy. Make sure to store the seed used to generate the galaxy so you can generate the same one again. For star names, you can use a name generator. That's what I planned on doing and there should be a few tutorials on youtube. Then for planet terrain I guess you can basically do the same thing, but one level down.
Sorry I cant really help you out any more than that.
 
Hey, is your gamemaker studio up to date? Because that number 2147483648 was encountered a lot by people when gamemaker used different levels of precision between getting and setting seeds. I believe it was fixed a while ago.
 
M

MasterGrey

Guest
Hey, is your gamemaker studio up to date? Because that number 2147483648 was encountered a lot by people when gamemaker used different levels of precision between getting and setting seeds. I believe it was fixed a while ago.
Hey Hows it going my man you saved me with that script my man.



Plus i would love to see how i would implment this with flyingsaucers code he gave me

Because it would be a random system when you left click with random planets.

Also sorry for my spelling my good sirs.


Another plus my galaxy dosent generate on a seed witch is a shame but because flying saucer made this code and im modifying it he would assist.





But however your code is usefull in the systems area random star systems will be a breeze after i modify it hopefully to my liking.

But because you only added 1 planet i might need to change it from other planets to just a single planet object.




Plus i changed it to this

Code:
var i
for (i=0 ; i<script_galaxy_generate();  i++)
    {
    global.systems[i,0]="System "+string(i);
    global.systems[i,1]=round(random_range(64,4096-64));
    global.systems[i,2]=round(random_range(64,4096-64));
    global.systems[i,3]=false;
    global.systems[i,4]=true;
    }
Another progress report i think i found a way to do this thank you for the code your usefullness has came to a end kiddos goodbye AHAHAHAH.


Maybe i was too fast to say this but i have a issue with the code it says varible not set before reading

And this is for global.current_system


I know what it means but i dont know what code to add to it this isnt my code so im ???????
 
Last edited by a moderator:
Top