4 Hugues Ross - Blog: 12/01/2018 - 01/01/2019
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.