4 Hugues Ross - Blog: 11/01/2020 - 12/01/2020
Hugues Ross

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.