I'm not too sure about this one, and what makes it worse is that I'm working in Nim. So, a minimal reprodicible sample will be hard to come by. But the facts are thus:
the only thing I can tell is that this is an unaligned access
[11:12 PM]
so somehow the processor is accessing a 16- or 32-bit value on an address that isn't aligned for that
I just played Gun Trails, which I'm pretty sure is a C-game using scoreboards. It crashes on 2.6.0-beta4 before reaching the start-screen, presumably because it pre-fetches the scoreboard.
I used the "gather diagnostics" and "send crash report" options. Panic-people may use the timestamp of this post to find it in their database.
Probably not related, but on sim I might get this error message when calling getPersonalBest(): Player not registered
I assume this means I need to register my sim with my account. But when opening the Serial Number and Access Token window, The fields there match the info on my account (last sync date: today) and the window shows a green checkmark. In the settings > account I see my name and join date.
Is there anything I'm missing regarding this? Are there particular sim-only and device-only boards?
It looks like the crash is in your code, the $pc register is in the game code memory area. If you open the pdex.elf file in arm-none-eabi-gdb and do info line *0x15036 (game code is compiled to base address 0x0 then relocated to 0x60000000 on rev 1 hardware, 0x90000000 on rev 2) it should show you where it's happening. The cfsr register says that's an invalid access error, with the bad access happening at mmfar=0x8. One way that could happen is if you're trying to access the player field at offset 8 in the score you're getting back, but the score is NULL because you're getting an error instead.
Thanks for teaching me how to fish! I was able to find the function name where the crash happened, at least (line number doesn't make sense because the c code is generated from Nim source)
My assumption was that errorMessage and score are mutually exclusive, so I check the length of the message > 0 and then proceed to read the score.
In lua, the error message is "No personal best" in this case. Seems there is a discrepancy between lua and c. On the C-side, both score and errorMessage are nil.
I would suggest to copy the lua behavior and return an error message in this case. Alternatively: revise the scoreboard api docs, and explicitly mention that both error and score can be nil. There is also a mention of this score only being fetched from cache in lua while there isn't in the C. Which may or may not be correct if the behaviour differs.
Double-check: is it indeed the case that in C both error message and score are nil in this case? I couldn't attach a debugger on device, so I can only go by the fact that with this Nim code, the "Playdate-nim" error is indeed printed:
proc invokePersonalBestCallback(score: PDScorePtr, errorMessage: ConstChar) {.cdecl, raises: [].} =
if errorMessage != nil:
privatePersonalBestCallback(PDScore(), $errorMessage)
return
if score == nil:
privatePersonalBestCallback(PDScore(), "Playdate-nim: No personal best")
return
[... proceed to read score ...]
Yep, you're right. It turns out that "No personal best" is created by the Lua wrapper when there's no score returned and there's no error. I'm torn: agree that it should be consistent, but I also don't think that should be reported as an error.
I think I'll leave it as is, where you get double NULL if there's no personal best, but I'll document it. The API is already public, and I hate changing API behavior if there's any chance people are already using it
I will return an error on a double NULL from the playdate-nim api I am buliding though. I think it is the better behaviour also in line with http 404 which is an error code. It also fits our philosophy to provide an API that has native performance and the comfort / breadth of Lua. And I do have the luxury of no existing users ;-p
I'll prefix it with playdate-nim though so it's clear it is no sdk error