Is roguelike a reasonable task for LOVE?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
pacman
Citizen
Posts: 81
Joined: Thu Mar 14, 2013 4:10 pm

Is roguelike a reasonable task for LOVE?

Hi o/

I was thinking about trying to make a simple roguelike.
Years ago I knew there is no way I can achieve that but today I'm not so sure

Let's try to create some map

Code: Select all

map = {}
for i=1, 45, 1 do
map[i] = {}
for j=1, 27, 1 do
map[i][j] = insert_tile('stone_floor')
end
end
I didn't even realise how much operations it is... Now I want my map to look dope so I need random characters for floors ( , . '  ; : ) and few random colors.

Code: Select all

function insert_tile(type)
local tile, rand, color
if		type == 'stone_floor' then
-- make a copy of the tile
tile = deepcopy(tile_type.stone_floor)
-- choose random character
rand = math.random(1, #tile.char_pool)
tile.char = tile.char_pool[rand]
-- and random color
rand = math.random(1, #tile.pallete)
tile.color = tile.pallete[rand]
It takes ages on my wooden PC but that's fine. Generating maps isn't something you do every 5 seconds and it would be nice reason to learn how to loading bar

Now the real struggle is with drawing the map.
Drawing this simple rectangle of characters gives me 60-100 fps.
What if I want colors, background colors, custom font?
I can't update only changed positions because not drawing equals black screen. Canvases are not supported.
I'm not looking for Dwarf Fortress sized maps.. just the tip
Attachments
Purge.love
jannn
Prole
Posts: 3
Joined: Fri Nov 07, 2014 9:00 pm

Re: Is roguelike a reasonable task for LOVE?

You can improve your map generation speed greatly by looping over some pre-generated tables of random numbers. You don't really need something like the look of floor tiles to be truly random, do you? (well pseudorandom, but you get the point)

Additionally, if you're talking about a true turn-based roguelike, then a slight framerate drop is a non-issue for the end user.
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Is roguelike a reasonable task for LOVE?

LOVE is perfectly capable of handling roguelikes. In fact there are a few examples in the projects forums.

The freezing at the start is likely because the window is being resized right after it was created using love.window.setMode(). You can avoid this by using a [wiki]conf.lua[/wiki] file. Also you should avoid copying static data to all of your tiles. Try using __index or a reference instead.

I've uploaded a modified .love that might help explain.
Attachments
Purge.love
pacman
Citizen
Posts: 81
Joined: Thu Mar 14, 2013 4:10 pm

Re: Is roguelike a reasonable task for LOVE?

The freezing is because my pc can't handle all that table copying

Your example works like a charm. Really impressive how metatables make it fast and furious!
The only problem is with my understanding of what happens

Code: Select all

tile = setmetatable({}, tile_type.stone_floor)
Does it mean that if I will look for tile.color it will check the empty {} and then it will look in tile_type.stone_floor?
If no:
If yes:
It requires

Code: Select all

for k,v in pairs(tile_type) do
v.__index = v
end
So stone_floor.__index = stone_floor
How does it work? What is the relation between tile = setmetatable and putting __index that points to the table with same name?
How computer sees it?
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Is roguelike a reasonable task for LOVE?

pacman wrote:

Code: Select all

tile = setmetatable({}, tile_type.stone_floor)
Does it mean that if I will look for tile.color it will check the empty {} and then it will look in tile_type.stone_floor?
You're only setting the metatable with that line. The magic happens with the metatable's __index. When you try and get a value does not exist for a table, it will check its metatable's __index next. Setting the index to the metatable itself is just for convenience. It can be any table or alternatively a function.

Some examples may help. All of these are functionally the same:

Code: Select all

-- Create the table, metatable, and index seperately then assign the metatable
i = { number = 5 }
mt = { __index = i }
t = {}
setmetatable( t, mt )
print( t.number )  -- prints 5

-- Use the metatable itself as an index
mt = { number = 5 }
mt.__index = mt
t = setmetatable( {}, mt )
print( t.number ) -- prints 5

-- Creates the table, metatable, and index in one line
t = setmetatable( {},  { __index = { number = 5 } } )
print( t.number )  -- prints 5

pacman
Citizen
Posts: 81
Joined: Thu Mar 14, 2013 4:10 pm

Re: Is roguelike a reasonable task for LOVE?

So the shortest way to do it would be:

Code: Select all

tile = setmetatable({}, {__index = tile_type.stone_floor})`
It works so fast I can't even...
Thank you very much \c", )/
Prole
Posts: 4
Joined: Tue Jun 04, 2013 12:17 am

Re: Is roguelike a reasonable task for LOVE?

I working on an roguelike game and I achieved decent performance with BSP trees. I use them to query what to update and what to draw.

A nice trick I do on my update is to first query the subtree that covers the screen then use it instead of using the original tree directly, as I only update dynamic entities that are visible and each of them make their own queries.

Currently I achieve between 0.8 ~1.6 ms of draw + update time per frame (running on an amd @3.2ghz). Scene size doesn't impact it much, if at all. But levels are a bit slow to generate, though it only becomes painful when I hit scene sizes like 1000x1000 tiles (it takes around 10s), so I'm not worried about it (yet).

Who is online

Users browsing this forum: No registered users and 37 guests