This is one of those posts that have a bit of everything, so no decent title for it…
Anyway, as you might have seen in the Spellcaster Studios blog, me and Rincewind gave up on the Indie Speed Run, mainly because of scope issues… We went a little wild with it, Rincewind because of lack of 48-hour compo experience, and me because I thought that without needing to do graphics I could do much more…
Anyway, it was a good exercise, and I’m definitely finishing this one, not because it is brilliant, but it’s great to figure out bugs on SurgeEd and SurgePlayer, which I used for the game. Already figured out some nasty bugs which would have taken a lot of time to fix on the “Grey” scripts, specially one that only seems to manifest in specific conditions…
If you’ve been following this blog, you know I’m using Lua to drive the game logic, and specifically LuaJIT, and I found an odd behavior…
The offending piece of code was something that tested a condition and acted on that:
function do_something(param)
if (ffi.C.test(param)) then
change_object() end
end
test is a function declared on the FFI, that returned a bool:
ffi = require("ffi")
ffi.cdef[[
bool test(const char* str);
]]
Which had a C counterpart like:
extern "C"
{ bool __declspec(dllexport) test(const char* str)
{
bool b=do_some_test();
return b;
}
}
Simple enough…
Problem is, “change_object” was never reached… First I thought it was the “do_some_test” function that was failing, and I added some tracing to it (writing to the logger) with the output, and it turned true eventually…
Then I added some tracing in the “do_something” function, and mysteriously, it started working properly… After a lot of tests, I found that if I used any function that called normally bound functions before the “ffi.C.test” call, the system worked properly… But if I added FFI based functions, it wouldn’t work!
This was driving me crazy… then I had a silly idea… “bool” is a C++ type, not C type, so I changed the declaration of the C function (not the FFI declaration) to “int __declspec(dllexport) test(const char* str)”, returning 1 if “do_some_test” was true, and 0 otherwise… And now the system worked properly!
So, I arrived to the conclusion that you can’t output “bool” directly from the C code (although you can declare it that way on the FFI declaration, to get a proper bool and not an int). I imagine the problem was the size of a bool and the stack manipulation of LuaJIT, which caused the system to access corrupted memory (that was probably zeroed before being used, and that’s why the function apparentely always returned “false”, although the C output was “true”).
Anyway, 2 hours of my life getting to the bottom of this… Had to change all the functions that return a bool to return an int instead…
Anyway, on other news, take a look at this Hamnasya game… It’s a cross-media kind of game, where you’re reading a book, but you can affect the outcome and fight battles à lá RPG… Very cool stuff indeed, and has an excellent trailer:
I haven’t picked it up (I had too many pending games at the moment), but it looks pretty good…
If I don’t write anything in the meantime (highly likely), Merry Christmas and a Happy New Year!