Hello all, I'm still learning about PICO-8 and I'm interested in ensuring I understand the implications of using local variables, global variables or upvalues.
As many do, I use a for/in loop to update my roster of enemies:
for en in all(ens) do local ecx,ecy,efov=en.x+2,en.y+3,0.1 --apply friction en.dx*=(en.dx>0.05 or en.dx<-0.05) and fric or 0 en.dy*=(en.dy>0.05 or en.dy<-0.05) and fric or 0 if (en.alert>0) efov=0.3 --sees player? if (sees(ecx,ecy,pcx,pcy,50,en.fac,efov,2)) then --face toward player en.fac=atan2(pcx-ecx,pcy-ecy) --set terminus en.tx,en.ty=pcx,pcy en.alert=2 -- ...etc |
My question is regarding the locality of the current element ("en" in the example above) and its constituent table elements. If I'm going to be reading en.x, en.dx, etc. multiple times within the loop, will it save cycles to make local copies of each of these first, or are they already local by being part of the current element ("en")?
Thanks!



loop variables are automatically local! but that doesn’t change anything about accessing items in table, you still need en.x
etc. they are table items, not variables. when you have en.x
it really means en["x"]
which is two operations: get local variable, get item in table.
yes, you can save the cost (tokens and cpu) of repeated item access by getting their value as a local variable (local enx = en.x
) but that also takes some characters and tokens, so it’s a balancing act as always :)
there is an advanced trick to use a table as a scope, so that you can use table items like variables (e.g. write just x
and automatically read from or assign en.x
): https://www.lexaloffle.com/bbs/?tid=49047



Thank you @merwok, that makes a lot of sense, and I hadn't even considered the token savings from dropping the accessor operator so that seems like a great starting point.
I had no idea about the _env
trick so that is really enlightening. It seems tricky to use since switching from the normal global environment not only restricts me from global vars but also PICO-8 native functions, however if I can wrap all the fully internal operations in a do..end scope and swap the _env
only there, and then swap back to global for interacting with the rest of the game, that could theoretically provide some savings... but I'm not sure how that would shake out.
Thanks for your insight!



the issue of accessing builtin functions is discussed in the linked post! lua tables have prototype inheritance so that item access can be chained from a table to another (the original _env) and solve this problem
[Please log in to post a comment]