Generating the Map

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.

  1. Create a new script called GenerateMap.
  2. 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.

  1. Add the ASCIIParser script from My APIs in Project Content as a custom property called ASCIIParser.
  2. 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 = 6
local MAP_HEIGHT = 4
local TILE_SIZE = 1000
Code 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.

local map, mapStr = ASCIIParser.BuildMap([[

	111111
	100001
	100001
	111111

]], MAP_WIDTH, MAP_HEIGHT)
Code language: Lua (lua)

Generate the Map

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 SpawnSharedAsset is 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 do
	for col = 1, MAP_WIDTH do
		local tileRow = TILES[map[row][col]]

		if tileRow ~= nil then
			local scale = Vector3.New(TILE_SIZE / 100, TILE_SIZE / 100, TILE_SIZE / 100)

			if tileRow.floor then
				scale.z = 1
			end

			local x = -(row * TILE_SIZE) + (MAP_HEIGHT * TILE_SIZE) / 2
			local y = (col * TILE_SIZE) - (MAP_WIDTH * TILE_SIZE) / 2
		
			local params = {

				scale = scale,
				position = Vector3.New(x, y, 0),

			}

			STATIC_CONTAINER:SpawnSharedAsset(tileRow.tile, params)
		end
	end
end
Code language: Lua (lua)

The GenerateMap Script

local ASCIIParser = require(script:GetCustomProperty("ASCIIParser"))
local TILES = require(script:GetCustomProperty("Tiles"))
local STATIC_CONTAINER = script.parent

local MAP_WIDTH = 6
local MAP_HEIGHT = 4
local TILE_SIZE = 1000

local map, mapStr = ASCIIParser.BuildMap([[

	111111
	100001
	100001
	111111

]], MAP_WIDTH, MAP_HEIGHT)

for row = 1, MAP_HEIGHT do
	for col = 1, MAP_WIDTH do
		local tileRow = TILES[map[row][col]]

		if tileRow ~= nil then
			local scale = Vector3.New(TILE_SIZE / 100, TILE_SIZE / 100, TILE_SIZE / 100)

			if tileRow.floor then
				scale.z = 1
			end

			local x = -(row * TILE_SIZE) + (MAP_HEIGHT * TILE_SIZE) / 2
			local y = (col * TILE_SIZE) - (MAP_WIDTH * TILE_SIZE) / 2
		
			local params = {

				scale = scale,
				position = Vector3.New(x, y, 0),

			}

			STATIC_CONTAINER:SpawnSharedAsset(tileRow.tile, params)
		end
	end
end
Code 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:

local MAP_WIDTH = 10
local MAP_HEIGHT = 10
local TILE_SIZE = 1000

local map, mapStr = ASCIIParser.BuildMap([[

	1111111111
	1100001101
	1001100101
	1111101101
	1100000001
	1001111001
	1011001001
	1011101011
	1010000011
	1111111111

]], MAP_WIDTH, MAP_HEIGHT)
Code language: Lua (lua)
Scroll to Top