I think I just created the Multiverse... ;)

wonder

Expert
Licensed User
Longtime User
Fellow game developers, @ilan, @melonZgz, @Informatix, @andymc, I raise your attention to this thread. :)

Inspired by the game "No Man's Sky", where an entire Universe of fully populated galaxies is procedurally generated, I challenged myself to acheive a similar result, at least mathematically.
The main feature of No Man's Sky is that its virtual universe, including the stars, planets, lifeforms, ecosystems, and the behaviour of the space-bound factions, is created through procedural generation using deterministic algorithms and random number generators. A single seed number is used to create these features via mathematical computation, thus eliminating the need to create each of these features by hand. This enables the game to have a massively open nature: Hello Games has estimated that with their 64-bit seed number, their virtual universe includes over 18 quintillion planets.


Using B4J, I quickly drafted what I want to turn into a B4X library one day. :)
An entire universe is generated, based on a given number (using RndSeed).
Changing this number generates an entirely new universe.

Below two examples. "Matrix" and "World".

The Matrix example shows how things work under the hood.
The red squares are objects in the rendered the universe "slice" (of customizable size) that's available for the game engine/logic/cycle.
The green circle represents the center of the universe (0, 0)
The blue square represents the user's viewport (a.k.a. what the player sees).

More details on post #5.

The World example, shows how things could look like in an actual game.

More on No Man's Sky procedural generation algorithms:
https://archives.nucl.ai/recording/building-a-galaxy-procedural-generation-in-no-mans-sky/

Source code available on request.
 

Attachments

  • Matrix.jar
    317.2 KB · Views: 185
  • World.jar
    325.5 KB · Views: 152
Last edited:

ilan

Expert
Licensed User
Longtime User
This is very good.

Let say you have a big world of 2000x2000 cells but the sreen itself shows only 250x250 so instaed of drawing the whole world each frame we draw only the part that is visible. It will save memory and we could use it for other stuff like collisions calculations.

Try to put a character in the middle and move him and draw only the part the is in the blue frame that moves in relation with the character.
 
Last edited:

wonder

Expert
Licensed User
Longtime User
With this technique, the world is "virtually" infinite. There is no need for a "2000x2000 array".
In the examples I provided there is no array at all. The entire world is stored* inside a singe 32-bit integer:
B4X:
Dim seed = 12345 As Int 'Yeps, here's your entire universe! ;)

That's the beauty of using a seed, that's the beauty of mathematics. :)

In a practical sense, if you created an infinity maze game, you would still need to have some sort of data structure (like an array), to perform things like collision detection and so on. Such array would need not to be bigger than the "universe slice" that includes both the visible area and surroundings of the viewport.

In the example you gave, 250x250 for the visible area, I would use a 750x750 array for a smooth simulation. :)

*by "stored", I mean "generated from".
 

ilan

Expert
Licensed User
Longtime User
You have to store all red squars as objects in an array list so u can do with them something. I dont think u need more then 250x250 (frame size) but u will have to update your code. Now the new world is created when u reach the end of the first world u could update the world every half world and like this storing only frame size (250x250) is enugh since the character is always far away from the frame half of the world.

Or u update the world on every move (drawing part) and creating on each move only objects that are near to the character and that are relevant for the game like (colissions)

So instead of creating 80-100 objects u creat only objects that are 2-3 steps far away from the character. Like this your collisions loop would go through a very small object size. ;)

(Btw there was an error in your source. in class location there is no variable .x .y, i fixed it and its working now) good job this is a very new perspective for me in game developing.
 

wonder

Expert
Licensed User
Longtime User
You have to store all red squars as objects in an array list so u can do with them something.
In a practical sense, if you created an infinity maze game, you would still need to have some sort of data structure (like an array), to perform things like collision detection and so on.
True indeed. But this array needn't be larger than the current slice. :)

Now the new world is created when u reach the end of the first world u could update the world every half world and like this storing only frame size (250x250) is enugh since the character is always far away from the frame half of the world.

Or u update the world on every move (drawing part) and creating on each move only objects that are near to the character and that are relevant for the game like (colissions)

So instead of creating 80-100 objects u creat only objects that are 2-3 steps far away from the character. Like this your collisions loop would go through a very small object size. ;)

Here's a quick explanation of my algorithm:
- An infinite universe (*limited only by hardware) is created from a single seed.
- Unique seeds will always spawn their own unique and constant universes.
- Since there is no need (or computer power) to render the whole universe, the universe is rendered in slices.
- Each slice is comprised of 9 sectors.
- The visible area will always be the central sector (0, 0).
- The computable area is the entire slice (all 9 sectors).
- Such area (slice) can in turn be easily passed into a fixed size array.

Visual Representation:
B4X:
'Representation of a universe slice

' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' '-1 ' 0 ' 1 ' ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' +---+---+---+ ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' '-1 | C | C | C | ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' +---+---+---+ ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' 0 | C | V | C | ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' +---+---+---+ ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' 1 | C | C | C | ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' +---+---+---+ ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '

' (') The infinite universe
' (C) Computable sectors
' (V) Visible (and computable) sector

So instead of creating 80-100 objects u creat only objects that are 2-3 steps far away from the character. Like this your collisions loop would go through a very small object size.
Everything's customizable to you own taste. :)

(Btw there was an error in your source. in class location there is no variable .x .y, i fixed it and its working now)
No error. X, Y are not variables, but methods that return posX and posY in read-only form.
Look for getx() and gety() methods. ;)

good job this is a very new perspective for me in game developing.
No man's sky! No man's sky! No man's sky! No man's sky! No man's sky! No man's sky! :D:D:D
https://archives.nucl.ai/recording/building-a-galaxy-procedural-generation-in-no-mans-sky/
 
Last edited:

wonder

Expert
Licensed User
Longtime User
Why don't use Unity3D to develop those things?
I guess I could, but in the end, it's a matter of personal preference. :)

Understanding algorithms and coming-up with my old solutions is one of the things I like to most.
As I'm currently writing my own personal B4A lib in C++, this kind of experiment can become a great addition!

Plus, B4J is the fastest, portable and most reliable tool I have on the PC. <3
 

sorex

Expert
Licensed User
Longtime User
check this out (requires flash)

http://www.touch-up.be/Touch-UP/temp/landscape/

something I wrote 10 years ago and also based on perlin noise,
and 'simulates' grass hills, snowy mountain tops and underwater.

should be a lot faster with AS3 tho but it didn't exist yet back then :)
 

Cableguy

Expert
Licensed User
Longtime User
Premise: I skipped all posts (I risk the mental paralysis, otherwise :p), I only saw the video.
Why don't use Unity3D to develop those things?
(ok, I understand that you like challenges!)
Remember the Ferrari vs Lamborghini story? If Lamborghini just acepted that hé couldn't do himself, we wouldn't have the diablo!
 

LucaMs

Expert
Licensed User
Longtime User
I guess I could, but in the end, it's a matter of personal preference. :)

Understanding algorithms and coming-up with my old solutions is one of the things I like to most.
As I'm currently writing my own personal B4A lib in C++, this kind of experiment can become a great addition!

Plus, B4J is the fastest, portable and most reliable tool I have on the PC. <3

I think Unity3D in your hands would become gold (also with it your sw can run on various platforms with little or no change!).
But I allow you to do as you want :p
 

wonder

Expert
Licensed User
Longtime User
check this out (requires flash)

http://www.touch-up.be/Touch-UP/temp/landscape/

something I wrote 10 years ago and also based on perlin noise,
and 'simulates' grass hills, snowy mountain tops and underwater.

should be a lot faster with AS3 tho but it didn't exist yet back then :)
Very, very nice!!

Given that PerlinNoise returns a value between -1 and 1, how did you assign the returned value to the color codes?
I understand that values next or equal to 1 become white, but how does the transition to green (in the middle range) works?
 

sorex

Expert
Licensed User
Longtime User
it's abusing the gfx card features so it quickly generated a greyscale "cloud" where you have 256 possible levels that are your heights.

so the image is acting as a heightmap.

so a pixel of

000 would be darkblue
333 would be blue
666 would be green
999 would be darkgray
ccc would be grey
fff would be white

just create a gradient of these colors in a 256px wide image and of you go :)
 
Top