4 Hugues Ross - Blog
Hugues Ross

12/31/18

2018 End of Year Wrap-up

Here we are, at the end of a new year. It's crazy how quick these years go by nowadays, but at least I'm still getting plenty done! Let's jump right over to some accomplishments:

Cloudy Climb

DFGame had its first field test this year, with a little platformer called Cloudy Climb. The game was very short and not great, but I was able to get things done without too much trouble. I'm in the mood to make another small game this year, but I haven't decided when. I'm focused on bigger stuff right now, so it'll probably happen much later in the year.

DFGame

On that note, let's look at DFGame. Since last year, DFGame has received dozens of improvements and 2 new modules. Despite the progress, I haven't made a new version since May. At this point, DFGame feels like it has made enough changes to consider a 2.0 version release. For the sake of making it a good one, I want to polish a little longer.

Halberd

This year also marked a return to my longest-running project: The Halberd RPG engine! This attempt is shaping up better than the previous ones, so hopefully things will continue to go smoothly next year. I'm not ready for a source release just yet, but it'll probably happen within the first 6 months of 2019.

...What about Singularity?

I've been awfully quiet about other projects for a while, and Singularity hasn't seen much attention since the release back in January. I've grown quite a bit as a software dev since then, and I want to make a cleaner and more polished release. I've scheduled an v0.4 release for next June, though obviously that date isn't a guarantee. I'll be focusing on bugfixes and polish this time around, since most of the important big features are already working.

A Little More

I didn't just spend all of 2018 programming (though I'll admit that was most of it). I also made some art! Following up on last year's attempts to learn pixel art, I kept practicing and improving. I'm not a great artist, but I'm miles ahead of where I began at this point. I can't wait to see what the future brings in this regard, who knows how my games will look in a few years!

On that note, I drew a few more things to cap off the year:
I'm also planning to look into a few other styles of art, such as digital painting. I think expanding my view of art will help me grow my style in general, so there may be more than pixel art around here a year from now...

Next Year

Besides the obvious, I have a few extra plans for 2019. I'd like to take dflib and fold it into the dfgame ecosystem, probably as its own set of high-level modules. This will not only give me an excuse to update and fix up dflib, but it'll also let any of my existing dflib projects to pick up any dfgame features they want. Most won't be useful, but there are a few interesting possibilities like audio notifications.

I also have another little something that might happen with dfgame later. We'll see about that...

12/25/18

Halberd: That's my property!

To anyone reading this on the same day that I post, Merry Christmas! Here's a little present: This year's final Halberd-related blog post.

Of my current priorities on Halberd, one of the biggest is building and integrating a property grid. I think this is a very interesting endeavor, and hopefully you'll see it the same way!

So what's a Property Grid?

When I spoke to some (programmer) friends about this, I was surprised to find out that some of them didn't initially know what a property grid was. So, let's start with definitions.

As the name implies, a property grid is a ui widget that lets the user inspect and edit the properties of an object. It usually amounts to a list of named fields, and you can find one in just about any game engine. Here are a few examples:

UE4's 'details panel' is a form of property grid
As expected, Unity's inspector panel is another good example
The ActiPro Windows UI framework also features a property grid
The GTK UI builder, Glade, also features something in this vein

If you're a game developer, you've probably figured out by now that property grids are a really important game development tool. This is even more true in RPGs, due to the large amounts of 'database' assets which lend themselves well to this type of UI pattern.

Digging deeper: How does a property grid work?

Like any programming problem, there are many ways to implement property grid functionality. However, I'd put most methods into one of 3 groups: Inspected, Declared, and Fixed. These are just personal categories, not proper terms, but I think they showcase some real differences.

An Inspected property grid assembles itself by looking at real game data and converting it to ui. This is typically done through Reflection, either by looking at data in a scripting layer or with a language that natively supports this, such as C#. For languages that can't do this out of the box, a dynamic class/property system can be added on top of the normal code. Examples of such systems can be found in Unreal Engine 4 and the GObject framework.

A Declared property grid is also dynamic. However, instead of inspecting objects at runtime it queries their information from a predefined source, such as a schema or similar descriptive document. Then, it sends data back and forth via Serialization instead of reflection. The result is less flexible, but it's also simpler and the underlying game code may be more performant since dynamic properties aren't necessary.

Finally, there is the Fixed property grid. I call this a property grid, but that may be an overstatement--this grid is essentially just a hard-coded bit of ui for interfacing with an object. By its nature, it's quite simple and totally static. Of course, it's also difficult to maintain and requires constant updates as the underlying data changes.

Depending on your use-case, any of the above can be valid approaches. The fixed solution may seem bad, but sometimes it's the best option: You don't need a powerful and complex solution just to edit a couple of fields.

What have I got?

At the moment, Halberd is stuck with the fixed style. I went for this solution early on to avoid getting bogged down while developing my proof-of-concept, but the scaling problems of this approach are starting to appear.

The general process of adding a new property to an object right now is:
  1. Add the property
  2. Add serialization for saving/loading
  3. Add simple getters/setters for editing
  4. Add the property to a Vapi file for interop access
  5. Add the property's editing widget to the ui file
  6. Add the widget code to the editor's vala class, including the signals for changing the property
That's a lot of steps for one property. With a simple property grid, I could skip steps 3-6 entirely and greatly streamline my development process.

A new property grid

With all that in mind, I decided to try out something better. Since most of my code is C, the declared style is necessary. But how to prepare the meta-information about the properties? In my case, it was actually rather simple. Since I already serialize my data to XML, I decided to go with the obvious option: XSD.

For the uninitiated, XSD is an XML-based schema standard for describing other XML files. While intended for databases, with a few additions the result can work quite well for defining a property grid!

The result looks like this:
You might recognize this as DFGame's editor demo which I completed last year. The controls were hard-coded since it was just a viewport showcase at the time, but now the editable parts are totally data-driven!

The schema that the editor is based on is a bit wordy, but pretty straightforward:
    1 <xs:schema
    2     xmlns:df="/org/df458/dfgame"
    3     xmlns:xs="http://www.w3.org/2001/XMLSchema"
    4     elementFormDefault="qualified">
    5     <!-- Types -->
    6     <xs:simpleType name="fill_type">
    7         <xs:restriction base="xs:string">
    8             <xs:enumeration value="true" df:displayName="Filled"/>
    9             <xs:enumeration value="false" df:displayName="Wireframe"/>
   10         </xs:restriction>
   11     </xs:simpleType>
   12     <xs:simpleType name="size_type">
   13         <xs:restriction base="xs:float">
   14             <xs:minInclusive value="0"/>
   15             <xs:totalDigits value="6"/>
   16         </xs:restriction>
   17         <xs:annotation>
   18             <xs:documentation>A decimal value above 0</xs:documentation>
   19         </xs:annotation>
   20     </xs:simpleType>
   21     <xs:simpleType name="degree_type">
   22         <xs:restriction base="xs:float">
   23             <xs:minInclusive value="0"/>
   24             <xs:maxExclusive value="360"/>
   25         </xs:restriction>
   26         <xs:annotation>
   27             <xs:documentation>An angle in degrees</xs:documentation>
   28         </xs:annotation>
   29     </xs:simpleType>
   30 
   31     <!-- Triangle struct -->
   32     <xs:complexType name="triangle">
   33         <xs:attribute name="size" type="size_type">
   34             <xs:annotation>
   35                 <xs:documentation>The size of the triangle</xs:documentation>
   36             </xs:annotation>
   37         </xs:attribute>
   38         <xs:attribute name="angle" type="degree_type">
   39             <xs:annotation>
   40                 <xs:documentation>The angle of rotation</xs:documentation>
   41             </xs:annotation>
   42         </xs:attribute>
   43         <xs:attribute name="color" type="df:color4">
   44             <xs:annotation>
   45                 <xs:documentation>The color of the triangle</xs:documentation>
   46             </xs:annotation>
   47         </xs:attribute>
   48         <xs:attribute name="is_filled" type="fill_type" df:displayName="Style">
   49             <xs:annotation>
   50                 <xs:documentation>Toggles filled/wireframe rendering</xs:documentation>
   51             </xs:annotation>
   52         </xs:attribute>
   53     </xs:complexType>
   54 </xs:schema>
One way to reduce the workload even further would be to tie this into a code generation system, but that strikes me as overkill for the time being...

What now?

I've been working on this feature for a few weeks now, but I finally merged it into DFGame's master branch yesterday. The next step will be to try and integrate it into Halberd, I'm sure there'll be more to do but I think this feature is a good investment for future work! Once the property grid's in place, the work will hopefully start moving a bit quicker.

12/4/18

Art, Take 2

Exactly one year ago, I posted some images showing my progress practicing pixel art. I've continued practicing since then, and I think the results are quite solid!

Let's get started with a quick review of the past year. Unlike last year's mostly unstructured practice, I've tried to aim for a few weaknesses in my art fundamentals and improve them. The main core skills I focused on were light and perspective, though I've been tentatively playing with anatomy and proportion lately. I also joined a couple of pixel art communities, which have been a very helpful source of critique.


With the stage set, let's make a few direct comparisons to last year:

Trees


Rocks


Tilesets

Click the image for a full-size version

As you can see, I've made some pretty good progress! Of course, I did quite a bit more than this: Here's an album with some of this year's finished work.

If you're interested in seeing more as I continue practicing, I occasionally post work on Twitter and Pixeljoint.

11/25/18

Halberd: What's a roadmap?

Since my last update back in October, I haven't touched Halberd's roadmap. The reason for this is simple: With a new work strategy, I wasn't really sure how I wanted to show and track progress. In the end, I quietly settled on using regular issues on the project's GitLab repo.

For the time being, I'm still keeping the code private. I'll make it public long before the first proper release, but I want a couple more months to get things cleaned up a little before then.

Now that all that's figured out, I think it's time to get back to posting. I have a couple of posts that I'd like to make before the end of the year, so things should soon liven up a little around here!

10/16/18

Halberd Studio: No Sleeping, Just Scheming

I didn't sleep last night. The cause had nothing to do with my projects, but I ended up thinking about Halberd for a few hours. The more I thought, the more I became certain: Something has to change.

If you read my roundup for September, you'll know that I actually made some decent progress. Despite that, I still have a lot of doubts. After last night, I re-read all of my recent posts and decided that a new strategy was in order.

There's a wall of text about my motivations between you and this strategy. Click here if you'd prefer to skip it.

...But Why?

Obviously, this is coming off as indecisive. Still, I came to an interesting reason to change things up. I wrote about a similar feeling in August. At the time, I wasn't happy with the game. I looked back at my first post on it, decided that my reasoning was still correct, and kept going.

As a refresher, here are the reasons I had for starting:
  1. Making a game is a way to validate that the tool works, by forcing me to engage with all of its features. If there are any bugs or missing parts, I can fix them before release. It also lets me see which features need the most love and which are 'good enough' as-is.
  2. Having games made in an engine is also good for proving its capabilities. Anyone can make game development tools, but if no good games have ever been made with them then they'll be a tough sell for other devs.
  3. Finally, games can also serve as a useful reference for anyone who wants to try Halberd out. I don't think anyone will at this point in development, but when people do start using it they'll have something to help them.
  4. Additionally, the large scope of Halberd makes it a real marathon of a project. I need to break it up with smaller game projects if I want to keep my sanity! Not all of my 'filler' will be made with Halberd, but it's still a convenient excuse to give the engine a workout.
I still think these points are sound. However, my current project isn't actually the best way to address them. Let's go down the list again:
  1. The first reason is spot-on. Making a game is a pretty solid validation process. Making a demo of the engine's features could also work for this.
  2. This point disqualifies a demo as a complete solution, but there's an important word in there: Good. A bad game won't convince anyone to use an engine, it may even turn them away.
  3. See point 1.
  4. Here's the other problem: I replaced one drawn-out process with a drawn-out process and a diversion that I didn't personally enjoy. Demos won't fix that, but I have some other plans.
'Henry' is not a good game. It won't be a good game, and I'd even go as far as to say that it can't be one. As I work on this project, I can feel the time I'm wasting. That has an impact on my productivity, and it's exacerbated by the fact that I was never really that interested in it. I knew that my options would be limited, so I tried to go as simple as possible. I also used the game to try a new post format. That's pretty much all I have to say about it, because there was nothing else to hold my attention.

Despite my lack of interest, I still want to make RPGs in general. I have a few 'real' ideas on the backburner, but Halberd just isn't ready for them. The engine is technically in an 'MVP' state because you can make a game with it, but it's not viable for anything serious yet.

The Plan

That last section went long, but it felt good to get it out. Next, let's talk solutions. Back in August again, I listed some wants. After re-reading them, I can confidently say that they mostly hinge on being more patient and giving Halberd the time it needs. Working solely on Halberd brings up the issue of fatigue, but nothing is stopping me from keeping my current 'alternating weeks' strategy. Let's run with that concept.

Halberd is a huge project, and there are a lot of very different tasks needed for its success. I've split them into roughly four different categories:
  • Foundations
  • Progress
  • Polish
  • Content

Foundations

Halberd rests on top of DFGame, and I've regularly had to dive in to fix issues and add features for the engine's sake. One thing that bothers me is that I never have enough time to polish all of this internal code. With the pressure of getting a feature to work so that I can finish whatever I started on Halberd, it's hard to spend extra time on code clarity, tests, refactoring, and so on.

Long-term, these things are necessary for a healthy engine.

Progress

The 'critical path' to making my dream games, if you will. This category represents the features needed to make a powerful and flexible engine, things like custom equations, items, cutscene and dialogue tools, etc.

Polish

Just getting Halberd to work well is enough for me, but to really sell (figuratively) the engine to the public I need to make sure that it also feels good to use. That means taking time to fix minor gripes, improve workflows, write help docs, and work on unifying the engine's look and 'brand'.

Content

I've never brought it up, but I think a big factor in novice-oriented engines is the quality and variety of the assets they pack in. I'm convinced that this is partly why so many people are attracted to RPGMaker, and also why some people look down on games made with it. Assets matter in the market that I'm planning to enter, and they're also a good source of practice.

If I spend enough time building my art and audio skills before I start my RPGs, I can make them truly live up to my expectations.

Conclusion

With some diverse long-term tasks prepared, the remaining question is how to divvy them up. Conveniently, I found out last month that I can get a couple solid features done per week. For now, I'm going to try focusing on each of these categories for one week every month. I'll keep this up until the end of the year, then I'll re-evaluate if I'm still not happy.

Looking further ahead, I'm about 5 1/2 months away from the first anniversary of Halberd's announcement. I don't think it'll be ready for release at that point, but I'd like to at least have some convincing demo videos by then! I'll also make the code public some time in the next few months, so that I can point people there for more detailed progress.