Tile Map Generation

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Tile Map Generation

Post by spynaz »

I'm planning to make a 2d survival game that's a platformer, basically like Terraria. I just need a little help on how terrain generation should work. I was planning on make the terrain generate as you walk, but the problem is that when you explore a lot then the game will lag a bunch while it's trying to go through every single tile in the map table and drawing it. How should I make it generate massive maps without lagging?
User avatar
markgo
Party member
Posts: 190
Joined: Sat Jan 05, 2013 12:21 am
Location: USA

Re: Tile Map Generation

Post by markgo »

Best bet is to use a sprite batch with an image with all your tile textures on it. It's very fast compared to drawing each tile individually as an image or quad.
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Re: Tile Map Generation

Post by spynaz »

markgo wrote:Best bet is to use a sprite batch with an image with all your tile textures on it. It's very fast compared to drawing each tile individually as an image or quad.
That's exactly what I was planning to do. But you didn't understand my question. Ok, for example, here is how I was planning to make my map work like:

map = {
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0},
{0, 0, X, 0, 1, 0},
{1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1},
}

As you can see, the map is 6x6 tiles large (fairly small but this is only an example). 0 is the air, 1 is the grass, and X is the player's position. If the player moves one tile to the right and it's missing a column of tiles because the player hasn't explored this part yet, then it generates a new column of tiles on the player's screen:

map = {
{0, 0, 0, 0, 0, 0, 0}, --Since the screen is 6x6 tiles large, only the red is visible by the player.
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, X, 1, 0, 0},
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1},
}

When the player moves back to the left one tile, he has been there already so no new tiles need to be generated:

map = {
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 1, 0, 0},
{ 0, 0, X, 0, 1, 0, 0},
{ 1, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 1, 0},
}

But the problem is, after the player explores a lot, the map table will become huge which will take a while for a function to go through the table (example: when drawing the tiles) which will lag. My question was, how can I make the terrain generation work without having so much lag?
User avatar
markgo
Party member
Posts: 190
Joined: Sat Jan 05, 2013 12:21 am
Location: USA

Re: Tile Map Generation

Post by markgo »

Hmm. I see that you are rebuilding the map each time you walk to a new area, with the exception that the size of each rebuild is bigger than the next. I think it would be best to randomly generate your entire map in chunks. Each chunk is randomly generated when your vision is within range of it and you would add it to your map. It's better than having to regenerate the entire map each time you move to a new area. If your algorithm relies on the entire map for random generation, you'll probably need to tweak it so you don't have to iterate through every tile.

Pseudocode:

Code: Select all

map = {...}
love.update(dt)
  if not tileInRange(x,y,w,h) then -- x,y,w,h is the box area of our vision
    chunk = generateChunk(...)
    map:add(chunk)
  end
end
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Re: Tile Map Generation

Post by spynaz »

markgo wrote:Hmm. I see that you are rebuilding the map each time you walk to a new area, with the exception that the size of each rebuild is bigger than the next. I think it would be best to randomly generate your entire map in chunks. Each chunk is randomly generated when your vision is within range of it and you would add it to your map. It's better than having to regenerate the entire map each time you move to a new area. If your algorithm relies on the entire map for random generation, you'll probably need to tweak it so you don't have to iterate through every tile.

Pseudocode:

Code: Select all

map = {...}
love.update(dt)
  if not tileInRange(x,y,w,h) then -- x,y,w,h is the box area of our vision
    chunk = generateChunk(...)
    map:add(chunk)
  end
end
Isn't that was I was doing when I was adding a column to the map if the player moved?
User avatar
markgo
Party member
Posts: 190
Joined: Sat Jan 05, 2013 12:21 am
Location: USA

Re: Tile Map Generation

Post by markgo »

I don't see how my pseudocode will "lag" as the map gets bigger. The vision range remains the same through out. Are you iterating through every tile to draw or something? You realize that you can add your tiles to a sprite batch and do one draw call with the sprite batch:

Code: Select all

addChunkToSpriteBatch(spritebatch,chunk)
love.draw()
  love.graphics.draw(spritebatch,...)
end
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Re: Tile Map Generation

Post by spynaz »

markgo wrote:I don't see how my pseudocode will "lag" as the map gets bigger. The vision range remains the same through out. Are you iterating through every tile to draw or something? You realize that you can add your tiles to a sprite batch and do one draw call with the sprite batch:

Code: Select all

addChunkToSpriteBatch(spritebatch,chunk)
love.draw()
  love.graphics.draw(spritebatch,...)
end
Oh yea, your right, I was just going through every tile.
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Re: Tile Map Generation

Post by spynaz »

Wait, what if I wanted to change or check something in the map would I have to go through all the values in the map table?
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Tile Map Generation

Post by Nixola »

If you just want to check a single tile, you can just read map[x][y]
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
spynaz
Party member
Posts: 152
Joined: Thu Feb 28, 2013 5:49 am

Re: Tile Map Generation

Post by spynaz »

Nixola wrote:If you just want to check a single tile, you can just read map[x][y]
I know but what if I want to update all water blocks? They can't just stay static in one place.
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests