Swashbuckler Seas Development Reflection based on a walkthrough of its GDevelop events sheet
Let me begin by saying itâs one thing to be theoretically cognizant of the âdefined... architecture for the overall game programâ as:
â1. Initialisation (Init or Start)
2. Game Loop (Main or Update)
3. Termination (Cleanup or Quit)â
--and another thing altogether to develop a game large enough (ha!) to experience it and really get your hands dirty (CodeHS, 2022).
Iâve been using the following excellent flowchart from the blog Read Write Code as a general reference for this structure:
However, in truth, this is the structure that has intuitively arisen anyway in the development of Swashbuckler Seas, and Iâm inclined to think that, as long as computers continue to work the way they do in terms of processing, this is how any and all games look as programs.
As the sole âprogrammerâ on Swashbuckler Seas (if you can call looking up whatever arbitrary language GDevelop uses for otherwise standard conventions, âprogrammingâ) Iâve made it my business throughout this piece of assessment to refine my programming and coding practice. The benefit of using something so accessible and simplified as GDevelop, of course, is that this refining of good coding etiquette hasnât become sidetracked by simply not being able to speak the programming language-- for the most part.
Iâll admit it-- I didnât organise all the parts of the game program into appropriate groups until I was absolutely waist-deep in mechanics, both used and discarded, cherry-picked and adapted from all sorts of YouTube videos and GDevelop forum posts.
When I did, however, I think I actually realised satori.*
Moving on, the Start phase of the program runs as follows:
The music begins. Any relevant timers begin. Variables are set to their defaults. The camera is set.
Now, I have no doubt that to the experienced eye (i.e. not mine), literally none of this is new or particularly surprising. I also have no doubt that there is likely a best practice for what order in which these things should be initialised-- off hand, I wonder if itâs more prudent to have the timers begin before the music, for example. In a pragmatic sense, it probably doesnât matter, but I wonder about these things in terms of keeping code clean and extending consideration toward anyone else who might also be handling the code.
(In this case, obviously, there was only me. Needless to say, what you wonât see in any of the âcodeâ throughout this post is the struck-through remains of unused, omitted or disabled features and mechanics, which I cleaned up for the final version, and which would have definitely presented issues for any fellow programmers on the team).
Now hereâs a âlearning moment.â I should probably not begin the Game Loop proper with the health/firepower upgrades mechanic.That probably belongs after player controls, player health, scoring, etc. Chalk it up to something to bear in mind in future. Incidentally, this was one of the last things I added to the game, and I think in my search for a fresh start on a feature, I simply created a new event underneath the Start Phase, and the rest was history.
Being one of the last things implemented in the game, Iâm proud to say that I actually required very little assistance from online sources in writing this âcode.â I already knew how to set a condition for the player clicking on something, changing scene variables, the difference between a global variable and a scene variable, creating objects (and on the correct layer, too!), starting timers, and playing sound effects.
(The Score I had to change from a scene variable to a global variable when I wanted to carry it into the âGame Overâ scene. That was an exciting âfind and replace,â let me tell you.)
Upgrading the maximum health hearts was a struggle, actually. I was nervous to change the code around the hearts as I had adapted it from a tutorial and there were parts I didnât fully understand. I experienced what I have no doubt is the classic programmer anxiety around pulling one block out of the proverbial Jenga stack and having the entire thing simply stop working unaccountably, creating an extra three hoursâ work for me.
Nevertheless, I persevered and talked myself through the logic of the events (as I like to do while coding) and the entire thing turned out to be much simpler than I had anticipated.
Implementing the 360-degree spray of cannonballs was really fun. Again, Iâm glad I didnât try to implement it earlier, because in particular I needed to be able to manipulate object instance IDs in order to determine the angle of each of the six cannonballs. And I couldnât do that until I had finalised the health hearts system.
My intuition as to the âcostâ of these Upgrades in-game-- i.e. how much of the score the player must spend to earn each upgrade, turned out to be fairly spot-on. The exception was the multi-cannonball upgrade, which had to be nerfed by increasing its cost to 2000 points, as it rendered an already comically easy game positively braindead once you accessed it.
Now this is interesting. Originally, the game retained the original controls we were instructed on our âAsteroidsâ prototype: mouse only. This, to my thinking, was a boon, considering it made the game very accessible to mobile players, who represent an audience with a terrifying growth rate within the games market, to the point where some researchers have actually identified âa gradually shrinking traditional gaming marketâ (Cai, 2022).
However, during collaborative team discussions, we decided we wanted the player movement and the player fire to be more separated, and a little more nuanced. We wanted the player to have more control over on-screen elements using the cursor, while enabling them to continue to move around the map. This was especially important when considering the slide-up Upgrades menu.
Other than that, I would note that it was fun to learn how to manage a separate weapon sprite from a player sprite, and I remember thinking that this would be a useful thing to understand for future game development. In this case, it was made simple by the fact that, as reflected in the code, the cannon would âAlwaysâ need to be in the center of the ship. (This in itself meant that I had to get to grips with the Points on the sprites, learning that sometimes GDevelop considers certain âpositionâ actions using the âCenterâ point, and others using the âOriginâ point, and thereâs no way of knowing in advance what the program will do).
This was frustrating. I found a YouTube tutorial on creating an arcade-style score with leading zeros. (Or at least, a demonstration of such a feature with, well, something to be desired in terms of explanation and detail), but no matter how hard I tried, I kept encountering an issue whereby the number of leading zeros at the beginning of the game changed once the player began earning points. Iâm sure itâs actually a very easy fix, and if I set my mind to it, itâll only take a maximum of half an hour. But it fell to the bottom of the bugfixing priorities.
In deciding that the map of the game world would extend beyond the window, of course the issue arose of enemy spawning location. In its Per My Email days, this part of the events sheet simply had enemies spawning in random spots on the map. Simple!
However, now we needed enemies to spawn anywhere on the map, except in the field of view of the player. For the longest, most irritating while, it somehow slipped my mind to create variables representing the extreme sides of the map, and instead I had coded hard co-ordinates into the enemy spawning mechanic. When I finally saw sense, I was able to respond to team-member requests to alter the size of the map with much greater ease.
To further comment on enemy spawning, likely the most interesting feature to me at this point, yet also the smallest detail and also the most last-minute detail to be added, was the spawn rate.
One of the core pieces of feedback which was consistently raised by playtesters was the difficulty of the game. It was possible to sit in one spot, fire in all directions, and not see a single enemy for minutes on end, earn 1000 points shooting off-screen enemies, purchase the multi-cannonball upgrade, and then you could really grind up the score, rinse and repeat.
I had the rough idea of implementing a simple time-sensitive difficulty scale. The simple addition of a timer for âelapsed timeâ and tying it to the spawn rate of enemies actually added a rudimentary additional level of challenge to the game. It added, in fact, a sense of rising tension and urgency to gameplay.
Given more time on this game, I would have liked to have playtested this thoroughly and refined the specific values.Â
Originally, the health restore item was a rum barrel, as I thought it fitted with the pirate theme. However, I created the sprite in a rush, and no playtesters were really sure what to do with it. It also created confusion whereby if playtesters learned it was a health restore item, they also thought they might pick up points by running into debris.
If Iâd had the time, I would have added an animation whereby it rotated and behaved more like a barrel, and less like a badly-tweened Flash animation prop circa 2008.
Thereâs not a whole lot to say regarding the collisions in the game, other than the fact that itâs pretty clear at this point that I took Per My Email and built on it for this game. There was a lot of logic involved in ensuring objects were created and destroyed appropriately, and scene variables updated properly.
There is an unused variable/function in there called âPush,â which again, is from a tutorial I used to implement the hearts system. The idea was that there was some pushback to the player sprite on sustaining damage, however this was another minor ânice-to-haveâ bugfix that fell to the bottom of the priority list.
My gods, if someone had told me earlier that GDevelop had a âfor eachâ function!
And I think I just spotted the issue with the âPushâ function. I forgot to introduce the variable âDamage.â Cue head-smacking.
Need I say more here? The Health variable is equal to or less than zero, you die and we change to the âGame Overâ scene. I should have probably removed the âdeathâ sound effect, since: a) itâs me indecorously going âbleghâ into a microphone, and b), itâs inaudible considering the louder âGame Overâ jingle which plays on the scene change.
*The state of awakening in the Zen Buddhist tradition.
Cai, X., Cebollada, J., & CortiĂąas, M. (2022). From traditional gaming to mobile gaming: Video game playersâ switching behaviour. Entertainment Computing, 40, 100445. https://doi.org/10.1016/j.entcom.2021.100445
CodeHS. (2022, March 3). Teaching the Game Loop. readwritecode.blog. https://readwritecode.blog/teaching-the-game-loop-4c264398384
GDEV in 60 Seconds. (2021, April 5). GDevelop 5 Score and Countdown Timer [Video]. YouTube. https://www.youtube.com/watch?v=qraa4xgvLmY
NT_exe. (2020, August 24). Health points as hearts in Gdevelop [Video]. YouTube. https://www.youtube.com/watch?v=sKVQsdaH3l8