0

I’m building a Starflight-inspired 2D space exploration game with a procedural world. The gameplay is divided into different « scenes » (to use Godot terminology) to manage the different « depths » of the game. For example, interstellar flight is a scene where the star systems are simply represented by star sprites. When the player gets in range, the view is moved to the solar system scene, where the player moves his ship inside the actual solar system.

So far so good, I generate the universe (the solar systems) from a hard coded array of coordinates and seeds. Now I also want to make the universe generation procedural, but I’m guessing that loading a whole universe (there is no real limit to the number of solar systems once it becomes procedural) in memory won’t be efficient.

I’m thinking of generating the universe on the first run and saving the data to a file, but I’m wondering how to load the relevant data in an efficient way that would let me load only a certain « radius » of data around the player’s ship. I feel like it would be the way to go if I use my generation algorithms that generate « realistic » galaxy shapes, since it implies many steps of data processing (different cluster shapes are generated, arms, blobs, etc. and then stars are spinned around the center to simulate the galaxy rotation, etc.) that would be probably too long to calculate in realtime.

I’m wondering which approach I should take on this problem. It’s not really language or engine dependant, so references to generic articles and algorithms on the subject would suffice.

I also read a bit about QuadTrees and I think I’m getting to something there, but I’m not exactly sure how to use that with a file on disk.

Thanks in advance for your help!

BadgerBadger
  • 696
  • 3
  • 12

3 Answers3

2

I have some suggestions:

  • Do not generate the whole universe on the first run, generate only the areas that are somehow visible. Then, instead of loading the whole universe from disk, you just generate it whenever your spaceship (or whatever) come within view distance of that area. This makes game initialization much faster and allows an (almost) infinite universe.
  • If you want the universe to be modifiable, store only the `edits' that a player makes. So if you want to show a part of the universe, generate the part from your seed and then overlay the stored edits. This makes storage much smaller.
  • For storage on disk, have a look at R-Tree, especially R*Tree and R+Tree, they are designed for storing data in disk pages.
TilmannZ
  • 1,784
  • 11
  • 18
  • The way I was thinking of doing something inspired from Martin Evans blog, but in 2D. Use modular generators that can impact their children. For example a Sphere generator would create stars in a circular fashion around its center, an Arm generator would generate an arm shaped mass of stars. Then you put them both as children of the Galaxy generator and this generator would induce spin on the stars of its children so the galaxy would look like a spiral, etc. That’s why I thought storing the data would be more efficient. – BadgerBadger Jun 20 '18 at 16:52
  • I am having a discussion with someone on Discord and he suggested a way that would diminish the amount of precalculation for the whole universe, while letting me shape it in a realistic way and generate the surroundings on the fly. To make the universe modifiable, you suggested exactly what I wanted to do. Ill look into R*Trees right away. – BadgerBadger Jun 20 '18 at 16:54
0

as TilmannZ suggested, you should not be generating the whole dataset for the galaxy when you start the game, because there is likely no need (unless the player needs to see/interact with all the data at once - e.g. all stars). If this is the case, for example for a starmap, then you may be better loading all the data once and saving the result in an image file.

Instead, you should only genereated the data as needed around the player. The most obvious way to do this would be to construct a grid around the player, and keep this grid centered on the player as they move around. As the player moves around, you only need to update the conceptual galaxy coordinates of each cell (not the rendered coordinates). Then for each cell you can then use the coordinates as the input into a value or gradient generator like Perlin to determine what features should spawn in that location.

As for 'shaping' the galaxy or universe, one effective way is to sample the pixel data of a greyscale image of a galaxy which has the shape you want. You could load the image's RGB data at run time, and use the coordinates of your grid as you generate the stars to get the RGB value, which you can use as a density factor for the star generation; the whiter the pixel, the higher the star density at this location and visa-versa for black pixels. This method lets you effectively draw the shape of the galaxy in paint.

LintfordPickle
  • 420
  • 4
  • 13
0

Maybe think about different layers of abstractions. Each layer uses the parent layer, designer input, events & procedural generation algorithms to generate the needed data.

  • The Universe layer contains user or randomly placed galaxy polygons & types.
  • The Galaxy layers can add more details (number & density of spiral arms) or a density map.
  • A cluster of solar systems.
  • The solar system adds the stars & planets.

And only create the details for currently needed elements.

Orchaldir
  • 41
  • 6