Devlog #4

I am moving at a relatively good speed, and have nearly completed the scope of a first early prototype, on which I hope to collect a first few feedbacks.

But before moving forward, I had a last mechanism that I wanted to implement: in my game, you use an electrical bike to move goods between destinations in Kerry County. Given the distances, your bike will run-out of battery during the day, so I wanted to give you the opportunity to charge it in some locations. In short, exchanging time for range (knowing that without battery, you will be way slower, losing therefore even more time). Seemed simple enough. Spoiler alert: it ends up being my first scope creep and architectural failure.

It looked rather straightforward though? A bike charger is tied to a location, so I just needed to extend my locations: add a simple boolean to indicates a location has a bike charger, display a button if the boolean is yes, and when the button is clicked, set back the battery to its max value. Simple. Basic.

Except that :

  • the Bike Charger was one type of « service » I wanted to implement (with a second already quite clear in my mind). I made sense to implement a bike charger as a service, so that I could use the same base for all of them in my location and avoid duplicate / redundant mechanisms and code
  • it made sense that you might not want to spend the time to load your bike until it’s full, but rather just enough to finish your day
  • moreover, it made sense for the sake of realism but also gameplay to propose trade-off / decision to take when charging your battery: the fuller the battery, the longer it takes to charge it. In other words, the first 50% are quite fast, the last 15% are rather slow
  • doing so would require quite a bit more of calculation, and definitely more work on the UI
  • on top of that, it would make sense to allow players to, if they want, do other things while loading their bike, like discussing with characters…
  • …but not loading cargo in your bike, because it’s not available to charge when you load it, and vice-versa

And that’s how, from a very simple, basic feature, I ended up with something way bigger, but also slightly complex to implement. That’s the scope creep part.

But then, after implementing it, I ended up with a ton of bugs. And when I solved one, others were popping-up. Until then, I hadn’t encountered such a situation. There were bugs, but quite easily fixed and contained. Here, I don’t seem to see the end of it.

When I looked at it with a bit more distance, I realized that I hadn’t though this trough. I have used a Resource for my Service class, that I extended with a BikeCharger class. All this should indeed be a Node.

To be honest, I’m still fumbling around in Godot when it comes to decide what I should do as Resource and what I should do as Node. It’s partially caused by the fact that my game is mostly UI so I don’t have the usual 2D / 3D Nodes you find in many games. Which means that as many of the components of my game are in fact data. Theoretically, the game could be a single Scene with Control nodes, and one big ass script to load / unload data from Resources. That would be hell to extend and debug, so I didn’t go this way.

Coming back to my BikeCharger, I used a Resource because I believed it would be mostly data. In fact, it is mostly functions, and worst, functions that rely on data coming from multiple entities. Using a Resource to host those functions makes it quite difficult to use, without any benefits. So I will need to change that so that my services, especially BikeCharger, are scenes to be loaded as child of the related locations.

On top of that mistake, I also started developing the functions while tired. And though they don’t imply massively complicated maths, there are a few specifics to get right. It ended up with way too complex formulas to calculate something that should be quite simple and with an approach that led made it way less flexible than it should.

I had to rework the function two or three times, and I am still not happy with it, possibly because the « architecture » around the functionality is wrong. There is a good chance I will redo the whole thing later on, but now that I have something sufficiently functional (for a prototype), I will leave it at that and move forward.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Aller en haut