In this lesson, you will add a spawn point to your map. This can be done by adding a new id value to the ASCII table. This could be set up to handle multiple spawn points, but in this case, it will just be one.
Update ASCII Map
The id for the ASCII map should be something that represents what it is. For a spawn point, we will use the S.
Open up the GenerateMap script.
Modify the ASCII Map by adding a spawn point using the id value S.
The Tiles data table will need a new row and a new column for the spawn point. The new column will be used to set the rotation of the spawn so the player is facing the right way. This could be done automatically based on the tiles around the spawn point, but it is nice having full control over it using a preset rotation.
Add a new column called rotation and set the type to Rotation.
Add a new row with an id of S and a key of Spawn.
Update MapBuilder API Script
The MapBuilder API script will need to be updated to communicate to the PlayerServer script by a broadcast to handle the spawning. Later in the course, this method will be changed so that players only spawn after the map and all of its components have been initialized.
Create SpawnPlayers Function
Create a new function called SpawnPlayers that will check the spawn point is valid and then broadcast to the PlayerServer script. Setting a player’s position needs to be done on the server, and because the GenerateMap script is in a Static Context that is requiring the MapBuilder script you can do an environment check to just return if it is not the script running on the server.
When a script is in a Local Context or a Static Context, that script has a copy on the server and the client. Some environment functions that are normally available to you will not work in these contexts. So a broadcast to a script that is in the same environment but outside that context will need to be done. In this case, a broadcast to the PlayerServer script is done because the PlayerServer script is in the server environment, meaning it has permission to set a player’s position.
The Spawn function will find a spawn point for the player, and then at the end of the generation will call the SpawnPlayers function. When a tile is spawned the data for the current tile will be checked to see if it a spawn point. If it is a spawn point, then the position of that tile is used as the spawn point. Because the position has already been stored in the params table, then it can be reused for the spawn point.
local ASCIIParser = require(script:GetCustomProperty("ASCIIParser"))
local TILES = require(script:GetCustomProperty("Tiles"))
local MapBuilder = {
Type = {}
}
for key, row inpairs(TILES) do MapBuilder.Type[row.key] = row.id
endfunctionMapBuilder.Build(opts)local map, mapStr = ASCIIParser.BuildMap(opts.map, opts.width, opts.height)
MapBuilder.Spawn(map, opts.width, opts.height, opts.size, opts.container)
endfunctionMapBuilder.GetTile(map, row, col)local foundRow = map[row]
if foundRow thenreturn foundRow[col]
endreturnnilendfunctionMapBuilder.GetNeighbors(map, row, column)return {
NORTH = MapBuilder.GetTile(map, row - 1, column),
SOUTH = MapBuilder.GetTile(map, row + 1, column),
EAST = MapBuilder.GetTile(map, row, column + 1),
WEST = MapBuilder.GetTile(map, row, column - 1)
}
endfunctionMapBuilder.CheckForWallCorner(map, neighbors, row, col)local tileRow = nillocal extraTile = nillocal rotation = Rotation.New()
if neighbors.WEST == MapBuilder.Type.Wall and neighbors.NORTH == MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall and neighbors.EAST ~= niland neighbors.SOUTH ~= nilthen tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = 0elseif neighbors.NORTH == MapBuilder.Type.Wall and neighbors.EAST == MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall and neighbors.WEST ~= niland neighbors.SOUTH ~= nilthen tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = 90elseif neighbors.EAST == MapBuilder.Type.Wall and neighbors.SOUTH == MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall and neighbors.NORTH ~= niland neighbors.WEST ~= nilthen tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = 180elseif neighbors.SOUTH == MapBuilder.Type.Wall and neighbors.WEST == MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall and neighbors.EAST ~= niland neighbors.NORTH ~= nilthen tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = 270endif tileRow ~= nilthen extraTile = TILES[MapBuilder.Type.Floor]
endreturn tileRow, rotation, extraTile
endfunctionMapBuilder.CheckForDeadEnd(map, neighbors, row, col)local tileRow = nillocal extraTile = nillocal rotation = Rotation.New()
if neighbors.WEST == MapBuilder.Type.Wall and neighbors.NORTH == MapBuilder.Type.Wall and neighbors.EAST == MapBuilder.Type.Wall and neighbors.SOUTH ~= MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall then tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = 45elseif neighbors.NORTH == MapBuilder.Type.Wall and neighbors.EAST == MapBuilder.Type.Wall and neighbors.SOUTH == MapBuilder.Type.Wall and neighbors.WEST ~= MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall then tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = 135elseif neighbors.EAST == MapBuilder.Type.Wall and neighbors.SOUTH == MapBuilder.Type.Wall and neighbors.WEST == MapBuilder.Type.Wall and neighbors.NORTH ~= MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall then tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = -135elseif neighbors.SOUTH == MapBuilder.Type.Wall and neighbors.WEST == MapBuilder.Type.Wall and neighbors.NORTH == MapBuilder.Type.Wall and neighbors.EAST ~= MapBuilder.Type.Wall and map[row][col] ~= MapBuilder.Type.Wall then tileRow = TILES[MapBuilder.Type.WallCorner]
rotation.z = -45endif tileRow ~= nilthen extraTile = TILES[MapBuilder.Type.Floor]
endreturn tileRow, rotation, extraTile
endfunctionMapBuilder.SpawnExtraTile(extraTile, params, container)if extraTile == nilthenreturnendif MapBuilder.Type.Floor == extraTile.id then params.scale.z = 1 params.rotation = Rotation.New()
end container:SpawnSharedAsset(extraTile.tile, params)
endfunctionMapBuilder.SpawnPlayers(spawnPoint)if spawnPoint == nilornot Environment.IsServer() thenreturnend Task.Wait()
Events.Broadcast("SpawnPlayers", spawnPoint, TILES[MapBuilder.Type.Spawn].rotation)
endfunctionMapBuilder.Spawn(map, width, height, size, container)ifnot Environment.IsServer() thenreturnendlocal spawnPoint = nilfor row = 1, height dofor col = 1, width dolocal tileRow, rotation, extraTile
local neighbors = MapBuilder.GetNeighbors(map, row, col)
tileRow, rotation, extraTile = MapBuilder.CheckForDeadEnd(map, neighbors, row, col)
if tileRow == nilthen tileRow, rotation, extraTile = MapBuilder.CheckForWallCorner(map, neighbors, row, col)
endif tileRow == nilthen tileRow = TILES[map[row][col]]
endif tileRow ~= nilthenlocal scale = Vector3.New(size / 100, size / 100, size / 100)
if tileRow.floorthen scale.z = 1endlocal x = -(row * size) + (height * size) / 2local y = (col * size) - (width * size) / 2local params = {
scale = scale,
position = Vector3.New(x, y, 0),
rotation = rotation
}
container:SpawnSharedAsset(tileRow.tile, params)
if map[row][col] == MapBuilder.Type.Spawn then spawnPoint = params.position
endif extraTile ~= nilthen MapBuilder.SpawnExtraTile(extraTile, params, container)
endendendend MapBuilder.SpawnPlayers(spawnPoint)
endreturn MapBuilder
Code language:Lua(lua)
Update PlayerServer Script
The PlayerServer script needs to be updated so it can listen for the broadcast and handle spawning the players at the position and rotation passed in.
When testing the game after modifying the PlayerServer script, it is recommended to test in Single Player Preview mode for now. Later on in the course you will be modifying this script again that will work better for Multiplayer. If you do test in Multiplayer Preview Mode, you may find the player character spawning under the generated map.
Create SpawnPlayers Function
Create a new function called SpawnPlayers that will receive the position and rotation. The function will loop through all the players in the game and set the world position and world rotation. A small up direction of 150 is added to the position to make sure the player is above the floor tile, or they will fall through.
localfunctionSpawnPlayers(position, rotation)for _, player inipairs(Game.GetPlayers()) do player:SetWorldPosition(position + (Vector3.UP * 150))
player:SetWorldRotation(rotation)
endendCode language:Lua(lua)
Connect SpawnPlayers Event
Connect up the SpawnPlayers event to call the SpawnPlayers function.
localfunctionActionPressed(player, action)if(action == "Toggle Fly Mode") thenif(player.isFlying) then player:ActivateWalking()
else player:ActivateFlying()
endendendlocalfunctionSpawnPlayers(position, rotation)for _, player inipairs(Game.GetPlayers()) do player:SetWorldPosition(position + (Vector3.UP * 150))
player:SetWorldRotation(rotation)
endendInput.actionPressedEvent:Connect(ActionPressed)
Events.Connect("SpawnPlayers", SpawnPlayers)
Code language:Lua(lua)
Test the Game
Test the game to make sure the player is spawned in the correct position. If you have a different map layout, you may need to adjust the rotation in the Tiles data table for the spawn point.
Hello,
I have a problem spawing the character over the ground, even changing the value inside the function SpawnPlayers of the PlayerServer.
I’ve checked back my hierarchy and everything but cant happen to make it.
Hello CommanderFoo, thank’s for your reply.
I verified everything but sadly I wasn’t able to fix it.
I made an image for you to see if you can detect something wrong in my project. https://imgur.com/Z4ha7qN
Thanks. So the error is on my part. I should mention that at the moment it is suited for single player preview, but later on in the course it gets updated. Will add a note to the lesson. Thanks very mucm 🙂
Hello
The spawning works but i get this error code
Error running Lua task: [45150F3CAED9AF47] PlayerServer:14: stack index 2, expected Rotation, received nil: value is not a valid userdata (bad argument into ‘void(Player, Rotation)’)
Not sure where i went wrong
you have an error in the script “MapBuilder” function “Spawn” line 155, if “map[row][col]” is equal to “MapBuilder.Type.Spawn” then “tileRow.tile” will be equal to “nil” . Spawn points cannot be created dynamically.
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!
Hello,
I have a problem spawing the character over the ground, even changing the value inside the function SpawnPlayers of the PlayerServer.
I’ve checked back my hierarchy and everything but cant happen to make it.
Hello,
Make sure you have an entry in the Tiles table. There should be an entry with an id of `S` and the key should be `Spawn`.
Make sure no spawn point exists in the world either.
Is the player spawning at the world center position (0, 0, 0)?
Hello CommanderFoo, thank’s for your reply.
I verified everything but sadly I wasn’t able to fix it.
I made an image for you to see if you can detect something wrong in my project.
https://imgur.com/Z4ha7qN
Hello,
Would you be able to send me your project on Discord?
https://discord.coregames.com
I can be found under the same name as here. Thanks 🙂
Sure, thank you. 🙂
Thanks. So the error is on my part. I should mention that at the moment it is suited for single player preview, but later on in the course it gets updated. Will add a note to the lesson. Thanks very mucm 🙂
Hello
The spawning works but i get this error code
Error running Lua task: [45150F3CAED9AF47] PlayerServer:14: stack index 2, expected Rotation, received nil: value is not a valid userdata (bad argument into ‘void(Player, Rotation)’)
Not sure where i went wrong
Make sure you are broadcasting the rotation in the MapBuilder script. It comes from the TILES table (should be a column called `rotation`).
`Events.Broadcast(“SpawnPlayers”, spawnPoint, TILES[MapBuilder.Type.Spawn].rotation)`
you have an error in the script “MapBuilder” function “Spawn” line 155, if “map[row][col]” is equal to “MapBuilder.Type.Spawn” then “tileRow.tile” will be equal to “nil” . Spawn points cannot be created dynamically.