In this section, you will be creating the Lua code that will generate a map by reading the 2D table generated ASCII Parser into 3D world objects.
Create GenerateMap Script
This script will be responsible for generating the map by looking at the 2D table the ASCII Parser builds, and matching each item in that table against a tile in the Tiles data table. This script will handle spawning the tile, scaling, and positioning it in the world.
Create a new script called GenerateMap.
Place this script into the folder Generated Map in the Hierarchy.
Add Custom Properties
The GenerateMap script will need references to the ASCII Parser script and the Tiles data table.
Add the ASCIIParser script from My APIs in Project Content as a custom property called ASCIIParser.
Add the Tiles data table from My Tables in Project Content as a custom property called Tiles.
Edit GenerateMap Script
Open up the GenerateMap script and add the variables to the custom properties so you have a reference to them. Notice that both properties needed to be required. This is because the ASCIIParser is an API, and the TILES is a table.
local ASCIIParser = require(script:GetCustomProperty("ASCIIParser"))
local TILES = require(script:GetCustomProperty("Tiles"))
Code language:Lua(lua)
Create Variables
A few variables are needed for the script. You need to define the map width and map height so that when looping over the map table that will be generated from the ASCII Parser it knows the bounds of that table. A tile size needs to be defined, otherwise, the tiles will be spawned at a scale of 1 x 1 x1, which would be quite small.
The STATIC_CONTAINER is the Static Context that will be used to spawn all the assets in for the tiles.
local STATIC_CONTAINER = script.parent
local MAP_WIDTH = 6local MAP_HEIGHT = 4local TILE_SIZE = 1000Code language:Lua(lua)
Build Map from ASCII String
You can now build the map by calling the BuildMap function created in the ASCII Parser in an earlier lesson. The BuildMap function will take in a multiline comment, map width, map height, and return a table, and the map string. The ASCII map string can be used to verify the ASCII Parser created the map correctly. If it matches the input string, then it is correct.
The last step in this lesson is to generate the 3D map by reading the 2D map. This will be a fairly simple process for now, but it will be revisited to improve the look of the map so different tiles and assets are spawned.
You will need to create 2 loops. The first loop is going to loop based on how many rows there are (MAP_HEIGHT), and the inner loop is going to loop over how many columns there are in a row (MAP_WIDTH). For each iteration of the inner loop, it will attempt to find a tile that matches the value inside the map table. For example, if the current entry of the map table is 1, then it will look up the row in the Tiles data table where the id column matches 1 and return that row.
A check is done to make sure the row is valid by checking it is not nil. This is just in case an id in the ASCII table does not exist in the Tiles data table.
On line 6, the scale of the tile is uniformly scaled based on the TILE_SIZE value. Otherwise, the tiles will be very small, or the map would feel small to move around in. If the tile is a floor, the scale for z will be set to 1, otherwise, the floor would be the same height as all the other tiles.
On lines 12 and 13, the x and y position of the tile is worked out so they are spaced out correctly based on their position in the map. These lines also move everything by an offset so that the center point is closer to the world origin.
To spawn the asset, the function SpawnSharedAssetis used so that it will spawn in to the static context for the server and the client. This is an efficient way of spawning objects so that when players join late, they will also receive the spawned assets.
for row = 1, MAP_HEIGHT dofor col = 1, MAP_WIDTH dolocal tileRow = TILES[map[row][col]]
if tileRow ~= nilthenlocal scale = Vector3.New(TILE_SIZE / 100, TILE_SIZE / 100, TILE_SIZE / 100)
if tileRow.floorthen scale.z = 1endlocal x = -(row * TILE_SIZE) + (MAP_HEIGHT * TILE_SIZE) / 2local y = (col * TILE_SIZE) - (MAP_WIDTH * TILE_SIZE) / 2local params = {
scale = scale,
position = Vector3.New(x, y, 0),
}
STATIC_CONTAINER:SpawnSharedAsset(tileRow.tile, params)
endendendCode language:Lua(lua)
The GenerateMap Script
GenerateMap
local ASCIIParser = require(script:GetCustomProperty("ASCIIParser"))
local TILES = require(script:GetCustomProperty("Tiles"))
local STATIC_CONTAINER = script.parent
local MAP_WIDTH = 6local MAP_HEIGHT = 4local TILE_SIZE = 1000local map, mapStr = ASCIIParser.BuildMap([[ 111111 100001 100001 111111]], MAP_WIDTH, MAP_HEIGHT)
for row = 1, MAP_HEIGHT dofor col = 1, MAP_WIDTH dolocal tileRow = TILES[map[row][col]]
if tileRow ~= nilthenlocal scale = Vector3.New(TILE_SIZE / 100, TILE_SIZE / 100, TILE_SIZE / 100)
if tileRow.floorthen scale.z = 1endlocal x = -(row * TILE_SIZE) + (MAP_HEIGHT * TILE_SIZE) / 2local y = (col * TILE_SIZE) - (MAP_WIDTH * TILE_SIZE) / 2local params = {
scale = scale,
position = Vector3.New(x, y, 0),
}
STATIC_CONTAINER:SpawnSharedAsset(tileRow.tile, params)
endendendCode language:Lua(lua)
Test the Game
Test the game and see if the map is generated correctly. You may find that your player is falling in the world, and this is because there is currently no spawn point. This will be addressed soon, but for now, you can pause the game by pressing Tab and then move the camera around to see if the map was generated.
Test Different Maps
Try a few different maps by modifying the ASCII string that is sent to the BuildMap function. For example, a 10 x 10 map:
This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.
Strictly Necessary Cookies
Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.
If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.
3rd Party Cookies
This website uses Google Analytics to collect anonymous information such as the number of visitors to the site, and the most popular pages.
Keeping this cookie enabled helps us to improve our website.
Please enable Strictly Necessary Cookies first so that we can save your preferences!