It’s been a few days since my last news post and it’s been a hell of a busy week since. Figure it’s time to let you know what’s been going on.
First, I’ll summarize my last news post: I’m writing code that will write my code so that I don’t have to code.
That’s pretty much done. But in doing that, I spent a lot of time looking at the code in it’s current state and realized just how much experience I’ve acquired in the last year of making this game.
I started examining some of the problems I’ve been having with broken saves, evolving classes and objects, the structure of the story, and in general just how my code interacts with itself. This really put me into a long term mind set and got me thinking about what I could do to make things more stable going forward.
A number of solutions quickly made themselves apparent. Solutions that as a rookie renpy programmer were not immediately obvious. But having worked through so many quirks and problems in the last year, I started imagining ways to avoid those going forward.
Now the rest of this post may get a bit technical, but I want to try my best to convey not just how much work is going into this, but how it’s going to benefit you in the long run.
I want to be in full creative mode. I want to sit down, write stories, make art, dump it into a file and forget about it.
As we go through these, remember my end goal is to NEVER CODE AGAIN! (not now, and not in any of the 100 future games I want to make).
Problem 1: Broken Saves
This is something that has irked me from day one and I realize that a big part of that problem was how I kept changing the code around trying to find a good ‘fit’. Add to that the complexity I introduced by having different classes and objects all recording different stats and info and before you know it, I’ve got variables and instances all over the place keeping track of different things. If I change how one class works, it impacts a cascade of others and I have to go through and start scrubbing code to make all the corrections.
Even then you miss some, saves break or errors pop up and the whole thing becomes a shit storm. Essentially you wind up with different saves each based on a different version of the code and everything hates each other and won’t work.
Solution 1: Centralization and Static Methods
It’s still handy having different classes handle different functions. But instead of having to initialize an instance of those classes and let them store all this individual data all over the place, why not just give them a job to perform, and then hand off the results to a central record keeper that will keep all the variables safely locked in a single place? And while I’m at it, I should design it so that they don’t have to be instanced to do it.
This way, if the class needs to evolve or change, there is no instance of it in the save file. The game won’t know or care that it changed as long as the output of the class methods remain the same. If the output is the same, there is no code to scrub for and update, and the train continues to run smoothly.
Of course, there is still data that needs to be retained between plays. So I created The_Scribe. Now ALL of the variables that change during the course of play are now being saved in a single instance of the scribe who records and tracks all the stuff that changes during the course of a play through. All the variables in one place. If a function or statement needs to know something, it turns to the scribe because it knows all! Nothing in the game can change without it knowing, and it remembers! (Ok, that got a little ominous but I was feeling it.)
As a bonus, if for some reason I need to improve the scribe in the future or add features to it, I can create an updated version that takes the old version as an initialization parameter and all of your data will flow into the new object during the loading process and the game will continue to function without error.
By following a few simple rules, there should never be another broken save.
Problem 2: Some Classes and Screens need Data that requires periodic maintenance
A perfect example is the Character Selection Screen to start new chapters. In order for that screen to do it’s job, it needs to be told what chapters are currently in the game, and whether or not they are currently accessible in the story.
This means whenever I add a scene to the game, I need to go into the code, add the new scene to the available list of scenes. Then tell it what conditions are required before it can be played, like whether or not the preceding chapter had already been completed. And finally I have to debug it and make sure it works.
The same goes for the objects that calls on music, sound effects, images, etc. It’s not a massive burden, but it’s work. And any time I have to touch the code there is a chance something is typed incorrectly, not properly indented, or a dozen other small things that can break the code and require debugging.
I don’t want to do it anymore.
Solution 2: Find it your damned self!
Objects that now rely on the existence of files can track them down on their own. Using the example of a new chapter in the game. The Class responsible for managing the story flow will use it’s static method to scrub the directories and find all of the scene files in the game. It opens each file and reads the first line and uses the information to make a temporary dictionary of scenes and their requirements (like completing chapter 1 before you can play chapter 2).
With this temporary dictionary in hand, it asks the scribe (our central recorder), which scenes have been completed and what other conditions have been met. It uses the info to filter out any scenes that are complete and not currently available.
It takes what’s left and throws it over to the character selection screen to be displayed by the player and then immediately forgets about everything it did so that the next time you are at the character selection screen it can start the process over and make sure you only have the most up to date information.
It also means that after I write a scene, all I have to do is drop it in the file and the game will find it on it’s own. I don’t have to update any code. I don’t have to input any parameters. Everything is self contained and automated. LIBERATION!!!
The same goes for when I add music, sound effects, or new characters. There are classes that handle each of these and when the game needs the information, they fire up, search for their respective files and hand off the info to whatever process called it without ever saving a single thing to the save file and without me having to add anything to the code.
Problem 3: Missing Files and Errors
So with all this automation, there is a certain degree of failure in that if a file isn’t found or is there one minute and suddenly gone the next, that a crash will occur. I could of course write error handles that would check for the existence of this or that prior to running a section of code, but that’s a lot of work.
When I have three or four game variants available that rely on different images, and an image is missing, the most thorough thing I can do is test the existence of each image before trying to load it.
It’s a shit ton of work and up till now I haven’t done it because “fuck it, I’ll fix it if it’s broke”.
Solution 3: Make the Code that Writes the Code Write that Code
Well now that I’m getting away from coding altogether, and I’m making code that will handle the coding, I’ll just make that code handle the error handling as well.
A simple example is with the alternate images. Some characters have outfit changes for certain scenes depending on whether or not they are currently blue or red. Sometimes, I incorrectly name an image or something gets moved. Whatever, the point is, the game finds the error and crashes.
Now I can add a few lines of code to each image that will test it’s existence first and if not found fall back to a default and keep on moving. That doesn’t mean it won’t be odd when suddenly a character’s outfit changes and then swaps back. But at least the game didn’t crash! And I don’t know about you, but I’d take a distracting hiccup over show stopping vomit any day of the week.
Plus I can always go back and fix it after the fact, but at least your play through didn’t crash!
That’s just one example but there are several places I’ve added error handling that should increase stability going forward.
Anyway, I think I’ll stop there for now. There’s much more I’ve been working on and adding to the code (Including modifications that should make an Official Android Build possible in the next month or so) but I’ll share that later. Just know that when it’s done, all the weak spots should be shored up and all future development should be a cake walk.
Right now, I estimate another three or four days of coding and by this time next week I plan to be in 100% Creative Mode. No more coding and no more broken saves.
Nothing but story, art and bright horizons! I’m excited as fuck!
Till next time, thank you for your support and I salute you!