When I'm starting a new game, I usually have arrays for different things. Like one array for enemies. One array for bullets, one array for friendly entities.
Then I always wonder, when the number of arrays grows, whether I should store everything in a single array.
Storing it in a single array means you have to check the type each time you scan the array. E.g. when a friendly bullet does collision check with enemy.
On the other hand, if you need to check against multiple types of entities, you need to scan through multiple arrays.
Is there any common approach to this problem? How do you handle this?
There's not really any benefit. A table is 17 bytes of memory plus contents, while the under the hood storage is a table as well (which probably uses a hash table/dictionary in C), so lookup is the same amount of time anyway. Typically I would only expect everything to be stored in a single array if you need them to be treated as the same in some sense. For example, if the same treatment needs to be used on all objects for a chaotic world, that structuring would fit. That said, there's a pretty major downside: deleting objects gets more expensive. If you choose such an approach, it's important to create a constant pool of objects and mark them when not in use instead of deleting.
That said, I can think of two ways off the top of my head for how to avoid type checking if you store all the entities in a single array. 1. keep track of where the sections with each type begin and end, adding any new ones at appropriate indices and incrementing the records as needed. This is basically just a more memory efficient version of having multiple arrays. 2. store functions on each object that can be called for each use of the object. For example, when a when a friendly bullet does a collision check for an enemy, it could call the object's fcollide
field, with other friendly bullets and the player object all having a function that just returns false.
@kimiyoribaka I wasn't concerned about performance, though that's of course also a part of the story. My games usually only have some ten entities. The question was more about easy of coding.
Storing everything in one array, but having sections of the same type sounds like the worst of both solutions. Then separate arrays are easier to handle.
performance is really the deciding factor on the games I made + how/if spatial partitioning is needed + if game engine ‘assumes’ all entities to be of same nature.
Nuklear Klone: 2 sets (many bullets + entities) + spatial partitioning only for entities
Poom: 1 set (few bullets and mandatory spatial partitioning for everything)
noob here needs help getting over some syntax "hurt"les. This thread very much pertains to some general questions I have so I hope it's okay to post here.
1st of all, Is there a comprehensive and/or free guide to proper syntax for running functions, loops, if statements, and using modulus, on 2d,3d,etc. tables?
for instance the manual shows: ADD(TBL, VAL, [INDEX]) and besides one line stating, "If index is given then the element is inserted at that position:" it doesn't elaborate or give an example. I've tried it on some 2d tables with no success
having Trouble getting "[]"s to work properly in general.
after generating some tables and running some FOR I DO ADD(tablename,{X=,Y=,type=,etc}) loops in the _INIT function if i do a PRINT(tablename[1]) I get (TABLE) which is correct.
But, if I do: PRINT(tablename[1][1]) i get (NIL). shouldn't I be getting the first x coordinate? If I however, do another: FOR I IN ALL() DO PRINT(I.X) etc.. loop it works, printing every X entry in the array. whats up?
how do I setup proper 2d FOR ALL() ADD() loops?
how do I apply a function across multiple tables that carry the same variable types without having to copy and paste huge swaths of code for each table?
i.e. like all having x,y coordinates that the draw function interprets the same exect way but, because, as far as I know, it only goes: ALL(Just1StupidTable,{whatever},[ThisDoes'ntWork]) I have to make an essentially new function for each table.
I've also tried watching some lua tutorials. Maybe I'm wrong(noob) but, it doesn't seem to translate perfectly. I've already tried some stuff.
> if I do: PRINT(tablename[1][1]) i get (NIL). shouldn't I be getting the first x coordinate?
no! because the nested table does not have numbers for keys ({ 20, 10, "blob", false }
) but strings ({ x=20, y=10, type="blob", flip=false }
) so to access you need to pass the right key: tablename[1]["x"]
(or the shortcut tablename[1].x
)
more about tables: https://www.lexaloffle.com/dl/docs/pico-8_manual.html#Tables
all
is a function to iterate, you may want foreach
to apply a function to items in a table (but only a numbered table, not a key-value table)
@nerdart9
pico-8 uses Lua 5.2 plus a few extra alternate syntaxes, so the main authority for how syntax is supposed to work would be the Lua 5.2 manual. It's hard to read if you aren't used to technical specifications though. That can be found online here: https://www.lua.org/manual/5.2/
There's also an online version of "Programming in Lua" that has a lot of explanations on how to do common tasks. The version that comes up when I google it is for 5.3 though, which has a few difference in more obscure features (like not having goto
). Here's its page on multi-dimensional arrays: https://www.lua.org/pil/11.2.html
That said, I noticed that you put all()
as taking the same arguments as add()
. That's not the case. all()
only takes a single table.
[Please log in to post a comment]