{"author_link":"\/users\/arkinrev","author_name":"arkinrev","author_uid":"arkinrev","comments":[],"epoch":1588895572,"event":"LD46","format":"md","ldjam_node_id":209870,"likes":1,"metadata":{"p_key":"145966","p_author":"arkinrev","p_authorkey":"1125658","p_urlkey":"362379","p_title":"Random Levels in It Hungers","p_cat":"LDJam ","p_event":"LD46","p_time":"1588895572","p_likes":"1","p_comments":"0","p_status":"WAYBACK","us_key":"1125658","us_name":"arkinrev","us_username":"arkinrev","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":7,"author":125658,"body":"I thought I'd take a few minutes to quickly describe how I created random levels in [It Hungers](https:\/\/ldjam.com\/events\/ludum-dare\/46\/it-hungers). This last minute addition to the game was really something that made it a little bit more replayable for me, even though it's a very crude addition. \n\n# The Overall Plan\nThe plan basically consists of a grid of positions within an arena. I would then essentially shuffle a deck of tiles, rotate them, and place them into the arena. These vignettes are each responsible for populating themselves with the prefabs that inhabit them, like enemies or pickup items. \n\n## The Grid\nIt's not much to look at, but the grid is basically several game objects out in the world. \n![grid.png](\/\/\/raw\/ada\/e1\/z\/33d79.png)\n\nPretty uninspiring, right? That's where my VignetteManager comes to the rescue!\n\n## The Vignette Manager\nThe vignette manager's job is to know where all of the game positions are for these tiles. Generates a random \"deck\" of tiles, shuffles it, and rotates each tile as it places it down into the game. Each tile then populates itself, or in the case of \"special\" tiles like the player spawn or the larva spawn, it handles them accordingly. This is a little bit clunky, but the shuffling function basically randomly selects an item in a List (array) of available locations. It \"draws\" that tile from the stack, and places it into a \"shuffled\" stack. Basically, all it's doing is rearranging the order of the tiles.\n\n```\nTransform randomListVignetteTransform()\n    {\n        Transform selectedVignetteTransform;\n        \n        int index = Random.Range((int)0,(int)shufflingVignettes.Count); \/\/picks a random array index\n        selectedVignetteTransform = shufflingVignettes[index]; \n        shufflingVignettes.RemoveAt(index); \/\/ removes that index from the unshuffled version of the list\n        shuffledVignettes.Add(selectedVignetteTransform); \/\/ adds it to the shuffled version\n        return selectedVignetteTransform; \/\/ and returns the transform of the empty placeholder game object in the list \n    }\n```\n\nThen, we randomly rotate in a similar way, and put a random vignette prefab in that location.\n\n```\n    float randomPrefabRotation()\n    {\n        float randomRot;\n        int randIndex = Random.Range((int)0, rotations.Length);\n        randomRot = rotations[randIndex];\n\n        return randomRot;\n    }\n\n    GameObject randomPrefab()\n    {\n        GameObject randomGO;\n        int randIndex = Random.Range((int)0, vignettes.Length);\n        randomGO = vignettes[randIndex];\n\n        return randomGO;\n    }\n```\n\nYou may have noticed by now, that each of these bits are really doing the same thing: grabbing random items from a list. These random things are basically random obstacles or meshes, that have not been populated yet with any denizens or items in the game. \n\n## Filling out the Vignette\nThe last little bit was putting something in each of these vignette tiles. Basically, I really did the same thing. A random list of \"things\" in an empty game object. The Start method randomly instantiates an item from that list, and the placeholder game object deletes itself. \n\n```\npublic class RandomSpawnControl : MonoBehaviour\n{\n    public GameObject[] enemySpawnerGO;\n    public GameObject mapGOParent;\n    public GameObject spawnParentGO;\n\n    \/\/ Start is called before the first frame update\n    void Start()\n    {\n        spawnParentGO = GameObject.FindWithTag(\"MapGOTagger\");\n\n        GameObject goInstantiated;\n        GameObject objToSpawn = enemySpawnerGO[Random.Range((int)0, enemySpawnerGO.Length)];\n        goInstantiated = Instantiate(objToSpawn, this.transform.position, this.transform.rotation);\n        goInstantiated.transform.SetParent(spawnParentGO.transform);\n\n        Destroy(this.gameObject);\n    }\n}\n```\nThese enemySpawnerGO game objects are enemies, items, and spawners. \n![randSpawn.png](\/\/\/raw\/ada\/e1\/z\/33d7b.png)\nYou can see that I've cheated a little bit, and seeded these elements to favor some things more than others. Once this has all been instantiated, you've got yourself a level!\n\n![LD46LDImage.png](\/\/\/raw\/ada\/e1\/z\/33d7f.png)\n\n# Thinking like a Boardgame\nI sort of knew what I was getting into with random levels. I've looked at it so many different ways, and ran out of time trying to do it in a previous Ludum Dare. This time, the Ah Ha moment was thinking like it was a board game. These weren't \"random levels\" they were tiles or cards being drawn from a deck. Pick a random place, draw a random card, place it, and remove the possibility of \"drawing\" that same location again. I know it's a mess and could use more work. But look at it! It was a 30 minute effort and really made it feel like there is more game there. \n\nThe full code can be found buried here: https:\/\/github.com\/ArkInRev\/LD46\n\nYou can check out the game here: https:\/\/ldjam.com\/events\/ludum-dare\/46\/it-hungers\n\nIf you stuck it out this far, thanks for reading and I hope it helps someone!\n","comments":0,"created":"2020-05-07T22:54:21Z","files":[],"files-timestamp":0,"id":209870,"love":1,"love-timestamp":"2020-05-08T08:19:31Z","meta":[],"modified":"2020-05-08T08:19:31Z","name":"Random Levels in It Hungers","node-timestamp":"2020-05-07T23:52:52Z","parent":184742,"parents":[1,5,9,176557,184742],"path":"\/events\/ludum-dare\/46\/it-hungers\/random-levels-in-it-hungers","published":"2020-05-07T23:52:52Z","scope":"public","slug":"random-levels-in-it-hungers","subsubtype":"","subtype":"","type":"post","version":637883},"node_metadata":{"n_key":"209870","n_urlkey":"362379","n_parent":"184742","n_path":"\/events\/ludum-dare\/46\/it-hungers\/random-levels-in-it-hungers","n_slug":"random-levels-in-it-hungers","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"125658","n_created":"1588892061","n_modified":"1588925971","n_version":"637883","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/46\/it-hungers\/random-levels-in-it-hungers","text":"I thought I'd take a few minutes to quickly describe how I created random levels in [It Hungers](https:\/\/ldjam.com\/events\/ludum-dare\/46\/it-hungers). This last minute addition to the game was really something that made it a little bit more replayable for me, even though it's a very crude addition. \n\n# The Overall Plan\nThe plan basically consists of a grid of positions within an arena. I would then essentially shuffle a deck of tiles, rotate them, and place them into the arena. These vignettes are each responsible for populating themselves with the prefabs that inhabit them, like enemies or pickup items. \n\n## The Grid\nIt's not much to look at, but the grid is basically several game objects out in the world. \n![grid.png](\/\/\/raw\/ada\/e1\/z\/33d79.png)\n\nPretty uninspiring, right? That's where my VignetteManager comes to the rescue!\n\n## The Vignette Manager\nThe vignette manager's job is to know where all of the game positions are for these tiles. Generates a random \"deck\" of tiles, shuffles it, and rotates each tile as it places it down into the game. Each tile then populates itself, or in the case of \"special\" tiles like the player spawn or the larva spawn, it handles them accordingly. This is a little bit clunky, but the shuffling function basically randomly selects an item in a List (array) of available locations. It \"draws\" that tile from the stack, and places it into a \"shuffled\" stack. Basically, all it's doing is rearranging the order of the tiles.\n\n```\nTransform randomListVignetteTransform()\n    {\n        Transform selectedVignetteTransform;\n        \n        int index = Random.Range((int)0,(int)shufflingVignettes.Count); \/\/picks a random array index\n        selectedVignetteTransform = shufflingVignettes[index]; \n        shufflingVignettes.RemoveAt(index); \/\/ removes that index from the unshuffled version of the list\n        shuffledVignettes.Add(selectedVignetteTransform); \/\/ adds it to the shuffled version\n        return selectedVignetteTransform; \/\/ and returns the transform of the empty placeholder game object in the list \n    }\n```\n\nThen, we randomly rotate in a similar way, and put a random vignette prefab in that location.\n\n```\n    float randomPrefabRotation()\n    {\n        float randomRot;\n        int randIndex = Random.Range((int)0, rotations.Length);\n        randomRot = rotations[randIndex];\n\n        return randomRot;\n    }\n\n    GameObject randomPrefab()\n    {\n        GameObject randomGO;\n        int randIndex = Random.Range((int)0, vignettes.Length);\n        randomGO = vignettes[randIndex];\n\n        return randomGO;\n    }\n```\n\nYou may have noticed by now, that each of these bits are really doing the same thing: grabbing random items from a list. These random things are basically random obstacles or meshes, that have not been populated yet with any denizens or items in the game. \n\n## Filling out the Vignette\nThe last little bit was putting something in each of these vignette tiles. Basically, I really did the same thing. A random list of \"things\" in an empty game object. The Start method randomly instantiates an item from that list, and the placeholder game object deletes itself. \n\n```\npublic class RandomSpawnControl : MonoBehaviour\n{\n    public GameObject[] enemySpawnerGO;\n    public GameObject mapGOParent;\n    public GameObject spawnParentGO;\n\n    \/\/ Start is called before the first frame update\n    void Start()\n    {\n        spawnParentGO = GameObject.FindWithTag(\"MapGOTagger\");\n\n        GameObject goInstantiated;\n        GameObject objToSpawn = enemySpawnerGO[Random.Range((int)0, enemySpawnerGO.Length)];\n        goInstantiated = Instantiate(objToSpawn, this.transform.position, this.transform.rotation);\n        goInstantiated.transform.SetParent(spawnParentGO.transform);\n\n        Destroy(this.gameObject);\n    }\n}\n```\nThese enemySpawnerGO game objects are enemies, items, and spawners. \n![randSpawn.png](\/\/\/raw\/ada\/e1\/z\/33d7b.png)\nYou can see that I've cheated a little bit, and seeded these elements to favor some things more than others. Once this has all been instantiated, you've got yourself a level!\n\n![LD46LDImage.png](\/\/\/raw\/ada\/e1\/z\/33d7f.png)\n\n# Thinking like a Boardgame\nI sort of knew what I was getting into with random levels. I've looked at it so many different ways, and ran out of time trying to do it in a previous Ludum Dare. This time, the Ah Ha moment was thinking like it was a board game. These weren't \"random levels\" they were tiles or cards being drawn from a deck. Pick a random place, draw a random card, place it, and remove the possibility of \"drawing\" that same location again. I know it's a mess and could use more work. But look at it! It was a 30 minute effort and really made it feel like there is more game there. \n\nThe full code can be found buried here: https:\/\/github.com\/ArkInRev\/LD46\n\nYou can check out the game here: https:\/\/ldjam.com\/events\/ludum-dare\/46\/it-hungers\n\nIf you stuck it out this far, thanks for reading and I hope it helps someone!\n","title":"Random Levels in It Hungers","wayback_source":[]}