{"author_link":"\/users\/deylinia","author_name":"Deylinia","author_uid":"deylinia","comments":[],"epoch":1588189620,"event":"LD46","format":"md","ldjam_node_id":209008,"likes":5,"metadata":{"p_key":"145534","p_author":"Deylinia","p_authorkey":"1178767","p_urlkey":"361947","p_title":"My First Ludum Dare Part 2 - Map Generation","p_cat":"LDJam ","p_event":"LD46","p_time":"1588189620","p_likes":"5","p_comments":"0","p_status":"WAYBACK","us_key":"1178767","us_name":"Deylinia","us_username":"deylinia","event_start":"1587081600","event_key":"77","event_name":"Ludum Dare 46"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD46","removed_author":false},"_superparent":176557,"_trust":1,"author":178767,"body":"This is going to be a bit more of a technical dive on the map generation in [Cacophony](https:\/\/ldjam.com\/events\/ludum-dare\/46\/cacophony-the-ballad-of-the-celestial-goblin-king).\n\nI got a bit carried away so this post is a bit long but I hope its informative!\n\n\n# Map Generation\n\nProcedural generation of maps is arguably one of the most iconic properties of roguelike games, because of this we had to make sure we got it right. As I had some experience creating a similar script in a previous unity project this task fell on me.\n\nSo I got to work.\n\nThe generation in our game is based on the methodology from a popular roguelike tutorial using a python library called libtcod. The basic process followed by this tutorial is as follows:\n\n1. Fill the specified area with walls\n2. Carve rooms out of this area by deleting walls and placing floors in rectangles\n3. Connect the current room with hallways\n4. Determine what type of room has been generated and place the proper extra characteristics within the room\n5. Repeat for the specified number of rooms\n\nThere was, however a few issues with using this tutorial namely:\n\n1. This tutorial is meant for python, not C# and especially not Unity\n2. This tutorial represented every wall with the same \u201cSprite\u201d (really a character in most cases)\n3. While I am sure they get to it eventually, the section I read did not have different types of rooms generated\n\n\n![traditionalRogue.png](\/\/\/raw\/f4a\/b2\/z\/3391b.png)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0*More traditional roguelike couresty of my co-developer Scott*\n\n\n\n\n\n\n\n![ourMap.png](\/\/\/raw\/f4a\/b2\/z\/3391c.png)\n*One of our generated maps*\n\n\n\n\n\n\n\n# Our Implementation\n\nThere are 3 main classes involved in the generation of maps in our game\n\nGridGenerator.cs \u2013 Handles the generation aspect\n\nMapInfo.cs \u2013 This is a scriptural object that contains variables used to generate the map, stores information such as the x and y bounds, the current tileset, and the list of enemies to be spawned in this map\n\nMap.cs \u2013 This class contains static dictionaries used to reference the different tile layers using their (x,y) coordinate as a key. This class is responsible for populating these dictionaries after the game has been loaded.\n\nIf you\u2019re interested in seeing the code in full for these classes [click here](https:\/\/gist.github.com\/ZacharyDangelo\/e7c33358f21636c9c7a9fb1b740bb836)\n\nThere is also a Rect class that handles some aspects of the room generation, but I don\u2019t feel this is a good implementation in its current form and would recommend against our current setup.\n\n\n\n\n# GridGenerator.cs\n\n\n\nFor the most part, this class follows the tutorial linked above to a tee. Below is some of the code that had to be handmade to have our display work properly. Essentially all this does is place the proper sprites on the edges of the room so that they can visually look better than just having a flat wall sprite.\n\n\n\n![gridgen.png](\/\/\/raw\/f4a\/b2\/z\/3391d.png)\n\n\n*It\u2019s game jam code, go easy on me*\n\nFurther down, in the GenerateMap() function we have another slight deviation from the tutorial script. We wanted to generate different types of rooms so we could have stores, traps, exits to a further floor, etc. The counter is basically a hacky way of making sure that we always generate one and only one kitchen, store, and exit.\n\nthe room variable is the room we are currently generating, this function will be called after the room has been carved out and hallways generated.\n\n\n![roomGen.png](\/\/\/raw\/f4a\/b2\/z\/3391e.png)\n\n\n*I can\u2019t explain why the usage of that counter \u2013 switch statement combo feels wrong but it does\u2026*\n\nThe functions being called on the room object belong to the Rect class, I am not sure is the best way to break up this code but it\u2019s what we came up with in the time allotted.\n\nI\u2019ll only show a few examples so you can get an idea, because this is most likely the messiest code in the entire project.\n\n![diffRooms.png](\/\/\/raw\/f4a\/b2\/z\/3391f.png)\n\n\n*Believe it or not, this is some of the better code from this section*\n\nNow, if you\u2019re reading this in hopes to learn how to do some map generation please do not copy and paste this code, it is ugly ugly ugly and one of the first things I will be refactoring but it got the job done for the time we had.\n\n\n\n\n# MapInfo.cs\n\nMapInfo is a Scriptable Object class, if you don\u2019t know what that means I spent my first post on this blog talking about them! Alternatively, you can go straight to the resources I learned from this excellent [blog post by Daniel Ilett](https:\/\/danielilett.com\/2019-10-07-unity-tips-4-scriptableobjects\/).\n\nTo sum it up real quickly scriptable objects are a Unity class that are very good for storing data independent of game objects and with very easy serialization.\n\nHere\u2019s what our usage of them looks like:\n\n![mapinfo.png](\/\/\/raw\/f4a\/b2\/z\/33920.png)\n\n\n\n*The entirety of this class*\n\nThe first section of variables lines 9-15 contains some general information about the map that will be useful to players,enemies and the grid generator.\n\nAll of the variables here are pretty self explanatory, the tiles and enemies are fed into the grid generator so that it knows what tiles to use and the boundaries determine where the map starts and stops generating.\n\nWhat this allows us to do is create a Unity asset entirely in the editor for each different tileset and set the enemies and dimensions in there without changing any code at all!\n\n\n![unity.png](\/\/\/raw\/f4a\/b2\/z\/33921.png)\n\n*An example of what this object looks like in the Unity inspector*\n\nThis is one of the better design choices we made during the jam as it allowed our map generation to be flexible even for our team members who did not know how to code.\n\n\n\n# Map.cs\n\nThis is the class that glues this whole thing together to work in our project.\n\nIt contains two dictionaries with every relevant tile that we can then access using the tiles (x,y) coordinates. This is how we handle movement, combat, and interaction with special objects.\n\nWhat this class does is quite simple but the implementation can seem a bit confusing.\n\n\n![getTiles.png](\/\/\/raw\/f4a\/b2\/z\/33922.png)\n*Thank God for stackoverflow*\n\nWhat happens is the tilemap object has a collider that scales when a tile is placed, we use this to get the x,y bounds of an this object and then we iterate every x,y position in world space and create a MapTile object (This is a data class that I will likely rewrite soon) and store it in the dictionary.\n\nMost of the time when we reference this dictionary we are checking whether the requested tile is a floor or a wall.\n\n\n# Wrapping Up\n\nAll in all, I don\u2019t think this seems like the most complex take on map generation I have ever seen and it is really a stringing together of different tutorials until we had something manageable. But it worked well for our game and most importantly we were able to get it done in the time frame we had.\n\nThis is a section of the code I spent a lot of Ludum Dare working on, and as we continue to develop the game I have no doubts this will continue to be the case.\n\nYes you read that right, we are going to continue developing Cacophony because we\u2019re all having so much fun working on it.\n\nThe first update will release the same day Ludum Dare voting ends May 12th.\n\n\n\n![space.PNG](\/\/\/raw\/f4a\/b2\/z\/33923.png)\n\n\n\nCacophony: The Ballad of the Celestial Goblin-King is a procedurally-generated roguelike dungeon crawler created in 72 hours for Ludum Dare.\n\nThe first update to Cacophony will be released May 12th.\n\nYou can try the game in your browser [here](https:\/\/dreamsteppe.itch.io\/cacophony-the-ballad-of-the-celestial-goblin-king).\n","comments":1,"comments-timestamp":"2020-04-29T20:39:55Z","created":"2020-04-29T16:38:57Z","files":[],"files-timestamp":0,"id":209008,"love":5,"love-timestamp":"2020-04-29T22:00:04Z","meta":[],"modified":"2020-04-29T22:00:04Z","name":"My First Ludum Dare Part 2 - Map Generation","node-timestamp":"2020-04-29T19:47:00Z","parent":203434,"parents":[1,5,9,176557,203434],"path":"\/events\/ludum-dare\/46\/cacophony-the-ballad-of-the-celestial-goblin-king\/my-first-ludum-dare-part-2-map-generation","published":"2020-04-29T19:47:00Z","scope":"public","slug":"my-first-ludum-dare-part-2-map-generation","subsubtype":"","subtype":"","type":"post","version":634927},"node_metadata":{"n_key":"209008","n_urlkey":"361947","n_parent":"203434","n_path":"\/events\/ludum-dare\/46\/cacophony-the-ballad-of-the-celestial-goblin-king\/my-first-ludum-dare-part-2-map-generation","n_slug":"my-first-ludum-dare-part-2-map-g","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"178767","n_created":"1588178337","n_modified":"1588197604","n_version":"634927","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/46\/cacophony-the-ballad-of-the-celestial-goblin-king\/my-first-ludum-dare-part-2-map-generation","text":"This is going to be a bit more of a technical dive on the map generation in [Cacophony](https:\/\/ldjam.com\/events\/ludum-dare\/46\/cacophony-the-ballad-of-the-celestial-goblin-king).\n\nI got a bit carried away so this post is a bit long but I hope its informative!\n\n\n# Map Generation\n\nProcedural generation of maps is arguably one of the most iconic properties of roguelike games, because of this we had to make sure we got it right. As I had some experience creating a similar script in a previous unity project this task fell on me.\n\nSo I got to work.\n\nThe generation in our game is based on the methodology from a popular roguelike tutorial using a python library called libtcod. The basic process followed by this tutorial is as follows:\n\n1. Fill the specified area with walls\n2. Carve rooms out of this area by deleting walls and placing floors in rectangles\n3. Connect the current room with hallways\n4. Determine what type of room has been generated and place the proper extra characteristics within the room\n5. Repeat for the specified number of rooms\n\nThere was, however a few issues with using this tutorial namely:\n\n1. This tutorial is meant for python, not C# and especially not Unity\n2. This tutorial represented every wall with the same \u201cSprite\u201d (really a character in most cases)\n3. While I am sure they get to it eventually, the section I read did not have different types of rooms generated\n\n\n![traditionalRogue.png](\/\/\/raw\/f4a\/b2\/z\/3391b.png)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0*More traditional roguelike couresty of my co-developer Scott*\n\n\n\n\n\n\n\n![ourMap.png](\/\/\/raw\/f4a\/b2\/z\/3391c.png)\n*One of our generated maps*\n\n\n\n\n\n\n\n# Our Implementation\n\nThere are 3 main classes involved in the generation of maps in our game\n\nGridGenerator.cs \u2013 Handles the generation aspect\n\nMapInfo.cs \u2013 This is a scriptural object that contains variables used to generate the map, stores information such as the x and y bounds, the current tileset, and the list of enemies to be spawned in this map\n\nMap.cs \u2013 This class contains static dictionaries used to reference the different tile layers using their (x,y) coordinate as a key. This class is responsible for populating these dictionaries after the game has been loaded.\n\nIf you\u2019re interested in seeing the code in full for these classes [click here](https:\/\/gist.github.com\/ZacharyDangelo\/e7c33358f21636c9c7a9fb1b740bb836)\n\nThere is also a Rect class that handles some aspects of the room generation, but I don\u2019t feel this is a good implementation in its current form and would recommend against our current setup.\n\n\n\n\n# GridGenerator.cs\n\n\n\nFor the most part, this class follows the tutorial linked above to a tee. Below is some of the code that had to be handmade to have our display work properly. Essentially all this does is place the proper sprites on the edges of the room so that they can visually look better than just having a flat wall sprite.\n\n\n\n![gridgen.png](\/\/\/raw\/f4a\/b2\/z\/3391d.png)\n\n\n*It\u2019s game jam code, go easy on me*\n\nFurther down, in the GenerateMap() function we have another slight deviation from the tutorial script. We wanted to generate different types of rooms so we could have stores, traps, exits to a further floor, etc. The counter is basically a hacky way of making sure that we always generate one and only one kitchen, store, and exit.\n\nthe room variable is the room we are currently generating, this function will be called after the room has been carved out and hallways generated.\n\n\n![roomGen.png](\/\/\/raw\/f4a\/b2\/z\/3391e.png)\n\n\n*I can\u2019t explain why the usage of that counter \u2013 switch statement combo feels wrong but it does\u2026*\n\nThe functions being called on the room object belong to the Rect class, I am not sure is the best way to break up this code but it\u2019s what we came up with in the time allotted.\n\nI\u2019ll only show a few examples so you can get an idea, because this is most likely the messiest code in the entire project.\n\n![diffRooms.png](\/\/\/raw\/f4a\/b2\/z\/3391f.png)\n\n\n*Believe it or not, this is some of the better code from this section*\n\nNow, if you\u2019re reading this in hopes to learn how to do some map generation please do not copy and paste this code, it is ugly ugly ugly and one of the first things I will be refactoring but it got the job done for the time we had.\n\n\n\n\n# MapInfo.cs\n\nMapInfo is a Scriptable Object class, if you don\u2019t know what that means I spent my first post on this blog talking about them! Alternatively, you can go straight to the resources I learned from this excellent [blog post by Daniel Ilett](https:\/\/danielilett.com\/2019-10-07-unity-tips-4-scriptableobjects\/).\n\nTo sum it up real quickly scriptable objects are a Unity class that are very good for storing data independent of game objects and with very easy serialization.\n\nHere\u2019s what our usage of them looks like:\n\n![mapinfo.png](\/\/\/raw\/f4a\/b2\/z\/33920.png)\n\n\n\n*The entirety of this class*\n\nThe first section of variables lines 9-15 contains some general information about the map that will be useful to players,enemies and the grid generator.\n\nAll of the variables here are pretty self explanatory, the tiles and enemies are fed into the grid generator so that it knows what tiles to use and the boundaries determine where the map starts and stops generating.\n\nWhat this allows us to do is create a Unity asset entirely in the editor for each different tileset and set the enemies and dimensions in there without changing any code at all!\n\n\n![unity.png](\/\/\/raw\/f4a\/b2\/z\/33921.png)\n\n*An example of what this object looks like in the Unity inspector*\n\nThis is one of the better design choices we made during the jam as it allowed our map generation to be flexible even for our team members who did not know how to code.\n\n\n\n# Map.cs\n\nThis is the class that glues this whole thing together to work in our project.\n\nIt contains two dictionaries with every relevant tile that we can then access using the tiles (x,y) coordinates. This is how we handle movement, combat, and interaction with special objects.\n\nWhat this class does is quite simple but the implementation can seem a bit confusing.\n\n\n![getTiles.png](\/\/\/raw\/f4a\/b2\/z\/33922.png)\n*Thank God for stackoverflow*\n\nWhat happens is the tilemap object has a collider that scales when a tile is placed, we use this to get the x,y bounds of an this object and then we iterate every x,y position in world space and create a MapTile object (This is a data class that I will likely rewrite soon) and store it in the dictionary.\n\nMost of the time when we reference this dictionary we are checking whether the requested tile is a floor or a wall.\n\n\n# Wrapping Up\n\nAll in all, I don\u2019t think this seems like the most complex take on map generation I have ever seen and it is really a stringing together of different tutorials until we had something manageable. But it worked well for our game and most importantly we were able to get it done in the time frame we had.\n\nThis is a section of the code I spent a lot of Ludum Dare working on, and as we continue to develop the game I have no doubts this will continue to be the case.\n\nYes you read that right, we are going to continue developing Cacophony because we\u2019re all having so much fun working on it.\n\nThe first update will release the same day Ludum Dare voting ends May 12th.\n\n\n\n![space.PNG](\/\/\/raw\/f4a\/b2\/z\/33923.png)\n\n\n\nCacophony: The Ballad of the Celestial Goblin-King is a procedurally-generated roguelike dungeon crawler created in 72 hours for Ludum Dare.\n\nThe first update to Cacophony will be released May 12th.\n\nYou can try the game in your browser [here](https:\/\/dreamsteppe.itch.io\/cacophony-the-ballad-of-the-celestial-goblin-king).\n","title":"My First Ludum Dare Part 2 - Map Generation","wayback_source":[]}