Page 1 of 1

Not sure how to handle many entities on a tile-based map

Posted: Thu Dec 19, 2013 11:18 am
by Khal
Hi everyone,

I'm trying to create my own little map editor for the games that I want to create. I've seen that there are already a bunch of super flexible solutions out there already, but I really wanted to create my own :(

What I'm currently doing is creating a 2D table of "tile objects" that are just tables that contain the tile's x and y positions as well as a string that represents the tile's image, which is used as a key for a table containing the image data for the sprite.

After I create the table, I have a function that gets all the tiles that need to be rendered to the screen based off of the player's current position's offset and puts them in a table. Then I can draw that table to the screen and also check the tiles for collisions and whatnot.

What I haven't been sure how to do is take entities (like vehicles or npcs or whatever) and render them to the screen efficiently without having to iterate over every single one of them to check if they're within bounds of the screen.

Sorry if this is a pretty elementary thing to ask or if I'm going in entirely the wrong direction; as much as I enjoy programming, I'm still very new to most concepts.

I'll attach my .love for the project, I'm pretty embarrassed of my code, of course it is largely unfinished but if you have any suggestions or if you see that I'm exhibiting poor programming practices, please let me know. :oops:

Re: Not sure how to handle many entities on a tile-based map

Posted: Thu Dec 19, 2013 11:34 am
by Plu
How efficiently do you want it? Unless you're going into thousands of entities, iterating over them should be pretty quick.

If you want to speed it up, here are some ideas.

- Assign the whole map into sectors that are at least twice as large as your screen. Assign each entity to a sector. If an entity is not in the current sector, it's definately not on the screen. (Careful; entities might be in multiple sectors if they overlap an edge)
- Make a list of entities on the screen. Only update the list when the screen or an entity moves. This saves constant iterating when nothing is changing.

Re: Not sure how to handle many entities on a tile-based map

Posted: Sat Dec 21, 2013 2:19 am
by Khal
Woo, thanks! I thought about separating the map into chunks, but wasn't sure if that would work or how I could move entities between them, but I after thinking about it I've got a pretty good idea.

The only thing I was wondering now was whether or not it's possible to save tables with functions in them to a file. That way I can save NPCs with a sort of "action" attribute that can do stuff when they're activated. Or is there a better way of going about this?

Re: Not sure how to handle many entities on a tile-based map

Posted: Sat Dec 21, 2013 11:58 am
by Plu
You cannot literally store a function into a file as far as I know, but there are some tricks you could use to do it (which would be more efficient, too)

First thing that comes to mind is making a table of saveable functions with an identifier key each, and storing the identifier when you save the item instead of the function itself.

Code: Select all

greetFunctions = {
 1 = function() print "hi" end
 2 = function() print "bye" end
}

entity = {
  greetFuncID = 1
  greet = function( self ) greetFunctions[ self.greetFuncID ]() end
}
Now you only need to save the greetFuncID (which is just a number) and the actual function itself is unchanging, so you can always just instantiate it normally. There are probably better ways, though. This is just the first I came up with.

Re: Not sure how to handle many entities on a tile-based map

Posted: Sat Dec 21, 2013 6:48 pm
by Nixola
The string.dump function actually returns bytecode for a function. I can't explain it better than this, so here is some code:

Code: Select all

someFunc = function(something) print(something) return{something} end --just some random function
someBytecode = string.dump(someFunc)
sameFunc = loadstring(someBytecode) --this is actually a copy of someFunc above
SomeBytecode is a string that can be saved to a file and loadstringed to get the function back. You can't dump C functions or functions with closures.

Re: Not sure how to handle many entities on a tile-based map

Posted: Sat Dec 21, 2013 7:46 pm
by slime
Nixola wrote:SomeBytecode is a string that can be saved to a file and loadstringed to get the function back. You can't dump C functions or functions with closures.
Or functions with upvalues of any kind.

For example, this won't work as expected:

Code: Select all

local foo = {}

function bar(k)
    return foo[k]
end

s = string.dump(bar)

Re: Not sure how to handle many entities on a tile-based map

Posted: Sat Dec 21, 2013 8:01 pm
by Roland_Yonaba
Nixola wrote:The string.dump function actually returns bytecode for a function. I can't explain it better than this, so here is some code:

Code: Select all

someFunc = function(something) print(something) return{something} end --just some random function
someBytecode = string.dump(someFunc)
sameFunc = loadstring(someBytecode) --this is actually a copy of someFunc above
SomeBytecode is a string that can be saved to a file and loadstringed to get the function back. You can't dump C functions or functions with closures.
I'd like to add a small minor detail. If you want this work, the given function must be a Lua function without upvalues...

Re: Not sure how to handle many entities on a tile-based map

Posted: Sun Dec 22, 2013 9:32 am
by Robin
Heh, guys, Nixola mentioned that already:
Nixola wrote:You can't dump C functions or functions with closures.

Re: Not sure how to handle many entities on a tile-based map

Posted: Sun Dec 22, 2013 10:37 pm
by Plu
Interesting function, did not know that :)