The First Month

It's now been a month since I left the world of employment to work on making my own games. So, what progress have I made?

The first week was taken up with Bird Game. Bird Game, with it's many problems that I have no intention to fix, proved that I can still make games. And it also planted the idea to work on something else every now and again, which later evolved into working on something else at least once a week.

Week 2 was the start of Halloween Game. I created a solution with a few projects, the first being the main project, which is a library of code and assets used in the game. The second project is a smaller project which references the library and basically says "use this", and will be used to create the PC version of the game. If it ever comes to consoles, additional projects specific to those consoles can be used to do the same thing.

Then I built the dialogue system (more on that next week), and in the process of getting it displaying on screen to test it, worked on scaling resolution so that I'd have that from the get-go instead of trying to retro-fit it and introduce bugs later on.

After that, I attempted to get the character to move. And then I ran into a problem that I needed to solve.

Instead of having sprites be displayed frame by frame, with each frame being part of an animation, I wanted the sprites to be made up of different parts. One of the features of Halloween Game is being able to wear different costumes, so I don't want to have to draw the same animations for every costume - I want to draw the parts of the costume once and let the code use the same animation no matter which costume is being used.

I knew I was going to store this data in a text file that could be manually edited. But assembling the parts of the character I already had, even without any animations, took a long time - having to find the exact top left corner of a part on the image with all the parts, seeing how wide and high they were, and then figuring out the positions relative to each other took at least half an hour and I wanted to cut that time down. That meant I was going to have to write some tools to help me do it faster.

I'd just hardwired some text files to get data into the game, but at some point I'd have to write import processors to do this properly and my previous experience doing that was not pleasant. I'd planned for that some point to be further down the line, but the start of day 3 was when I needed it to write the tools. The last time I'd done import processors, it spanned too many hours across a couple of weeks, and the end result was that every text file just got merged into a single data file because that was the only way I could get it to work and I wasn't going to break it by attempting to split them up.

So I was shocked when I'd now started from scratch, had each file successfully processed individually and not merged into one, and I was less than an hour into the day. I was now ready to start making the tools. Although I hadn't fully woken up and still felt tired, so took the decision to break from my working hours and go back to bed. Once I woke up, I began working on the tools.

Usually I'd make tools using WinForms, but I wanted a custom control which could display a MonoGame panel. The last time I had tried to do that, I got all sorts of errors that I couldn't find a fix for (thinking about it, the fix is probably something as simple as changing a version number in the project file), and I figured since I was going to have to write new controls anyway that I might as well create a new MonoGame project and have the tools be their own "game".

By the end of week 2 I hadn't finished the tools and was still a way off. It got demotivating not seeming to make any progress, and even jumping back into the game to add a couple of cameras didn't really help.

Then I decided to make some changes to the working week - Thursday would become a half day, and Friday would be added to work on 3D Game as an ongoing side project to let me work on something different that also potentially means I have a second game to release sooner.

Week 3 began with continuing on with tools. I'd switched to getting a dialogue editor working and had a bit of dialogue with all it's options showing with links between them. But I hadn't slept well, in part to my brain deciding not to shut off until at least 3am, so I went for a nap again because there's no point in even trying to work on something complicated if my brain can barely keep my eyes open.

One of the things I appreciate about working for myself is being able to walk away when I know I'm not going to get anything done. I'm not stuck in the office for however many hours are left in the day, and even at home I don't have to be sat next to a laptop in case anyone decides to call. Although I need to make sure I'm not just going for naps all the time.

Returning to the tools, I was adding context menus - options that appear when right clicking - and had a generic one appearing when I clicked anywhere. I'd set it up so that a more specific one would appear if I clicked while hovering over an object, but the specific one was never appearing. Chasing this down resulted in trying to figure out why the mouse's position was always coming through 20 pixels above where the object was, so the code never thought it was in the object's bounds. Then I found some code wasn't firing, and then some events were being lost so they would never trigger, and it continued to descend into chaos to try and figure out which bits weren't actually hooked up.

Eventually I had progressed far enough that it was possible to select a piece of dialogue and change one of it's properties. However the text input required a bit of refining as it was being quite literal with what buttons were being pressed - entering the word Space when the spacebar was pressed, instead of adding a space.

I hate tools.

In trying to get things working, I had lost all sense of structure and was just mashing words into the keyboard and hoping that the resulting code did something that seemed like it worked. It wasn't possible to add new bits of dialogue in the editor, but this made it easier to see the connections so I was happy enough with using a hybrid system of.

To try and get things progressing on the game side, I decided to set up parts of the front end since that wasn't reliant on writing mechanics or making editors. I wanted to add the 'Press button to start' text, but replace the button with a relevant icon. I had icons displaying, but not in the right place.

Maths is hard.

As part of the editor fatigue of just writing code until it works, I was doing maths on all the wrong things. The dialogue system would type out the text to the screen one character at a time, so I had copied out the code for that to use as a base for this icon code. Once the icon stuff was working, I then went back to the dialogue system and made it use the new text with icons code. And then it turned out it didn't work properly with text that spans multiple lines.

By the end of week 3, I was able to change the positions of sprites using the editor. I couldn't add new sprites or edit any animations in the editor, like I had planned, but what I had now allowed me to setup all the icons correctly so that the game no longer needed to have hard-coded positions and could read them from the file.

To finish off the week, I started working on 3D Game with basic character movement and a camera, and watched a few videos highlighting ways to maximize performance when using Unity.

Because I had nothing better to do, I spent Sunday night adding in all the dialogue from the game's introduction, but not using the tool I had written to do this as it was clunky and unstable.

Week 4 started by not continuing with the tools, but by writing out a level into a text file, then loading it into the game to make sure that it was capable of loading and displaying the tiles properly. I spent the rest of Monday hooking together the front end to an empty cutscene, which flowed into the introductory dialogue, and then into the level I'd written earlier.

Part of the game's introductory dialogue.

By branching through the intro dialogue in a certain way it is possible to trigger the end credits, so I also loaded them in from a file and got them displaying.

This means the game is done, right?

Continuing with ignoring tools, I then edited some basic menus I'd implemented to make them functional. With this I now had the ability to change the screen size and resolution from the options menu, instead of setting a resolution in code before starting the game. I then populated the list of resolutions based on the current device's available resolutions.

Booting the game on my other machine later on, to test even more resolutions, I noticed that the profiler said that at it's peak it had used 2.8GB of memory. This did not make any sense. If all the current assets were reloaded on every frame, and not cleared out so they stacked up, then it could take about 15 seconds before the game used that much memory. But the assets were only loaded as they were needed so it definitely wasn't that.

I restarted the game and watched the profiler every time I pressed a button. It was stable going through the intro dialogue and moving around in the test level. Then I went into the options and changed resolution. The memory increased. So I changed resolution again. And kept doing it. The graph kept going up. But I wasn't loading anything whenever the resolution changed, so what was making it go up?

Rather than drawing at the window's resolution, the game draws everything at a base resolution of 1920x1080 to a render target. The render target is then scaled to match the window's resolution. Before adding the ability to swap resolution I was calling the code that sets up the render target once, but now I was calling it each time the resolution changed. Recreating the render target was the cause of the memory skyrocketing. Changing the resolution code so it only updated the scale when the resolution was changed kept the memory consistent.

I created another level about 6 times bigger than the previous level to see if that was appropriate for a small hub world, and added some collision to stop the player going past where I was going to put some fences. The player character was not able to go past the collision at the top and bottom of the level, but could walk through the collision on the sides. This made no sense since the collision at the sides worked on the previous level.

I added draw code for the collision and it was showing up where I had placed it, but the player character did not seem to care. Eventually I discovered that the character was checking the wrong y co-ordinate and was always defaulting to 0. This worked on the first level since there was collision at position 0, but there was not in the new level.

With collision fixed, I somehow ended up breaking it again but I haven't investigated to see what is causing it this time. Deciding to test that the camera transitions correctly between levels, I created some more levels by copying the existing one and changing the tiles to make it look like there was a path leading off the edge of the screen. Except I had to do maths to work out which tiles I was editing and this was taking longer than anticipated.

Despite having thought about abandonding tools completely, I decided to create a new command line project where I can enter a *checks notes* command line and the code will generate things for me. So inputting a command like '--build --level --tilesize 64 --width 1920 --height 1080' will create a formatted JSON array for a level that is 1920x1080 in size, where each tile is 64x64. This not only spits out all the tiles with the correct ones around the edges, but also any collision around the edges too. I can expand this as I need to, so for if example I wanted to create a spawn point then I would go '--spawnpoint 320 480' and it would add one at those co-ordinates.

Creating a level in the command line tool.

Ending off the week I set up some mechanics for 3D Game.

So, what is my plan from here?

I want the game flow in Halloween Game to be done at some point within the next 4 weeks. At first I'd selected next week but as I hadn't started even making the game when I made that decision, I then decided that April 7th was a more reasonable target as it was almost a month later, and I was also going to be taking the week after that off, so a deadline made more sense then.

Having the flow done means I can select new game and move through each area in the game until getting to the end. I don't care that art is not in. I don't care that sound effects are not in. I don't care that events don't trigger exactly as they are designed. The purpose of this is that I can play through and fill in the blanks in my mind to figure out what makes sense and what doesn't, to allow me to shift things around or remove things.

It also means that going forward, it becomes really obvious what still needs to be done. If enemies aren't animating, or entire rooms are just one colour, I can easily spot them and add them to the to do list to help paint a clearer picture on what needs doing.

It would be easier to have a nice way to animate the characters and edit the levels, but I think the tools are going to be too much of a timesink. It's going to require a lot of effort to get them to a point where they are stable and easy to use. Each level consists of at least 510 tiles, and with the command line project can spit them all out to me within a few seconds of loading it up. Adding things into the text file is pretty easy - it's just changing and removing things that will become an issue.

After realising that my current plan for the animation tool did not take into account joints - so moving the arm would not also move the hand - I had a look for existing animation tools. There was one that seemed like it would do the job, but it is expensive and I'd have the uphill battles of learning how it works and then changing my code to make it compatible. Having dealt with horrible workflows before, changing numbers in a text file doesn't seem so bad.

Unless I've missed something, my rough plan is to have everything in and working by the end of July. That allows August and September for polishing and fixing bugs and preparing the Steam and itch store pages for release in October. And, if I'm feeling ambitious, I can see about getting an Xbox or Switch devkit over the summer.

I don't predict a lot of overhead to the game logic to get it working on consoles. As it stands, the only part of the game that will need rewriting for other platforms is the save / load system. Platform specific functions are already passed into the game based on the platform, so if an achievement needed unlocking then the Switch function can be left empty since there's nothing to do, and the Xbox function will need to make a call to the Xbox SDK.

Where I am likely to run into problems is handling cases that I know will fail the compliance checks like disconnecting controllers, or signing into a different account. If it turns out this is super easy, then a release on at least one console in October could be possible, if not then just PC will be fine.

There's lots of things to do before then though. Except the dialogue system. That's pretty much done, and I'll explain how it works next week.

Popular posts from this blog

Getting Started with the FireRed Decompilation

Phoning It In

Tonight Matthew, I'm Going to Make...