![](/media/82211/madness.png)
I've spent two hours fixing a nasty bug. The image above is essentially the bug I was trying to fix, except all the steps were spread in three functions, and took a good minute of playing on average before everything aligned just right (or just wrong depending on how you look at it) for it to seemingly randomly occur.
Can you figure out why t[2] is not 8 in the end ?
Hint : Lua arrays and # operator are cursed.
Ideally, I'd like the game to crash at t[i]=8 if possible. Anyone knows if you can add some sanity checks to all array accesses ?
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/68936/5_BigVerb.png)
Best guess is I is internally 1.999... but it rounds to 2 when printing.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/82211/7_realshadowcaster.png)
That is correct and the 1st step of the problem, but I would have found it quickly if the index had been truncated and off by one. The wild part is how lua handles the array access : it happily adds a new entry in the array with a non integer index, but does not increase #t .
So as long as you do t[i] with the Index that contais the rounding error, you get the new value, but if you later iterate over the array with an integer index, you get the old value back from the dead, very spooky and confusing.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/85395/picocolordance_24.gif)
Tables can contain a mix of sequential, 1-based integer keys and other keys (strings, non-integers, 0 or lower values). Only the 1-based integer keys are considered by the operator # and functions such as all()
.
See the warning in the manual:
https://www.lexaloffle.com/dl/docs/pico-8_manual.html#Table_Functions
Edit: To be clear, I agree that this is confusing behavior due to the rounding issue, but it is pretty similar to the kinds of problems you'd face with older languages. For example, in C++ I believe your expression 3*(1/3)+1
would be =1 which is also pretty unintuitive, but something you have to learn to work around.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](https://www.lexaloffle.com/bbs/files/32759/comovic.gif)
You can use i\=1
to avoid decimal values in the index. This is lighter than implementing a function to check.
You can also use tbl={unpack(tbl)}
to repackage it into an integer index array (table). However, you need to remember that this is a repackaged table when the numbers you thought you had entered are not there.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/92447/Logo.png)
@shiftalow I saw a reply somewhere advising the use of x&-1 instead of x\=1, presumably because bitwise and'ing is faster than integer division.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](https://www.lexaloffle.com/bbs/files/32759/comovic.gif)
@Soupster
Oops, that was a blind spot!
It's true that logical operations are faster.
I'll have to update my trifill code...!
Thank you.
I wonder if &-1
is really the fastest, and &0xffff
seems like the more straightforward way to write it. (The calculation result should be the same.)
Apologies for getting off topic.
[Please log in to post a comment]