4 Hugues Ross Writes a Devlog
Hugues Ross


Taking a break this week

Just a quick update to say that the next 'Getting Organized' post will be arriving next week. Some may choose to find this delay ironic, but in this case I've realized that the week is going to keep me too busy to make a proper post.


Getting Organized - 2 - Looking at Options

Last week, I wrote about my plan to try and help myself get organized. After that, I spent the week trying out tools and planning.

What's available?

The taskwarrior site has a tools page, where a number of tools and scripts are listed. There weren't many that looked useful, but I was able to find a handful of relevant tools and tried them out.


Doesn't work. It's a few years old, so I suppose that's to be expected.


Taskswamp is a python script that creates a tmux session with predefined taskwarrior filters. Basically, it lets you create a window with several tabs, each displaying different views of your tasks.

Some thoughts

  1. Taskswamp doesn't update its view without user intervention. This means that you have to press a button to refresh whenever the window is resized or your tasks change.
  2. It also fails to start up properly unless you open another tmux session first. I could use a script to do that automatically, but it's still a little bit of extra effort.
  3. Lastly, it puts the new session inside of Xterm. It doesn't offer a choice of terminals, or check environment variables for your default terminal. That's unfortunate, although I could probably live with it.


(note: text redacted)
Tasknc is an interactive curses-based client for taskwarrior. It theoretically supports all of the basic features of taskwarrior, such as creating, editing, and deleting tasks.

Some thoughts

  1. Tasknc doesn't seem to be actively developed. This is unfortunate, because it has a few bugs.
  2. Unlike Taskswamp, the view will automatically refresh when the window is resized. You still have to refresh it when your tasks change, but that's ok because it supports all the basic editing actions from within its UI.
  3. Deleting a task seems to make the application hang indefinitely. In addition, the add task command seems to display the wrong information. Both of these issues seem to have a workaround, but basic features being broken without extra configuration isn't a good sign going forward.


So taskwiki is actually pretty great! It acts as an extension to the 'vimwiki' vim plugin. Basically, vimwiki lets you make...wait for it...wikis in vim. Taskwiki takes the concept a step further, by adding the ability to just throw a little checklist into any wiki page which automagically becomes a set of tasks managed by taskwarrior. Basically, it gives you a text-based method of managing your tasks.

You might be wondering why I like taskwiki so much, despite the fact that it fulfills none of my stated goals. It took me some thinking to figure out why I was so attracted to it, but I think I've figured out the reason: It gives your tasks a greater context. Sure, you can add tags and projects in taskwarrior, but this lets you organize and annotate those tasks however you want. You can make a new page in your wiki, write down some general description of something you want to do, then add a checklist of actionable goals to it. Those goals can then show up in checklists elsewhere, where you can check on their status or update them, and in the main wiki page you can add notes and other details as you make progress. Personally, I find that very exciting.

Some thoughts

  1. Taskwiki is actively developed/maintained. This is good.
  2. Resizes nicely, but you have to manually refresh your tasks.
  3. It was a huge pain to set up (about an hour of work). This is no longer important, but I figured it was good to mention.

Constructing a plan

I didn't find anything that really fills the niche that I'm looking for. I think I can adopt taskwiki to handle some of my needs, but I'll also need to make something to fill some of the gaps. So, here's the plan:
  1. Try to use taskwiki seriously for a while. I want to see how well using a wiki for organization actually works in practice, and there's only one way to do that. Next week, I'm going to write up a more detailed overview of vimwiki and taskwiki.
  2. After that, I'm going to start building some scripts to cover the features that I want. While I can't precisely say what I'll need yet, I'm expecting that I'll want some way to be directly notified of upcoming tasks, and I'll probably also want a way to quickly pull up the wiki when I log in.
Ad before you get worried about dfgame, don't! I've been working on it behind the scenes, and you'll hear more about my progress in a few weeks.


Getting Organized - 1 - Selection

One problem that I've been dealing with these past few months is organization. As the past 4 1/2 years of blogging should have made clear, I am not very good at managing my time and priorities. Now that I'm working 40 hours a week, the problem has gotten bad enough to seriously annoy me. So, I've decided to try and solve this problem the only way I know how: With software.

Looking back

I've tried a few pieces of software for keeping track of important dates and tasks. None of them have really stuck so far, so my first instinct was to write my own solution. However, I'm not going to do that. After seriously considering the idea for a minute, I've reached the obvious conclusion that creating a new project to try and improve my time situation is only going to make things worse. Instead, I decided to try and look at the problems with previous approaches and solve them.


In the months before and just after starting this blog, I was using some kind of todo list software. I remember almost nothing about it, including the name, and I can't find it anymore.

Google Calendar

During my college career, I used Google Calendar to keep track of classes and events. Beyond that, I never really bothered with it. My main issue with Google Calendar is the fact that it's an online service. I prefer to keep most of my applications off the web, mostly because webapps:
  1. Take up a disproportionately large amount of system resources to run.
  2. Won't work without an internet connection (duh).
  3. Take up an extra tab in my web browser.
  4. Usually collect personal information to sell/profit from.
 I see the appeal for most "normal people", but I can't stand webapps. This disqualifies Google Calendar right off the bat.


 For a while, I used a terminal application called Calcurse. Calcurse is an interesting program, because it gives you a nice curses-based calendar UI in the terminal. However, I had a couple of big complaints:
  1. The way that Calcurse handles todo lists leaves a lot to be desired. Unlike regular appointments, the program doesn't let you add items to your todo list with any sort of time attached. If you want to do something by next week, you need to make an appointment, rendering the todo list useless. Worse still, Calcurse won't try to warn you about the appointment ahead of time besides tossing you a notification a few hours or minutes before.
  2. In practice, Calcurse is incredibly aggravating to use. When you start it up, you have to hit enter to pass a message saying that it has loaded up. You have to do the same thing when you exit, but then it also prompts you just to be sure you want to quit after that. So, you have to hit 3 different buttons in turn to exit, for no good reason. It might not seem too bad at first, but it's super annoying and I don't know of any method to disable it. On top of that, it splits everything into 3 different panes, and you have to cycle between them with the tab key. They couldn't give you a "go back" or "go next", or just 3 buttons to select the specific mode that you want. Nope, they decided that you'd have to press tab until you got where you wanted.
 This program is a usability nightmare. I'd like to avoid using it.


...This brings me to the last option, going by things that I've used previously. Taskwarrior is a task management program that works really well for keeping todo lists and does a good job of prioritizing tasks.

I really like Taskwarrior, but I can't ever seem to make it stick. The main reason for this is probably because it's a basic command-line tool. There's no interface, only commands. This makes using it pretty inconvenient, as you can't just keep a view open to glance at or see notifications when time-sensitive tasks are coming up. Taskwarrior is more of an interface than a user-friendly application, which makes using it without any extra tools pretty annoying.

Of the options I've looked at, I think Taskwarrior is a pretty clear choice. While I still have to do some work to get it working, most of the heavy lifting will be already done for me. Hopefully, this will keep the time investment for this solution low. Hopefully, I'll be posting updates on this soon after I make more progress. Stay tuned!


DFGame - Rendering Improvements

One of my main goals for DFGame is to make development fast and convenient. Some people might consider something like this to be impossible with a low-level language like C. However, there are a number of tricks that I've been using to improve the simplicity of DFGame. To see how this works, I'm going to compare and contrast the graphics code from before I started working to now.

Friendly warning: The contents of this post are going to get a bit technical. If you aren't fascinated by APIs, you may not be interested.

Shaders and Meshes

The first thing that we'll compare is how to create shaders and meshes.
The old method is simple, but not great. Both asset types can be loaded from files, but if you want to include any shaders in your code then you need to write them as strings. To help you visualize, here's an example from the old version of the code:

static const char* quad_fs[] =
    "#version 330\n"
    "uniform sampler2D texture;\n"
    "uniform vec4 color;\n"
    "in  vec2 v_uv;\n"
    "layout(location = 0) out vec4 f_color;\n"
    "void main() {\n"
    "f_color = texture2D(texture, v_uv) * color;\n"
That's more or less how it looks. There's no syntax highlighting, and every line has to be quoted and end with a "\n".
To create a new mesh from code, you specify the number of vertices and the type of data that you intend to store. The result looks a little like this:
create_mesh(vertex_count, VT_POSITION | VT_TEXTURE);
Not too shabby, but we can do better.

Next, let's see how it's handled now!
The first big difference is that I no longer need to put shaders in my code in order to compile them in. After discovering a code generation feature in Meson, I wrote a small program to generate C headers from shaders. The resulting headers go to the trouble of embedding the code for me, and I can simply include them in the code wherever I wish. I also made the generator write macros so that I can make a single call to get the compiled shader, ready for use.
Mesh creation has changed a little as well. Instead of initializing a buffer with the components that I specify, I've made a simple generic macro (another very neat thing that I learned a few months ago) that can infer what components you want based on the data that you pass in. To extend this I'm planning on making it possible to add/replace data in the mesh even if the data is in the wrong format, since I can figure out what's inside at compile-time. As you can see below, the result is a little more readable.

mesh_new(vertex_count, data);
As you can see, I've taken some decent code and made it even quicker and easier to work with. Changes like these are happening all over the codebase, so I have high hopes for the resulting framework.

One unfortunate thing to mention is that the updated version of dfgame can't load resources from files yet. In many cases, I'd load my meshes and shaders from elsewhere, but I can't compare how that will look until I get to it later down the line...

Binding Data

Now that we've looked at how meshes and shaders are created, let's look at how binding data to shaders works. In order to render a mesh, we need to bind the mesh being rendered as well as any additional data (textures, transformations, etc). Generally, making binding simpler also simplifies drawing code in general.

In the old version, there was a bind function for each type. Aside from textures, every function was more or less the same-it just called a different OpenGL function to bind the data. To try and get around this, I wrote a bunch of rendering functions that would bind things for the user. These would always bind to the same variable names, however.

When deciding how to update this part of the code, I decided to try and give a decent balance of simplicity and control. The rendering functions are no longer present (for now) but I've wrapped the binding functions in another generic macro. Now, I can bind almost anything I want with the same call instead of having to specify the type.

There remains one problem with this approach, however: Since meshes can have multiple types of data in their vertices, they need to potentially be bound to multiple different shader inputs. This wasn't an issue before, since variable names were assumed when binding. To get around this, I made my mesh binding function variadic (that is, I allow a variable number of arguments). The user can simply pass all of the names and data types that they care about in a single function call, resulting in something like this:

shader_bind_attribute_mesh(shader, mesh, "position", VT_POSITION, "color", VT_COLOR);
This is pretty simple, and if I wanted to I could make a name-less version that used the old assumed names.


There are still many parts of dfgame to review, and I'm certain that there are many other places where the API could use a helping hand. The few parts that I've touched have already benefited immensely, and I'm excited to see where things go from here! These posts will hopefully be a little less dry once I get out of the graphics code, but until then hang in there!


Let's Make a Roguelike: Schedule Change

Today, I have a not-so-good announcement. After much consideration, I've decided to drop the schedule for my tutorials, and post segments on a "when it's done" basis.

If you look at my track record, you'll find that I haven't hit my schedule on a very consistent basis. However, I probably wouldn't drop the schedule if this was the only issue. The real problem is how this schedule has been affecting my ability to work on other things.
My typical schedule for the past few months was something like this:

Pre-Tutorial Weeks
On weeks before a tutorial is due, I usually commit most of the week to working on the tutorial. However, I usually end up delaying things and as a result, I don't get a whole ton finished. This also means that I don't get anything done on my other projects. After that, I need to spend the weekend working on the tutorial so that it can be ready on Monday.

Post-Tutorial Weeks
Following the Monday tutorial post, I have about four days to work on other things before the weekend rolls around. I don't necessarily have to work on the tutorial during these weekends, but if I want to ensure that the tutorial will be done in time then it's a good idea.

Because of the circumstances, the tutorial is currently eating about 2/3rds of my development time. This makes it really tough to work on more than one other project at any moment. I'm not going to stop working on tutorials or anything, but after this one's done I'm going to move to a "prepare everything before posting" strategy.

Wrapping up
Despite these issues I'm still working on this series. After scrapping it twice, I want to see this thing done no matter what. However, I won't sacrifice my other projects to see that happen. To avoid that, I'm dropping the schedule.