Week 14: A crash-log auto-reporter, and save/load support for platform-graphs (a big performance boost!)
|New icons for my Scaffolder and Surfacer frameworks!|
tl;dr: I created a crash-log auto-reporter with Godot+GCP, and started adding save/load support for the Surfacer platform-graphs (a big performance boost!).
What happened last week?
- Created an automatic crash-reporter.
- Renamed my "Godot Scaffold" framework to "Scaffolder" and struggled with the consequences in Git (more on that below).
- Added a lot to READMEs and other documentation.
- Started implementing save/load support for Surfacer platform-graphs.
- Laundry list:
- Spent some time installing an Android v6.0 emulator to try debugging a crash report.
- :( No such luck. It works for me!
- Although, the touch input events seem to drop a lot and retrigger annoyingly, so maybe that’s a separate issue I could fix for some folks?
- It looks like my Google Ads iOS campaign somehow got throttled on March 19th, and hasn’t been spending any much money or getting many views since?
- I upped the budget for it, in case that’ll help...
- Implemented an automatic crash-log reporting system.
- This should help me debug some issues that only repro on certain devices that I don’t have access to.
- Refactored bootstrap and configuration flow to delay as much as possible until after the new CrashReporter has finished uploading (if there is something to upload).
- Researched options for uploading and storing these docs on GCP.
- Decided to go with plain GCS:
- Enabled a GCP Billing Budget.
- Created and tested a GCP PubSub-based Cloud Function which will disable my billing account when it goes over budget.
- Created a new dedicated log-handling scaffold class.
- Updated the scaffold framework’s README to describe more of its features.
- Created data-agreement versioning, so that I can force the player to re-agree to terms if they ever change.
- Lost about 4 hours to trying to fix issues relating to Git submodules.
- Tried to configure them to only sync shallowly.
- But that led to always having detached heads, which I can’t commit.
- And then I tried and failed a dozen times to undo things to get back to a stable repo state.
- Verified that CrashReporter works on Android.
- Created framework icons.
- Started implementing platform-graph save/load support.
- The save/load support primarily involves translating game state to and from JSON strings, which isn't too complicated, but there are a lot of data structures to encode and decode.
- This give a big performance boost when starting levels.
- Created a TileMap wrapper for Surfacer, which makes it easier to ID and configure defaults.
An automatic crash-log reporter
- At the start of the week, I got a report from one user that the app was crashing whenever they tried to load it.
- I tried to diagnose it with an emulator, but I couldn't get the crash to happen.
- I think I need the app to be able to upload error logs if I want to be able to diagnose errors like this in the future.
- I decided to use Google Cloud Storage (GCS) to host these crash logs.
- Godot can record all standard and error output to files.
- My system then just reads the latest log file and checks for any errors near the end of the file.
- If an error is found, the file is automatically uploaded to my GCS bucket.
- The problem: Most crashes happen at the very start, while the app is still initializing, and before my crash-reporter might have a chance to run.
- The answer: I refactored how things are configured and the initial sequence of events, in order to let this crash-reporter run as early as possible, and then delay everything else to wait until it's done.
Ugggghhhhhh, version control can be such a headache sometimes.
At one point on Tuesday, I decided that I wanted to rename my scaffold repository from "godot_scaffold" to "scaffolder". And that's where the trouble began...
The problem with Git, is that it's designed around the idea that if you want to pull-down some code, you will need to not only pull-down the current code, but also the entire history of all changes that have ever been made to that code. So when you have a repository with thousands of files and thousands of commits in its history, it can take a long time to pull it all down the first time. Especially if you also have lots of media files in the repository, like images and sounds, which you need in a game project.
So I thought, there's got to be a better way. I did a tiny bit of research and learned that Git does have a handy "shallow" option for just pulling-down the latest snapshot. So I set that up for both my top-level repo, as well as for both of its submodules. But then I made some changes, and wanted to push my changes back up to GitHub. At that point, I learned that when you only have a shallow copy, you are in a "detached HEAD" state, which means that you can't push your changes back up (at least in the normal ways).
So then I re-looked-up the various ways of resetting Git history back to a previous version (which I always forget, since I don't do it very often). But there was some sort of conflict when I tried resetting the submodule state. So I banged my head against that problem without for a couple hours before getting things back to a stable state.
For now, I'm just going to stick with just pulling down the full history for all three repos whenever I want to make a fresh local clone.
And I don't have my submodule configuration setup to magically make things easy in fewer steps. After cloning the top-level repo, I have to run two other (very slow) commands to get the submodule state pulled-down.
Oh well. I'm sure there's a better way to set this up, but I'm not the deepest expert with all of the fiddly edge-cases that Git supports, and it's not particularly worth my time to experiment with them at the moment.
- Finish implementing save/load support for Surfacer platform-graphs.
- Then take a brief break to learn about Unity!
- I'm going to do another game jam at the end of the month, Ludum Dare 48.
- I'll be doing this one with another group of friends, and we'll be using Unity and 3D tools.
- So I need to learn to use Unity!
- Unity is an industry-standard game engine (much more so than Godot), so it'll be really good for me to know more about it and how it compares to what I've been doing.
- I'll go back to Surfacer fixes in Godot after the game jam.