Weighted Diagrams For (Procedural) Map Generation

Hello and welcome back to another guide!

Disclaimer

This guide was produced by Toothless Inc Corp. This is not recommended with anybody with brain age less than 13. Symptoms from this guide may include crashing out, rage-quitting and a weird feeling of saying brainrot. If you are experiencing any of these conditions call 111-111-1111 for Brain rot help and 111 to patch you in with the nearest mental asylum. We are not responsible for any of these symptoms. Report bugs if found.

Table of Contents


How Does It Work

Purpose of This

Breakdown

Properties

First Trigger Code

System Generation

Are We Done?


Today, Iā€™ll be teaching you how weighted diagrams can be used with generation [1].

If youā€™re not that great with blocks this guide is not for you leave Iā€™ll do my best to help you understand this.

How does it work?

Basically, the idea is that with weighted diagrams, we can randomize values for nodes or/and edges [2] and use them with random generations.

Anyways, explaining time now.

  • Nodes:
    Nodes can be thought of as these dots on the weighted diagram. A good example would be cities in a map. Each city is a node.
  • Edges:
    Edges are lines that connect nodes together. You could think of them as roads connecting cities.
  • Weights:
    This part will be very important, as a number is assigned to the edge or node representing a certain aspect [3]

Now that you have a small understanding of what these do, Iā€™ll provide some gaming examples that use weighted diagrams while randomly assigning a value.

  • Minecraft:
    Minecraft contains something like a grid, in which values are assigned which can dictate what type of biomes it is like Grassland, Mountain, Desert and so on. Values in the nodes (biomes) could dictate certain aspects like possibilty of spawned mobs, difficulty traveling terrain and what types of loot in chests are available. In fact, weighted graphs are also used in pathfinding with mobs [4].
  • Tower Defense Games:
    Think Plants Vs. Zombies. You could imagine the tiles as the nodes such as areas where the plants are placed. Edges could get varying numbers that can say what types of zombies appear [5].
  • Dungeon Crawler:
    The nodes here could be considered as the rooms and the edges could be pathways connecting them. Randomized values for edges could determine difficulty of pathways, the type of monsters that appear. And randomized values for the nodes could choose what type of loots are available.

Hopefully youā€™ve got a good idea about their use.

Purpose of this

The reason I made this guide is because a while ago there was a research topic about True Random Generation | Theory. However,

This guide is for that ā€˜other areaā€™.


Breakdown

Yes! I love this part, simplifying the steps to make it easier to understand.

  • Node/Edge Randomization:
    Weā€™ll need to make the code that will give us that random value, right? Then weā€™ll have to assign it to the certain scenario it affects. I will provide code for both Node and Edges, but you donā€™t have to do both, you could just go with Nodes or Edges or even ignore both as there is another part for generation that I will mention. Note this isnā€™t exactly like procedural generation.
  • Procedural Generation:
    If youā€™ve ever heard of minecraft, you probably know it uses procedural generation. Initially, I wasnā€™t going to do this. But after doing some math based on how much memory is wasted with one such scenario [6], I decided that using it, I can keep updating new chunks so that it isnā€™t like a bunch of memory shelved, but constantly taken out and placed back so we get constant map generation if that makes sense.
  • Weighted Graph:
    Iā€™m still going to use this so that we can generate the biomes and other scenarios if you want. The procedural generation part will just ā€˜deleteā€™ all the props and devices we added and run the Node/Edge Randomization again so we can generate a new set of the map.

The Idea

Imagine we have 4 zones. And youā€™re in the zone with the * in it. Each zone has a different biome in it, the * zone might be a mountain area, the one next to it is grassland, below the * zone is a desert, and the one next to that is a tundra.

------------------------------
|   Mountain  |  Grassland   |
|  *          |              |
------------------------------
|  Desert     |     Tundra   |
|             |              |
------------------------------

With this, the program was run and generated the biomes and all the other stuff that was to be generated in it. Nice right? Now letā€™s say that you leave the * zone area and head toā€¦letā€™s call it the # zone.

------------------------------
|   Mountain  |  Grassland   |
|  *          |              |
------------------------------
|  Desert     |     Tundra   |
|       #     |              |
------------------------------

Now, in this case, when we leave the zone, it will ā€˜deleteā€™ all the props, loots, and everything else. Then it will re-run the code and recreate an entirely new biome, say now we have an ocean.

------------------------------
|   Ocean     |  Grassland   |
|  *          |              |
------------------------------
|  Desert     |     Tundra   |
|       #     |              |
------------------------------

With this, we can recreate the procedural generation, and constantly use our biomes in a way that it isnā€™t just memory locked away, but placed in the game and then removed.

For now, Iā€™ll just include the code for node randomization because the edge randomization shouldnā€™t be too important as with the zones being extremely close to each other, I donā€™t think itā€™d matter.

Anyways, letā€™s get started!


Properties

Okay, Iā€™ll pull a Slim here and include all the properties right now

Property Name Property Type Property Value
nodesForRandomizing Text A,B,C,D,E,F,G,*
index Number 0
scenarios Number 0
regenerationIndexNum Number 2
A# Text

*[7]
Anyways, we will now start Bob the builder building!
#[8]


First Trigger Code

Ok, youā€™re going to want to grab a trigger and have it invisible and not be activated when stepped on. This code will create the entire world so youā€™d probably want to wire a life-cycle to this so it can activate when the game starts.

Have the trigger trigger and broadcast when triggered on repeatNodeRandomization2. Now, make a new block and place this code in.

Gulp, thatā€™s uhā€¦a lot of code over there. Nowā€¦I have to make the preformatted versionā€¦:sob: Here it is.

If get property "scenarios" = 3
   do Set Property: "scenarios"
      Value: 0
else 'set nodeRandomization to' Get Property "nodesForRandomizing"
   if in text `nodeRandomization` find first occurrence of text "," != 0
   do Set Property: "index"
      Value: in text `nodeRandomization` find first occurrence of text ","
   'set index to' Get Property "index"
   Set Property: "nodesForRandomizing"
      Value: create text with: 
           item: in text 'nodeRandomization' get substring from first letter to 
                         letter #: ['index'-1]
           item: Convert Number To Text (WC) random integer from 1 to 3
           item: in text 'nodeRandomization' get substring from letter #:
                         ['index' + 1] to letter # 'index'
   Broadcast Message On Channel: create text with:
                               item: create text with Get Property "scenarios"
                               item: in text Get Property "nodesForRandomizing" 
                                   get substring from letter # ['index'-1] to 
                                   letter # 'index'
   else
   Set Property "nodesForRandomizing"
   Value: "A,B,C,D,E,F,G,"*
   Set Property: "scenarios"
   Value: [Get Property "scenarios" + 1]
   Set Property: "index"
   Value: 0

[9]
25 min and 1 tired mind later, this is your code! Now, what does it do? Ahā€¦Iā€¦donā€™t know. So Iā€™ll turn it to the block enthusiast.

Block Enthusiast:
From this, basically what happens is that we check if our scenarios is = 3. What does this mean? Well first of all, scenarios is used to choose different aspects of a biome. Say one is for the type of prop, the other is for the type of enemy. Iā€™ll explain this later since there are more parts for you to understand.

Anyways, we make a ā€˜nodeRandomizationā€™ variable, in the else area, that is based off of nodesForRandomizing. Then, we add another if that checks if we have a ā€œ,ā€ in our property. Basically for now, all you need to know is that if we have a value like A,B,C,D, itā€™ll check the index value of the first comma it finds and sees if itā€™s != to 0. We want commas to be present so we can assign a random number to choose the aspect, if there isnā€™t a comma, weā€™ve gone through all the nodes (A,B,C,D,) and given them their respective numbers. Then we grab our index property [10] and set it to the value of the index of our first comma, which in this case is 2. Then make an ā€˜indexā€™ variable based off of the index property.

Here is where our good old friend concatenation really kicks in. Weā€™re going to recreate our nodesForRandomizing value to include a randomized number. So, weā€™ll grab all the text before the comma, replace the comma with a randomized number between 1-3* and add the rest of our string. Now, this might sound a little confusing so Iā€™ll give you a visual. We have our A,B,C,D, string right? Well, we find the first comma index and use it as the value for index which is 2. Then, we grab all the letters before the comma. So, just A. Then we add a randomized number, letā€™s say 2. Now we have A2. Finally we grab everything from an index after the comma all the way to the last letter, so we get A2B,C,D,. Hopefully you understand and the process keeps repeating until we get something like this, A2B1C3D2. Then we broadcast a channel that includes our scenario and the node we were randomizing for. So if during our code we replace the comma after A to 2, hence A2. Weā€™d broadcast that from the code since weā€™re grabbing all the letters 1 before index, which in this case yet again, is 2.

Now, I know you might still be confused what the scenarios and randomized letters do, so Iā€™ll give you a visual.

1. (Biome Type)
   1A1: Winter
   1A2: Spring
   1A3: Fall

Basically, the 1, (Biome Type), but more importantly just the 1 is our scenario. Here, it dictates the theme of the biome. the 1, 2 and 3 after A are the type of biomes. So 1 after A would mean all the winter props would activate. See what I mean?

Anways, we then broadcast on saveChannelnode which will be explained later. Then, in our else section (the if was huge), we first of all reset our nodesForRandomizing to itā€™s original form so that way we can repeat the process. Then, as expected, we increase our scenarios by 1, so we can randomize a new aspect. We also reset our index.


System Generation

Wow, thanks for that explanation. Anyways, now letā€™s get into making our system generation.

First, grab the same amount of zones as you have nodes in you nodesForRandomizing. A,B,C, would result with 3 zones while A,B,C,D, would have 4.

This partā€¦erā€¦I canā€™t really help you with. Since itā€™s your choice what scenarios you want to choose, you have to incorporate everything into your map. That means quests, loots, enemies and all that stuff. For now, I can help with props since itā€™s a universal thing to have in any game. So, have ALL your props not visible on game start. Typically your entire map is empty at the beginning and assumes an identity during that generation process.

So, have your props be activated by their channels.Remember that visual on Scenarios?

1. (Biome Type)
   1A1: Winter
   1A2: Spring
   1A3: Fall

So, have all props related to winter be activated by 1A1, all Spring props by 1A2 and so on. Remember, customize! This is not set in stone. Make sure that each area of props (props in zone A, zone B, zone C etc.) is hidden on their own universal channel. All props in zone A might disappear on regenerateA, zone B has regenerateB and so on. That way we can reset the entire biome for recreation. Youā€™d want to have that channel broadcasted when we leave the zone, so make sure to add that.

Now, make a trigger for each zone. Then wire them, since we want to repeat this process multiple times until we completely regenerate our area. You know the drill, make a block, add the code, pre-formatted version below.

Broadcast Message On Channel: create text with
                              Item: Get Property "scenarios"
                              Item: "A"
                              Item: random integer from 1-3
Set Property: "scenarios"
Value: [Get Property "scenarios"+1]

Hopefully you can tell from the code from before that weā€™re basically recreating a broadcast channels to randomize a new set of props. Make sure to change that ā€œAā€ for each trigger, so the other one might be for ā€œBā€.


Are We Done?

Ha! Absolutely not. This part still has so many unknown bugs. I mean, the only thing I randomized was props! What about quests? If you were in the middle of a quest and left the biome, would you lose the quest? How would you save it? There is still so much to debug. I wouldnā€™t mind people discussing how we can expand on this or making a research theory on this. I wonā€™t, Iā€™m tired and not in the mood.

Well, I think thatā€™s about it. Uh, hereā€™s a difficulty poll I guess. Please donā€™t vote 11 for fun.

Difficulty
  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11?
0 voters

Stay curious.

Oh wait, did I do good with explaining? Thatā€™s my goal with these types of topics, making them understandable to everyone else.

Explanation
  • You did good!
  • I mostly understood
  • Half was gibberish
  • Go easy on me, Grammar levels of a kindergarten
  • Who wrote this? An alien?
0 voters

  1. Ok, Iā€™ll be quick with this. The reason this isnā€™t going into my Map Generation Guide is because first of all, that is for platformer, this will be more towards top-down. Secondly, that guide has a different way for map generation, which is different from the one Iā€™m making currently. ā†©ļøŽ

  2. more on these later ā†©ļøŽ

  3. They could represent the difficulty level of an area, the type of loot that is available in the nodes, what type of biomes might be connected via edge etc ā†©ļøŽ

  4. This requires Dijkstraā€™s or A* algorithm along with the weighted graph so donā€™t get too excited about this. Also rememberā€¦sentries canā€™t walk ā†©ļøŽ

  5. Are they fast? Do they have protection? Are they a special type of zombie? Are the weak? Etc ā†©ļøŽ

  6. Imagine 4 nodes, each randomizes a number between 0-3 to choose what type of biome it it. Iā€™d have to make 16 biomes for each of them, and each game would only have 4 active. What a waste of memory! ā†©ļøŽ

  7. Welcome! If youā€™re reading this, you either saw the asterisk and make the connection or your curiosity opened this without any thinking that this could be a virus. Very disappointed. Anyways, that asterisk you saw earlier means that the value can be toggled. You could instead set it to A,B,C,D, without messing up the system. I will include the * whenever there is an area you can toggle. This will include all broadcasts also so I wonā€™t include it. ā†©ļøŽ

  8. Hello again! Hopefully this time you made the connection or thought about the virus. Doesnā€™t matter anyway, youā€™re still getting it :microbe:. Anyways, that # means that those letter properties are based on what you put in your nodesForRandomizing. So if you put A,B,C, youā€™d have 3 properties named A B C. Now, if you added a D to it youā€™d also make a D property. Good thing for you, all these properties are texts and have nothing in their default value. ā†©ļøŽ

  9. Just a note, those differentS broadcast channels DONā€™T mean anything. That is just for debugging. Also, some pieces of text had ā€˜around itā€™. That means it was a variable and not a property. Also ignore the saveChannelnode one. I just discovered that I was working on an unnecessary part for daysā€¦so Iā€™m mortally sad. Anyways, that channel should be ignored. ā†©ļøŽ

  10. The index property is how weā€™ll replace all the commas in this string with our randomized number. ā†©ļøŽ

12 Likes

Itā€™s great that youā€™ve figured out map generation!
Thisā€™ll be so cool!

The formatting and writing and length and quality of this guide is really, honestly impressive. Excellent job.

It demonstrates a great understanding of Markdown as well lol.
Iā€™m going to remove ideas though haha.

3 Likes

Wha? I added ideas? Iā€™m looking and it was there. I have no memory of adding it. :sweat_smile: this must have really sapped my energy.

You didnā€™t do it, it was added because twofour implemented a system where topics mentioning the word ā€œideasā€ are tagged with ideas automatically lol. I donā€™t know if he can but Iā€™ll ask him to disable it so that wonā€™t work for Community Made Guides.

5 Likes

This is an amazing guide, and so well explained! Genius idea, too. I might use this for one of my maps, so thanks for that.

You might want to add dropdowns to make it more compact

2 Likes

Yet another genius guide by Toothless.

It kinda works for people over 13 too ngl.

Nice guide!
Itā€™s kinda long and not that easy to navigate. Could you link the headings and put them in a table of contents?
Or put dropdowns?
Other than that, this is awesome, the way you explained it is great, and it deserves every bit of attention it gets.

1 Like

Thatā€™s what Iā€™m figuring out

1 Like

Do you know how?

Hello

I can do it for you if you want but you can probably figure it out. Just copy the links from the left of the headers.

:+1:

2 Likes

I think turtle told me a while back, soā€¦Iā€™m trying. If I canā€™t thenā€¦I might have to ask someone again.

1 Like

Thanks, iā€™d like to be a bit more hands on with this so Iā€™ll try.

How would I change them? In your Compendium, you have
Introduction

Concept

Stuff like that, I canā€™t figure out how to change it.

he, nevermind, figured it out,

1 Like

Okay mini-guide time.

  1. Open two tabs, each with your guide.
  2. On one tab, start to edit the topic.
  3. On the other, click the first headingā€™s link icon. The page will snap to view with that heading at the top. Once thatā€™s happened, copy the url.
  4. Back in the topic composer, make a Markdown url. Here, this is what your first one will look like:
[Disclaimer](https://forum.creative.gimkit.com/t/weighted-diagrams-for-procedural-map-generation/146554#p-778284-disclaimer-1)
  1. Repeat the proccess for each header.

Well uhā€¦ at least someone else might see this and itā€™ll help them, glad you figured it out. I guess I didnā€™t see that sorry lol.

3 Likes

Yeah thanks.
:+1:

Summary

Come on! This is feeling very counter productive. Why did I even make this lol. :smile:

I also decided to add an explanation poll. If you want to give me feedback on how to improve this (explanation wise), vote and tell me.

2 Likes

Hands down, this is a real good and lengthy explanation of a guide. It has some nice jokes-

No comment.

Anyway nice guild.

1 Like
.

ā€œguildā€

Wow, actually. This is one of the few things that can be actually considered a good guide.

Iā€™d say more, but Iā€™m sure its already been said.

You did good, Congrats,

3 Likes