4 Hugues Ross - Blog: 2020
Hugues Ross

12/29/20

Moving Day

Hi everyone, just a quick blog post to give advance notice.

On January 1st, this blog (and the associated site) will be completely replaced! I've rebuilt the site on a new hosting platform, and I'll be throwing the switch to turn it on. There might be some brief confusion after that, and everything will look very different, but hopefully it will be a quick and painless process.

In the meantime, here's a little heads-up:

  • The domain hasn't changed, but 'blog.huguesross.net' will become 'huguesross.net/blog'. I might try to set up a redirect if I don't forget, but bear that in mind.
  • RSS is being discontinued, but Atom will still be supported. The new atom feed will be at 'huguesross.net/feed.xml' once the transition is complete. Some of the other forms of content on the site will get their own feeds as well, so be sure to check the new site for those.
  • Aside from the subdomain, blog post permalinks should be the same as before. I won't be importing most of this blog's content initially though, please contact me if you want something back.
  • Most of the other pages on this site will change URLs, so if you had them bookmarked you'll have to go back and change them. Sorry!
  • This blog will still be up at 'df458.blogspot.com'. I might delete it eventually, but there's no ETA and it won't happen for at least several months.

12/20/20

Royale Finale

We're finally here at the end of the experiment. Nearly 3 months after the original announcement, I've tried 9 different open-source engines and frameworks and written my thoughts on each. Now it's time to step back, do some comparisons on the group, and work out what I want to do going forward.

First, just to jog your memory I've assembled the complete list of posts:

  1. DFGame
  2. Godot
  3. HaxeFlixel 
  4. LÖVE
  5. Monogame
  6. PyGame (immediately and unceremoniously disqualified)
  7. Raylib
  8. SFML
  9. Heaps.io

 

The Predictions

In my first post, I talked a little about each lap and what I was expecting out of them (except Heaps.io, which was added to the list later on). Let's look back and see how they bore out.
 
DFGame fared about how I expected it to. This is no surprise, it's the one item on this list that I made myself so naturally it wouldn't really deviate from my expectations. Still, of note is the 'wordiness' that I mentioned in my write-up. DFGame's lap is the largest codebase by far, with the other (completed) games  ranging from ~400-600LoC, 25-50% smaller. It's not entirely C's fault either--raylib's demo is only 547LoC. If I was planning to keep it, I think a high-level API would be a must to remain agile.

Godot was probably the biggest upset of the bunch. I had only really heard praise for the engine, and several people I know and trust recommended it... but in the end I found it kinda awful.
On thing I feel obliged to note is that I've spoken to some Godot users after writing this article--for the most part, they don't really seem bothered by the issues I brought up. As a professional Tools Programmer with a (mild) UX background, it could be that I'm extra-sensitive to these sorts of issues. If you're unsure about Godot after reading my post, consider giving it a whirl to decide for yourself. It's free, so you have only time to lose.

HaxeFlixel is an odd one, because despite a very positive review I've since soured on it a little. I think as the first "good" lap, I overreacted to it a bit. The iteration times are really annoying, particularly paired with the logo that pops up at every launch, and there's something to be said for being the only engine on the list with physics issues that aren't clearly traceable to my code. Still, it's not a bad engine and it had easily the best documentation of the lot!
I think the other projects could improve a lot by copying HaxeFlixel's example site.

LÖVE is pretty clearly the "winner" of the bunch, hands-down. I was hoping that it would be good, since I remembered liking it, and it was. I have very few negative things that I could say, so here's a link to a post from 2012 where you can envision current me shouting "NO! YOU FOOL!" over an over.

Monogame was another big surprise for me. I was expecting to like it a lot more, but I bounced off of it pretty hard. For the record, it does seem to be a decent framework. Rather, I think it doesn't work well in the conditions I tested and doesn't really offer what I'm looking for. More on that in a later section.

Raylib was not what I expected at all. I was expecting something a little like DFGame (but, y'know, better), instead it was much closer to LÖVE. In the end, I think it mainly suffered from the language it was based on and the lack of a proper API. It could be interesting to check out the language bindings it has sometime in the future...

SFML was kind of a filler option when I put it on the list. I didn't remember it being all that great (something that you can see from the fact that I didn't bother using it when I was raving about C++, despite having tried it), and it turned out to not be all that great. I think there are better low-level options and better high-level options out there, so I don't plan to ever revisit this one.


Overall, there were a lot of surprises. I think this speaks to the value of trying out software, rather than relying on just word-of-mouth.


A Note on Language

One thing that I noticed during this whole process was that the language being used does matter quite a bit. On average, it seems like the full-blown OO languages under-performed a lot in this 6-day test. This doesn't surprise me much, since building up those kinds of structures adds overhead to the development process. I'm curious to find out how true the reverse is... will a larger script-based project break over the weight of its complexity? Time will tell, but I think this is avoidable with good design.


Another big deciding factor was compile times. Stopping to rebuild files really becomes annoying when trying to tweak gameplay, and I think the noticeably-slow compile times of Haxe make it a lot less suitable for games than it first seemed.

 

Eliminations

One last thing to look at before we wrap up is what options will do what I really want. Some time after starting this project, I hit upon a couple of requirements that I really wanted out of an engine/framework:
  1. Easy multiplatform support -- One thing that's held me back a bit with DFGame is the pain of porting to other platforms (like Windows. This is a real issue). It means that my audience is very restricted, and it's hard to stay motivated about a project no-one will play.
  2. Ease of Design/Iteration -- I don't think game-building tech needs a graphical editor, but it does need a way to quickly tweak assets and values with an 'in-game' view. That can be through hot-reloading or tools integration, but I think it's legitimately important for getting work done quickly.

Starting with the first requirement, we can eliminate everything based in C/C++. That leaves Godot, HaxeFlixel, LÖVE, Monogame, and Heaps.io

The second requirement is a lot more wishy-washy, since it's about how easily some things can be done. As a graphical engine, Godot definitely makes it in. Due to how it handles assets, Monogame definitely doesn't. The others are a little more up in the air... so for now, I'll leave them in. That leaves me with a final list of 4:

  • Godot
  • HaxeFlixel
  • LÖVE
  • Heaps.io

Setting aside preferences for a moment, I think these 4 engines are the most suitable for my requirements. Unless someone can find a way to bring Monogame back in or I find new engines to try, these are the engines most likely to show up on this blog again.


Coming Up...

At this point, I think it's clear that LÖVE is the engine that jives with me the most. Before I launch into anything big though, I have another project that needs some attention: this blog!

I have the next couple of weeks off, and my hope is to finally sit down and set up a unified site and blog on a new host. It's going to start out very simple, but hopefully having everything working off the same base will make updates easier later on. Once that's done, I think I'll try to spend at least a few months experimenting, doing game jams, etc. before I start on any larger projects. I think it's important to take time getting to know a new engine, and jumping directly into the deep end won't get good results.

12/13/20

Royale Week 9: Heaps.io

I didn't finish this week's lap, and frankly I don't have the motivation to do it. I'm in a bit of a weird position--I feel like I haven't delved deep enough to really give this engine a fair shake, and yet what I have seen so far doesn't inspire the confidence I need to keep going... all of this is to say that I don't like Heaps.io, but I'm not confident enough to say that it's entirely the engine's fault.

Regardless, let's talk about that experience a little.


My initial impression of Heaps.io was actually pretty good. The basic introductory text seemed to imply a pretty sane modern structure based on a scene graph, and the setup seemed simple enough. I didn't really like the focus on specific applications, but I figured that was mostly just to help out beginners.


My problems began immediately after that. The next major section of the documentation goes over 2D rendering, and shows a simple example of resource loading (here, scroll down to the Image section for that). What it doesn't mention is that you need to initialize a resource loader. Indeed, it doesn't mention those loaders at all! The first reference I found was a 1-line comment in a code sample several pages later.

If you don't realize this because you're not psychic, you'll get this helpful exception when you try that code:

"Resource loader not initialized: call to hxd.Res.initXXX() required"

...ok, so clearly a loader needs to be initialized, and the functions are in the hxd.Res namespace. See? I'm not being sarcastic, it is helpful!

 

Well, except that if you check the API docs you'll notice that there are no init functions listed. I'm not really sure why that is, but it's a problem. I also checked a good half-dozen of the official samples and conveniently, none of them had any sort of resource loader initialization either. Nice. The time I spent setting up loading code and searching the API and samples is a waste, because what I really had to do was:

  1. Skip from the second section of the documentation (H2D) to the fourth section (HXD). And as an aside, what does HXD even stand for?????
  2. Go into "Resource Management"
  3. ...and read that instead of the example that was given in the first place.

This is enough to progress, but there's no simple way to work out what resource loaders even exist. 'Embed' is used as an example, but if you look at the API page for it... Weird, there's nothing at all. And by the way, don't bother checking hxd.res.Loader. I know it seems like the obvious next place to look, but it contains nothing relevant to this search. To this day, I still don't know if there's a list of resource loaders out there.


After all that hassle, we finally have textures onscreen. At this point, I was pretty miffed but not nearly ready to throw in the towel. The apparent lack of vector math (more on that later) also didn't deter me, since I saw that collision detection code was available. Most of the math I've been doing in these demos has been bouncing a ball off of rectangles, so a basic collision API would cover that pretty well.

I'm going to spoil the punchline now and tell you that it doesn't cover that at all. You might think it would after looking at this sample, where they use built-in API calls to get the normals of a rotating collision object from a point in space. Amazingly, this function is entirely exclusive to the capsule collider class, for...some reason? Beats me. All I really need is the closest point from a circle-to-rectangle collision check though, so let's see what we get from that...oh. We get a bool, and nothing else.

 

At this point, I was starting to question how Heaps.io games handle physics, seeing as the built-in collision detection code doesn't seem to give anything that's needed for collision resolution. On a whim, I decided to check the hxd.col.Point class. It has all the vector math you could want! I should've been happy, but the only thought racing through my head was: "Wait, if this exists then why do all the scene graph nodes exclusively take raw floats???????"


And then, I stopped. Throughout these past 2 1/2 months, I've seen and dealt with a lot of weird and arbitrary API design, broken or incomplete docs, and a handful of runtime bugs. I've pushed through it all to bring you my opinions, but now? Now, I'm tired of this. Heaps.io put the last dagger in the back of my desire to try new game engines. I just don't have it in me to keep wondering about these things, and I think it's time to settle down and change gears.

Thankfully, that's already what's next on the agenda! We have one more post to round up all of the past engines and frameworks, and to declare a "winner" that I'll be playing with further.

12/6/20

Royale Week 8: SFML

This was kind of a weird entry, and the next one will be as well... I timed the demo out to 6 days as usual, but had to break it up over two weeks--let's just say I've been working on 2 AAA games simultaneously and one of them is shipping SOON™.

This may have hurt the demo a bit, but I don't think extra time would change my conclusions here.


SFML is a framework in a very awkward position, in that it seems to advertise itself both as one of those lower-level 'OpenGL/Vulkan access' libraries and also a higher-level 2D multimedia library. Since the goal of this little experiment is not to reinvent the wheel, I can't speak to the former use-case... but I'm not really impressed with the latter.


One common issue, perhaps the main issue I have with SFML, is the problem of trying too hard with its features and making the API worse in the process. Consider these examples:

For each 'instance' of a texture you want to draw to a window, you need to make a corresponding sf::Sprite object. You have to set transforms on the sprite, draw it yourself, manage the lifetimes of both objects, etc. It offers no gameplay functionality like the Sprite class in HaxeFlixel, so you can't use it to replace your objects.

The result is that any game object needs to copy its transforms over to this extra object on a regular basis, and you now have two objects to manage instead of one. Moreover, there's no simple 'just draw the damn texture' function. You can imagine a world where the sprite class never existed, and in that world it would be easier to draw textures onscreen...


SFML offers vector classes that you must use to represent positions. That's pretty standard... but what it doesn't offer is any of the corresponding vector math. There's no dot product, no cross product, and not even the humble length function. These vector math operations are the bread and butter of gameplay programming, but SFML expects you to provide them yourself. You now have a choice: write your own helper functions (which can't extend the API nicely, this ain't C#), or adopt a math library and convert types every time you make an SFML call.

Curiously, this situation is described in a very deliberate and matter-of-fact fashion in the docs. This proves that it wasn't an oversight, and it's almost as if the devs consider this missing critically-important functionality to be a positive.

In both instances the SFML devs thought of a useful feature, created the feature, but stopped short of the part that makes it useful. The result is baggage that the programmer must carry, but benefits little from.

 

Funny enough, this segues nicely into the next pain-point: C++ itself. I mostly swore off of C++ back in college, and have only used it in brief spurts since. I've grown a lot as a person since then, and I was interested to see how the language felt now... but no, it still sucks. Somehow, young and foolish me was completely right.

It has nothing to do with being lower-level, I've used C in two separate entries so far and been happy as a clam. It's not really about being higher-level either, I've used C#, Lua, and Haxe in this experiment as well. But something about C++ makes every new feature feel like an overdesigned mess that, get this, looks like the start of a useful feature but stops short of being useful. It makes me wonder how much of C++'s dominance in large-scale gamedev comes from inertia.


Well, I think that's enough ranting for one day. I'm tired, and the less time I spend thinking about this C++ and SFML tag-team the better.

Oh, and uh... the API docs are ok but they could really use a search bar.

11/23/20

Royale Week 7: Raylib

Ok, I'll admit it: I'm starting to get a little tired of Breakout. That won't stop me though, we're rapidly approaching the end of this comparison and I intend to see it through to the end!

Here's the customary gameplay video:


This one's pretty similar to some of the earlier options, but I mixed some of the paddle velocity when bouncing the ball and I think the 'mixed' version is an improvement. It gives the player a little more control on the ball, while still providing a more precise option.


I wasn't really sure what to expect from Raylib.It's a framework that I was aware of, but had never really heard of anyone using... I was very interested in this though, since I have my own little C framework (DFGame, from week 1) and I wanted to see how some of the problems I ran into were addressed. Being an old low-level language, C has a lot of limitations to think about in game development. I had to come up with my own solutions in DFGame, but many of them weren't ideal and I wanted to see how a more mature framework handled them.


Now that I've used Raylib for a bit, I have a pretty good answer: The framework seems to take a lot of cues from higher-level options like Monogame (but without the content pipeline), which relieves some of the wordiness with a simplified API. However, most of the other problems were 'solved' by being ignored outright.

The most egregious example of the bunch is asset paths. C doesn't offer a built-in way of finding the executable's location, so you have to use OS-specific system calls to find it instead. This is one of the factors locking DFGame to Linux, and it's one of the primary things I want to avoid in any new engine/framework. Raylib answers this problem by being completely unaware of it, and naively using the working directory to load assets. If you launch your game from anywhere it didn't expect, it will fail to locate your assets and crash.

This disqualifies Raylib for the purposes of the exercise, but I still wanted to play around with it. Let's look at the rest.

 

Now, you probably think you know where I'm going next: "He's going to moan about API documentation for a few paragraphs" You are wrong, of course, because Raylib doesn't really have any sort of formal API docs. It has this "cheatsheet" which covers only a subset of the API, and to my knowledge there's nothing more... not really much to say there.


Instead, talk about how Raylib feels to use. I think this is where Raylib shines, actually. Working in C made me feel at home like with DFGame, but since the API is much higher-level it felt a lot better to use. Honestly, I think if the dev can fix the lacking areas and put a good API doc in place Raylib could be a much more competitive option.

11/9/20

Royale Week 6: Pygame

I have not heard the name Pygame in some time. It just had a big update last month, so now's the time to see how it has shaped up over the years!

source ( GIPHY)

Royale Week 5: Monogame

With this post, we are officially past the halfway point of this series! There's a good chance we'll wrap this up at the end of the month, and if not we'll definitely finish before the end of the year.

 

But enough about that, let's take a look at this week's demo:


Overall, this demo is in-line with DFGame and HaxeFlixel. In the interest of transparency though, I should mention that I had a few days off last week and had much more time to work on this than usual... without that, the demo would probably have a lot less. In general, I'd say that Monogame is one of those frameworks that requires a bit of scaffolding to work in quickly. Since Monogame is C#, extending this sort of API is still pretty reasonable though. (As an aside, I really wish extension methods were a thing in more programming languages)


Setting that aside for a moment, let's talk about what I liked first. Obviously, as someone who works in C# professionally it's a pretty comfortable environment to work in. The compile times are also pretty good, although they still pale in comparison to raw C. To balance that out, I don't need to worry about defining code files in my build config or managing #include directives.

Like most of the tech we've reviewed so far, Monogame doesn't try to enforce a particular engine structure on the user. I always appreciate that, and in terms of complexity the framework seems to sit at a nice medium spot between DFGame and LÖVE.


...aaaand, that's the stuff I liked. I'm going to be honest, I was somewhat disappointed by Monogame. I have a number of friends and coworkers who use it, so I went in with pretty high expectations. However, I was less than thrilled by some of the design decisions.

Let's start with the big complaint: I really hate the Monogame Content Pipeline. To cater to larger games, Monogame compiles asset files into an intermediary binary format. This is great when you're publishing a game commercially, and terrible for everyone else! Every time you make a new asset, you have to pop open a special tool and 'import' your asset into the project. I haven't tested, but I suspect this also makes any sort of 'hot reload' feature infeasible. Regardless, at the end of the day it only serves to slow down the development process without bringing any real benefits until the game is ready to ship.

 

Now that you've marked down "Feature that slows down iteration" on your bingo card, let's move on the the free space: Griping about API documentation.

At a glance, Monogame's docs look fine. There's a search bar to filter through classes, and plenty of details. Unfortunately, there's one really serious issue: The sidebar listing class members doesn't scroll. Like, at all. If there are more results than your screen can display, you cannot see them. This is actually worse than not having such a bar, because it gives no indication that the results are trimmed. It's useless in the best case, misleading in the worst case, and you still have to Ctrl+F for class members.


I also have some complaints about the design of the API itself. I'm a firm believer that UX applies not only to User Interfaces, but to Programmer Interfaces (literally, APIs) as well. Monogame makes a good case for this, because I think it has pretty bad UX.

The SpriteBatch class, which handles most of the drawing functions, makes for a good example:

  • When drawing anything with the SpriteBatch, you have options to position, rotate, and scale the element you draw by passing vectors / angles. But if you want to do that to everything you draw, you need to provide SpriteBatch with a 4x4 transformation matrix instead.
  • Conversely, you can't use a transformation matrix with individual elements. You must pass in the individual transforms.
  • You can draw text, and you can 'measure' text for placement/alignment purposes... but you can't draw aligned text without writing the alignment code yourself.
  • You can recolor any element you draw. In fact, you are required to pass a color in every draw call. Yes, it will almost always be white. No, you still can't skip it.

 

While working with Monogame, I felt like I was spending most of my time doing busywork and adding things that should've been redundant instead of getting work done. I'm sure it can be a good framework with enough helper libraries, but it really feels like the API designers don't respect the user's time at all. I'm trying make games here, if I wanted to write my own framework I would rebuild DFGame in OpenTK. It's still leagues better than Godot tho.

11/1/20

Royale Week 4: LÖVE

I really love LÖVE. This past week has been a blast, and despite skipping a day (I spent Saturday trying to make some music, but alas I still absolutely suck at music compostion) I've managed to put together the most polished and stable demo so far:


Pretty much all of the features the other demos have were completed in the first two days, so I took it easy for the remainder and tried to add some extra polish and refinement to what was already there.

 

I think a big part of what makes LÖVE so efficient for me to work in is that it's a framework like DFGame. This lets the programmer go as simple or complex with the architecture as needed, which can really speed up the production of simple games. Unlike DFGame however, this framework is based on a high-level language with a greatly simplified API. To top it off, the fact that it's based on Lua means the user can launch builds instantly. In short, it has most of the upsides of HaxeFlixel, with none of the downsides. Honestly, this test makes me want to kick old me in the shins for casually dropping it ~9 years ago. It's great!


But of course, we can't just be positive. LÖVE has one curious flaw: There's no vector math in the API. Seriously! Since Lua supports multiple return values, the devs have taken to just passing around pairs of floats. That's not such a big deal, but having to write your own math boilerplate to do basic vector manipulation is kind of a chore. I have absolutely no idea why LÖVE doesn't provide these functions, especially since the core engine almost certainly has them somewhere...

Thankfully, this is the sort of problem that can be solved with a helper library. Overall, I think LÖVE is handily "winning" this comparison so far.

10/18/20

Royale Week 3: HaxeFlixel

After last week's fiasco of an engine, I was a little worried going into something I hadn't tried before. Haxeflixel, however, was a breath of fresh air!



As you can see, the resulting demo is pretty close to what I made for DFGame. There are a few notable differences:

  1. I had never used HaxeFlixel or Haxe before
  2. I spent less time on this entry than the DFGame one
  3. At 395 lines, the resulting game has less than half the DFGame entry's linecount

This is the sort of result I was expecting to see from some of our contenders, and in general I quite enjoyed my time with HaxeFlixel. The engine offers most of the stuff I wanted out of the box, and the documentation is really well-designed. Just look at the HaxFlixel Snippets site for an example of what I'm talking about:

Each page has a minimal example (often just a single line of code!) showing the relevant call, API links, a real demo running in your web browser, and the full demo code acting as a more 'complete' example. It manages to frontload only the most relevant info while still offering enough depth to understand what you're doing.


Overall, I was impressed and I think HaxeFlixel is actually a quite good starting point for new gamedevs. There are a few negatives that make me unlikely to use it for big projects going forward though.

The first negative is the engine/language's compile times. A 'dirty' build (ie. no code modifications) of my 400-line game for linux takes ~13 seconds. A clean build takes 2 1/2 minutes building to an SSD on a 12-thread Ryzen CPU!!! For comparison, here are the build times for DFGame:

  • Dirty: too fast to perceive
  • Clean: 4 seconds

The Haxe codebase is nearly 40x slower to compile, and I can only imagine what a 5 or 6-digit linecount would do...

The other issue is a little less obvious, but worries me just as much. Part of what makes HaxeFlixel so quick to develop in is that many of the things you want are already handled in the engine. Want an object with a sprite? Make an FlxSprite and add it in! Want to give it physics? Just turn the physics on! Want to make it disappear when it runs out of health? Just call hurt() on it!

This is awesome for quick development, but it also restricts your visibility of what's really happening with your game objects. For instance, when I tried to make bricks move the ball started randomly teleporting, getting shoved out-of-bounds, etc. The changes I'd made on my end were so small, and the API was so 'foolproof', that there was no clear bug in my code. Something was going wrong in the backend, and I didn't have any good debugging options. This always worries me when engines try to hide the details, simplicity can bite back hard when it fails.


With that said, HaxeFlixel seems like it would make for a good prototyping tool. I'll probably keep it around, and I would recommend it for small games and game jams.

10/11/20

Royale Week 2: Godot

Given how many people recommended Godot when I started gathering my list, I was actually pretty excited to try it out. I didn't think it would be as good as claimed, but I figured it would make it into my top 3 and get some use as a prototyping tool, at the very least.


...How wrong I was. As it turns out, Godot is a hot mess.

I'm not bothering with a video this time, there's nothing interesting to see. I got the very basics in place (bouncing a ball around, breaking bricks) and immediately dropped the project, because I didn't want to use this engine any more than I had to. Instead of talking about the game itself, let's talk about why I hate Godot so much now.


First off, let's set the tone with a little anecdote. Here's my first interaction with Godot, step-by-step:

  1. Load an example project to see how everything works
  2. Open a scene and look around a little
  3. Open a script--wait, did that just replace my tab?
  4. Try to open the scene again. Nothing happens.
  5. Try to close the tab. The tab (and the script within) is still open, but the tab title changes to "[empty]"

If you use Godot, you already know what's happening. But if you don't, I'm sure you're about as mystified as I was when this happened. As it turns out, Godot's designers had a bright idea along the lines of:

"Hey, why don't we force users to open scripts on top of their scenes even though we have tabs?"

For some reason, in addition to 2D and 3D level-editing views they just added a script editing view instead of opening documents in a new tab like any normal piece of software. Just for good measure, double-clicking a script will change the view but double-clicking a scene won't change it back. Like many of Godot's failings, it's so obviously wrong that it almost feels like a deliberate joke.

 

I should also take a moment to point out that I'm a Linux user and casual FOSS advocate. I know that most open-source software isn't the pinnacle of UX, since I use it all the time. Even knowing this, Godot feels like it's on a totally different level somehow. Almost every interaction is slowed or complicated for no reason.


Here's another example: Since we've established that you can technically open multiple files in the same tab, how do you suppose you save them? As it turns out, Godot has 2 save shortcuts, Ctrl+S and Ctrl+Alt+S. Normally, Ctrl+S will save the content of your tab. However, it's bound to save scene so if you don't have a scene open under your script you have to press Ctrl+Alt+S for save script. That's right, they fucked up the most basic action of saving your files.

Of course, that's a bit of a moot point since there is autosave. Unfortunately, autosave always saves open files, even if they're not modified! This means that if you use an external editor, every time you launch the game your editor will detect a file change and prompt you to reload. Nice. The classic loop of "make change, run, go back and adjust" now has an extra step, courtesy of Godot! Oh, but don't worry. In addition to always re-autosaving your files, Godot will also ask for confirmation every time you try to close the editor. Yes, even when nothing is modified. And yes, it also autosaves when you do that, making the entire confirmation pointless.


But you know what? If that was the end of it, I might be able to grit my teeth and push on. So next let's talk about the API documentation. Surely, a team of programmers (because I refuse to believe that there are any "creatives" involved in this engine) would make good docs right?

So the first thing I noticed when I opened the Godot docs was that the API docs were nowhere to be seen. The sidebar is filled with tutorials, but to get to the real API you have to scroll to the very bottom of the list. Or hit Page Down twice. Yes, it's that far down. You could also use the search bar, of course. From my experience, unless you put in the exact name of a type you'll have to scroll deep into the results to reach the relevant API page. Depending on what you search, you might also get the internal engine API, because they put both APIs in the same space for some reason. They also put ads in their documentation, but since Godot itself is free I have trouble blaming them for that.


Ok, so the workflow is bad and the API is annoying to search. But maybe the level editor is good? I'm not going to beat around the bush this time, it's not. The biggest offender is the "Select Mode", which does a lot more than select. Select Mode is ostensibly for selecting objects in your scene, but clicking and dragging moves them. Did your mouse move slightly when you clicked? Your object is now 1px out of alignment, sucker! I hope you noticed before you started doing any real work.


I think that's enough bashing to get my point across, I could keep writing for hours (these past 6 days have given me an endless supply of material), but I think I'll just block this past week out of my memory and move on to the next entry.

10/4/20

Royale Week 1: DFGame

Hello again!

Though it felt like an instant, a week has already passed. I spent my evenings banging rocks together, and a spark emerged. Roll the tapes!

This is not the most riveting game of all time, so I tried to combine all of the game's features (and bugs) into a single segment instead of making you watch a full playthrough. If you're curious, you can check out the code here.


What I got done:

  • Basic breakout gameplay, knocking a ball around with a paddle
  • Multi-hit blocks, walls
  • Moving blocks
  • Velocity transfer from moving objects to the ball

I wanted to try a slightly different formula, so instead of bouncing the ball at different angles based on where it hit the paddle I made the paddle give some of its velocity to the ball. I think using paddle movement to 'aim' the ball is a neat idea, but it's a little odd in practice. I'm not sure if I'll keep the idea or try something else next time.

The game itself has a couple of physics bugs as well. Both of them are totally fixable, I know why they're happening. Unfortunately, I simply ran out of time at the end and didn't get a chance to resolve them.


To sum up my thoughts about DFGame after this: It's handy, but needs more time in the oven.

The main drawback of DFGame is that as a C API it's pretty wordy. There are ways to improve this, and most of them involve adding more 'shortcuts' for common stuff to the API. The final game was ~800LoC, which isn't bad, but I think I could cut a quarter of that just with helper functions and refactoring. Since DFGame is my project, that means that any future project using it will have to account for framework development time as well.

9/27/20

The Big FOSS Game Tech Battle Royale

Lately, I've been in the mood to get back into gamedev. It has been a while since I sat down and made a game for real, so this feels like an ideal moment to look at the landscape with fresh eyes. Over the last 5-10 years, a lot of open-source game engines and frameworks have popped up and grown up alongside the indie scene. I have a little framework of my own, but I want to find the tech that I'm most comfortable with.

To that end, I've got a fun exercise to try. I call it:

The Big FOSS Game Tech Battle Royale


The concept is quite simple: Every week, I'll spend 6 days trying out a new set of tech and building a little breakout clone. I'll write about my experience, then at the end I'll pick whatever I enjoyed the most for my future projects. Also, though it goes without saying--I'll also post the code and assets for each attempt.

I think breakout is a nice 'test game' because it's very simple on a mechanical level but incorporates a decent number of core game development concepts. The simple format is also ripe for expansion--which will be good for testing tech with a fast iteration speed.

 

I've picked out 8 'contestants' for this exercise.

  1. DFGame -- DFGame is a lightweight C framework that I've worked on from time to time... It's not terribly impressive, but works well and benefits a lot from being familiar territory.
  2. MonoGame -- I've used XNA to build games in the past, and I work in C# professionally as well. For that reason, I think this framework is absolutely worth trying.
  3. Godot -- Godot is an engine that I've heard a lot about, but never actually used. While I'm a little skeptical of the hype it's gathered, dismissing it offhand would be silly. This exercise will be a good opportunity to give it a fair shake.
  4. HaxeFlixel -- From my understanding, Haxe is the phoenix that rose from the corpse of Adobe Flash... I never really enjoyed Flash development proper, but I've never tried Flixel before and Haxe has been used several high-profile indie titles.
  5. LÖVE -- Good old LÖVE, I used this engine for a few months back when this blog first started. I discarded it for silly reasons back when I was first learning C++, but the engine is still going strong to this day and I want to give it a second look.
  6. SFML -- Another briefly-used piece of tech, I used SFML for exactly one school project. I have a couple of friends who recommended it while I was building this list, so here it is!
  7. Raylib -- I've never used this one, but at a glance it looks like "DFGame, if it was fleshed-out and actively supported". I don't know if it's any good, but it's clearly worth trying out if it can save me from reinventing the wheel.
  8. Pygame -- I'd forgotten about Pygame until I asked around and someone mentioned it. It seems a bit dated, but how it fares remains to be seen.


What a list! If I knock out one test a week, it should be enough to last me a couple of months. It should also give me plenty to write in the meantime as well. I'm also open to suggestions, if you know a little open-source gem feel free to suggest it in the comments.

8/30/20

I'm Back

This blog has been on hiatus for about a year... I considered making a post explaining why, but I get the impression that no-one reads this blog. This is mostly my fault, of course! I've never been one for branding and advertisement, so it stands to reason that this place would be pretty empty.

I'm thinking of continuing where I left off, and trying to get more eyes on my work. But first, let's talk about where I was and what I was up to.

 

The Blocky Elephant in the Room

If you have been following this blog, you can probably guess that Minetest was the source of my disappearance. As I became more familiar with the project, I got the impression that I would need to invest a lot of time into helping it along. As a result, instead of leaving it as a side thing I dropped my other projects and invested my time and effort into it.

I don't regret doing this, but I'm also not sure how productive it was. RPG16 got a lot of love from the community, something I'm quite proud of! On the other hand, attempts at game development were bogged down by annoyances and engine limitations. Looking at the engine itself, it became quickly apparent that a lot of important things were broken or missing. So, I dropped that project and started working on improving the engine, telling myself "It will take a while, but once the engine is good I'll be able to make something cool".

There were some problems with this line of thinking:

  1. There's a ton of work to be done, and not enough people doing it
  2. The pace of development is greatly slowed by the combination of strict standards and a small core team
  3. The standards can't be loosened because there's a fairly large community expecting backwards compatible and bug-free updates
  4. Joining the core team would effectively cut my own development time

This creates a cyclical problem, resolving the reasons that development is slow would slow development. Worse still, this was taking me even farther away from my original goal. Just resolving blockers was turning into a bit of a nightmare.

In the end, I decided to cut my losses and leave. I suspect that I could invest 5-10 years into Minetest work without seeing any "return", and I just can't justify that kind of thing. I don't hold anything against the developers and community though, and I sincerely hope they can prove me wrong. I'd like to come back to a better engine someday.

At the very least, my time in the Minetest community taught me one important thing: I have the skills to make work that appeals to others. What I'm really missing is visibility.


How About Art?

On a happier note, my art practice has been progressing very well! This year I've been able to accomplish one of my original dreams and branch into landscape art:

I'm still learning a lot, but seeing the strides I've made over time is very exciting. I intend to continue for the foreseeable future, with weekly art streams on Twitch and pieces posted on my Twitter. Follow me in either of these places if you'd like to see my work as I make it.

 

The New Plan

I think that mostly wraps up the last year or so. Now that I have more time to myself, I'd like to continue my old projects and revitalize this blog a little. One of the first things I plan to do is rebuild everything under a new blogging platform. The nature of what I make has shifted over time, and I need something that can better serve my needs.

In addition to programming projects, I'd like to be able to post art pieces, photos, development resources, etc. on this site to give people more reasons to visit it. And finally, I need to start sharing and advertising my work more. There's no point in rebuilding a site like this if there's no community to enjoy it.