Im working on a sort of "Wolfenstein 3D" clone for the Playdate. At this point, it does raycasting that allows you to traverse a simple 3D level. I'm bit worried about the performance however and would like to know how it runs on a physical device (still waiting for mine).
Originally, I wanted to get some feedback on performance on it but it turns out it hard crashes on the device so now I'm instead trying to find out why it crashes on the device.
A (very) verbose version can be found here:
From what I've understood, if you connect the playdate device to the computer and run it you should be able to see the logs that it outputs before it crashes.
If you feel like helping out and trying to hunt down the crash I'd be very grateful ofc.
I've only uploaded a build for the physical device as I really am mostly interested in how it runs on a real device. It runs fine in the simulator but that might not translate well to performance on the device.
I've got confirmation that it crashes on the device
I did have created another build that tries to limit it down and only draws the wall - its sitting at
If you feel like trying it out and helping out finding the bug than I ofc would be very grateful I unfortunately dont have a device myself and the crash only happens on a physical device - not in the simulator.
Probably worth incrementing the version number too. I can't remember which one is more important offhand, I just put the build number on the end of the version number these days.
Ok, I removed the game from my PD account and sideloaded the second zip and reinstalled it on the device, to guarantee it was the latest build. It still crashes, I'm afraid. There's no output to the console, so if you're printing anything to that then the crash is occurring before that.
From what I remember reading in another post about crashes you should be able to see the logToConsole messages if you have the cable connected (and run something on your pc) while loading the game on the device.
If you feel like giving it a go and reporting back the log messages I would ofc be super grateful but I also 100% understand if you dont wanna spend more time on it
It renders a 2D image in full RGB that it later on performs a dithering on, I would have expected to see a "makeDitherFS called" in the log before it crashed if it managed to get to the "renderWalls finished" section...
My guess is still that either the dithering or conversion from the dithered image to the playdates buffer caused it to crash.
I can post a build that just cuts out the dithering and swapping to the playdates buffer and see if the crash goes away.
I can't tell much from running it on the hardware debugger, but it does look like a stack overflow. When the fault handler is triggered the process stack pointer is 374,024 bytes below the bottom of the game task stack. Memory is pretty tight on Playdate--we've only got a 10 KB stack there. Does stack overflow sound like a likely cause?
If there's anything else you'd like me to test, just let me know!
I'm trying to narrow it down further, so I've got 5 separate versions uploaded that tries to rule out different sections of the code that could cause the crash. I've tested them all in the simulator and they all run fine with no crashes (as is expected), hopefully one or more of them will run on the device as well without crashing and help me narrow down where the actual issue may be.
They all produce a lot of loggings using logToConsole.
Renders walls, dose'nt perform dithering, draws to playdate back buffer and finally calls pd->graphics->drawBitmap to display rendered image.
If it runs, you should se something.
Renders walls, dose'nt perform dithering, dosent draw to playdate back buffer, calls pd->graphics->drawBitmap to display rendered image.
Dont think this one displays anything.
Dose'nt renders walls, performs dithering, draws to playdate back buffer and finally call to pd->graphics->drawBitmap.
Might show a black screen, but dose'nt display anything interesting.
Renders walls without textures, dose'nt perform dithering, draws to playdate back buffer and finally calls pd->graphics->drawBitmap to display rendered image.
If it runs, you should se something.
I've bumped the version nr on all of them so it should out update if you load them in (they are in range from 1.2 - 1.6, my previous version was 1.1)
All and any testing of this is greatly appreciated ofc!
First of all - thanks for helping out, greatly appreciate it!
The game dose'nt use a lot stack allocated memory so I cant really see that this should be a problem - but I will read through the code again and try and see if there is something Im missing. It dose'nt use recursion at all so should'nt be the problem either.
This is what the memory allocations look like from within the simulator. I'm not sure if this shows only memory on the heap or on the stack as well? This is not from any of the "crash search" versions I've posted here but rather the running version.
I posted a reply further down with a couple of new versions that each try and rule out some section of the code by simply not running it and see if I can narrow down the issue that way. If you got the time and energy to try them out then ofc it would be greatly appreciated!
All run as described, except for v5 which crashes in the same way as before, last thing on the console log there is setupGame finished. Looks like the dither code is the culprit. Do you want any of the other log messages?
About stack allocations, no they won't show up in the malloc log. I can't think of any good way to track those, unfortunately. I dumped a disassembly of the pdex.bin in v5 and searched for usage of the sp stack pointer register, don't see anything that's obviously pushing it way out of bounds.. Ah! Okay, I poked around some more and got lucky. At 0x600024c8 it's moving the stack pointer down with
sub.w sp, sp, r3
and $r3 is 384,000 there. You can see what line that is with
arm-none-eabi-addr2line -e <path to pdex.elf> 0x600024c8
How I did it: I set a breakpoint at the logToConsole function to see if there were any calls that weren't making it out to the serial port before crashing, found one that mentioned a large allocation, set a breakpoint in the calling function at the next branch instruction, and found the stack pointer was way out of bounds at that point. Scanned the code between those two points, and quickly spotted the culprit. Ran again with a breakpoint there and confirmed that $r3 a huge value. I suspect you're doing something like
float buffer[400*240];
inside a function, which puts that on the stack. If you're never recursing back into that function you can declare the array static and it'll move the allocation from the stack to a static memory allocation. And not crash.
Ok, here is a version that hopefully does all the rendering of the walls and dose'nt crash - the dithering code now uses the heap (before it used the stack which most likely caused a stack overflow since it asks for 400*240 integers on the stack). I've bumped the version to 1.7 so should update fine.
You should be able to move around in the little mini level that is here. I've removed the very verbose logging in this one so it should perform not too different from my "working code".
If it does, I would be very happy to hear how it performs on a physical device. It is doing quite a lot of stuff so I would'nt be surprised if it runs slowly though
Very cool
Yeah I was kind of afraid it would be slow, but yeah that is ridicolusly slow
I got hopes on getting a physical device from ebay soon, gonna try and see if I can squeeze out some proper performance with that.
Thanks to both of you for helping me hunt down the crash! Really appreciate it!