4 Hugues Ross Writes a Devlog: 2017
Hugues Ross

7/16/17

Getting Organized - 6 - Tick Tock

Hello again, dear readers. Once again, it's time to make my life a little more productive. In my previous post, I grappled with my computer a little bit in order to bring my to-do list up every morning. This month, I'm going to work on my time management a little.

When I mentioned that I wanted a timer back in May, I said that I wanted "I'd like something that fits with everything else". I'm not entirely sure how many purely hypothetical beers I drank before writing that thought, but looking back it sounds more like the mutterings of the local town loony than anything important. I assure you, however, that this strange little collection of words will make sense if you read the following two paragraphs. So, y'know, you can just skip them if you're up for a challenge.

So, if you've been reading these posts religiously then you'll know that I use Awesome to manage my desktop. This gives me lots of control and customization options, but also makes using "traditional" desktop apps cumbersome at times. In this case, a quick Google search will find you endless pages of linux timer apps, coming in exactly two flavors:
  1. Pretty (useless) dialog windows that take up half your screen with fancy Large Text
  2. Icons in your system tray
Option 1 is unappealing in general, but also breaks with my window-management preferences. I could let one of these apps ignore Awesome's tiling rules, but then it would also block me from interacting with whatever's underneath it. Oh, and it's definitely not getting its own special desktop, so that's out. Option 2 would work nicely...if I had a system tray. I could add one and watch it fill with useless incongruous icons, or I could not do that and sleep well at night. But, there's another solution. Let's take a look at my bar for a moment:
Pretty much all of those nice little UI bits are custom. So, I can make my own "Option 2" that fits with the visual style of my desktop and does exactly what I want.

If you're still following along with my little scheme to make a timer but you're not sure it's quick or feasible, then I have some good news: It's done. I secretly went and did it this morning. Normally, I write and code together, but I just wasn't in the mood for 6 AM blogging. What was in the mood for was Runescape (???), and I didn't want to miss any deadlines in the process. I suppose you could say I was motivated by laziness, but I'm not about to complain!

The Implementation

The result of my mad morning keyboard mashing was just under 100 lines of Lua code. Most of that is UI boilerplate, but there's about 40 lines of actual logic in there that might interest someone, so let's give that a look:
   52 local timer = gears.timer {
   53     timeout   = 1,
   54     autostart = false,
   55     callback  = function()
   56         seconds_left = seconds_left - 1
   57         if seconds_left == 0 then
   58             awful.spawn({"mplayer", "/home/df458/assets/se/Notify01.wav"});
   59 
   60             local message = string.format("Your timer of %02d:%02d has ended", math.floor(seconds_total/3600), math.floor(seconds_total%3600/60))
   61             if seconds_total < 3600 then
   62                 message = string.format("Your timer of %02d:%02d has ended", math.floor(seconds_total/60), seconds_total%60)
   63             end
   64             naughty.notify {
   65                 title = "Time's up!",
   66                 text = message,
   67                 timeout = 300
   68             }
   69         elseif seconds_left < 0 then
   70             widget:set_visible(false)
   71             timer:stop()
   72         end
   73         progress:set_value(1 - (seconds_left / seconds_total))
   74         if seconds_left < 3600 then
   75             label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/60), seconds_left%60))
   76         else
   77             label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/3600), math.floor(seconds_left%3600/60)))
   78         end
   79     end
   80 }
   81 
   82 function activate_timer(seconds)
   83     seconds_left = seconds
   84     seconds_total = seconds
   85     widget:set_visible(true)
   86     progress:set_value(0)
   87     if seconds_left < 3600 then
   88         label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/60), seconds_left%60))
   89     else
   90         label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/3600), math.floor(seconds_left%3600/60)))
   91     end
   92     timer:start()
   93 end
As you can see, this little code block could probably use some cleaning. With that said, it works pretty well and demonstrates just how easy it is to make a timer. All I really do is set two numbers to how many seconds I want to wait, then subtract one from the 1st number every second. The second number isn't even necessary at all, but I use it to add a progress indicator. Beyond that, the rest is just making a nice text representation that switches between hour:minute to minute:second as necessary. When the timer's running, my little info are looks like this:
It's simple, sure, but it works quite well! Next time, I'll be wrapping up this series with some final touches to task management.

7/2/17

Roundup, June 2017 - Lost in another dimension

It's that time of the month again, and I've made great progress!

Additional Comments

In addition to what was mentioned in the video, I also went back and re-added joystick emulation to the input code, as well as adding a few minor features and fixes all around. Besides the lackluster demo, this has been one of the best months for development this year.

Goals

  • Time left: about 1 1/2 months
  • Application Module: Done 
  • Audio Module: Done
  • Core Module: Done
  • Gameplay Module: Done
  • Graphics Module: Done
  • Math Module: Done
  • Resource Module: Done
As I said in the video, and as is apparent from the list above, I'm just about finished with dfgame for the time being. If you've been following along, you've probably noticed that I quietly removed particles from the goal list. This is because particles are a bit of an unknown for me.

"But wait!" I hear you cry. "Didn't DFEngine have particles?" This is correct, but DFEngine's implementation was super basic and not very good. My standards for features, while not amazing, are definitely higher than they used to be. If I were to make particles now, I'd want to use the GPU or at least some form of SIMD to get good performance. I played around with GPU particles last summer, but I ultimately ran into a few issues that halted progress and moved on to other things. A decent particle implementation will take some research and effort, but I don't know how much so I'm putting it off for the sake of polish.

Some Bad News

The main goal of my "End of August" timeline was to use dfgame for an actual game jam entry. Unfortunately, I just found out that for the first time in 15 years, Ludum Dare is being held at the end of July. Why? I have absolutely no idea. I could theoretically still enter, since dfgame's release is now feature-complete. However, I would be sacrificing about 50% of my polish time to do so.

Instead, I'll just keep an eye on the itch.io game jams page and select one in the right general time period.

As for next month's posts...beats me, I forgot to plan anything. Whoops!

6/26/17

Happy birthday to Me!

First off, let me apologize quickly for missing my post deadline last weekend. I decided to take a second break this month in order to celebrate my birthday without the stress of writing another post. As much as I love working on this blog, it takes enough time and effort for me to want breaks here and there!

Anyhow, you can expect this month's roundup to land on Sunday at the usual time. I've made great progress, so I think it'll be a pretty good update.

6/11/17

Getting Organized - 5 - Some Awesome Work

When we last left off on my quest for good time management, I decided to share my pizza recipe instead of being productive. Clearly, I'm making good progress. Now then, it's time to do some actual programming.

Awesome!

No, that's not your cries of joy. Awesome is the Window Manager that I use on all of my machines nowadays. In addition to laying out my windows in a pleasing fashion, it also exposes a powerful lua API for customizing and scripting, well, everything. This includes the UI, allowing for some very in-depth customizations!

Last time, I made a list of tasks to complete:
  1. Automatically opening my wiki every morning
  2. A simple timer that fits with my workflow
  3. A way to create tasks remotely while at work
Today, I'm going to finish off the first task. Furthermore, Awesome is going to help me with that.

Hello, Wiki!

Originally, I said that opening my wiki in the morning would be "super-easy to do". I lied! I lied to everyone, even myself! And what a lie it was.

An Unexpected Snag

The easiest way for me to make programs start on launch is to add them to my xinitrc file. In this case, I actually can't do that. Because the terminal that I run vim in won't have its settings ready before my xinitrc finishes running. That means that if I use my xinitrc to bring up my wiki, the colors and fonts will be wrong and it'll have a horrifying scrollbar that looks like it crawled out of Windows 3.1.

Obviously, I don't want that. Awesome gives me the ability to run applications, so I can have it launch my wiki. Perfect, right? Wrong! To help debug scripts and configuration, Awesome provides a mechanism to restart it without closing anything. This is also great! However, this means that every time I restart Awesome it'll also open the wiki again. So, we have a conundrum.

The Solution

The second problem can be solved, but it'll take a few small additions. The goal here is to have Awesome run certain programs on startup, but only if it isn't restarting. To do that, I need to store some information across runs.

Conveniently, Awesome has an event that runs when it exits. Even better, that event tells you whether the exit is part of a restart or not! So, I simply write a value to a file based on whether Awesome is restarting or not. Then, Awesome can read the value when it starts and use it to make decisions. The result looks like this:
awesome.connect_signal("exit", function(restart)
    local lastrun = io.open("~/.config/awesome/lastrun", "w")
    if lastrun ~= nil then
        if restart then
            lastrun:write(0)
        else
            lastrun:write(1)
        end
        lastrun:close()
    end
end)

...

local lastrun = io.open("~/.config/awesome/lastrun", "r")
if lastrun ~= nil then
    local was_quit = lastrun:read("*n")
    if was_quit == 1 then
        for i,e in pairs(autostart_once) do
            awful.spawn(e)
        end
    end
    lastrun:close()
else
    for i,e in pairs(autostart_once) do
        awful.spawn(e)
    end
end

for i,e in pairs(autostart_each) do
    awful.spawn(e)
end

As you can see, it's actually pretty simple. Anything that I add to the autostart_once list will only start if Awesome shut down properly last time it ran. On the other hand, anything in the autostart_each list will run every time Awesome runs. This makes for a convenient solution that I can use as much as I want going forward.

So, that was a semi-complicated solution to a relatively simple problem. Come back next time for some tougher-but-more-straightforward scripting.

6/4/17

Roundup, May 2017 - Oh man I sure do hope the mosquitoes don't--

It took great courage and perseverance, but I finally drove back the mosquitoes that definitely ate all of last week's update. So, here it is:


Additional Comments

I had some difficulty capturing/rendering this video. Last time, I used glc for the video capture. However, glc's audio recorder is really buggy and doesn't work on my machine. It's also quite old, so I'm worried about relying on it too much. This time I made a recording with FFmpeg, but it's just a normal desktop capture so it's a bit slower than I'd like. Next time, I'll probably try to capture the video and audio separately. It might be annoying to line the two up in editing, but it will probably result in a higher-quality video.

The big gain from rewriting the audio system is that multiple audio players should now be able to play audio from the same source at the same time. This means that I don't have to reload a sound effect every time I want to use it, and instead I can easily load once and play hundreds of times. As you can guess, this is really useful for games where you could easily have a couple dozen objects that can make the same sound.

Goals

  • Time left: about 2 1/2 months
  • Application Module: Done 
  • Audio Module: 95%
  • Core Module: Done
  • Editor Module: Not Started
  • Gameplay Module: 80%
    • Missing joystick emulation for input
  • Graphics Module: 65%
    • Missing sprites
    • Missing text
    • Missing framebuffers
    • Missing particles
  • Math Module: Done
  • Resource Module: 65%
    • Missing sprite loading
    • Missing font loading
This month went a little slower than I'd hoped, and some of the code that I wrote feels a bit rushed. As a result, I'm going to need to do another quick pass on the audio and resource modules at some point, just to tighten them up a bit. That's not what I'm doing for June, however. I want to get the last couple essential features, sprites and text, done. This will happen as part of a greater attempt to finish off the graphics module as a whole. I don't expect to finish all of it this month, but it wouldn't surprise me too much if I could sneak framebuffer support in.

If all goes to plan as it has so far, I'll have over a month left over to clean up any loose ends and improve my workflow in preparation.

Next month's posts will feature lots of Linux shell scripting. Much like in May, I'll be kicking off next week with some more organization work.

5/29/17

Mosquitoes ate my update video

Man, don't you hate it when small, buzzing insects devour files off of your hard drive? It's the worst. It's also something that definitely happens all the time, and our modern society is powerless to stop them. Remember when your favorite thing was cancelled or delayed for no apparent reason? Mosquitoes. Yup. Definitely 100% not telling any sort of fib or white lie right now, and frankly I'm a little wounded that you'd suggest that I might ever not tell the truth in a vain attempt to cover up my own shortcomings.

So, because a swarm of mosquitoes ate the update video for this week that I definitely made and didn't put off for too long, I'm making a little life post instead. You can expect me to have it finally finished remade in time for next Sunday's post.

Let's talk about my weekend

I had a really busy weekend, which is why I was unable to complete my video powerless to stop the horde of ravenous arthropods from devouring my video files.

On Saturday, I went on a hike in the Laurentides with a group from the office. For those who don't know, the Laurentides is a region of Quebec that's packed full of beautiful lakes and mountains. Just imagine every photo of the Canadian wilderness that you've ever seen.

This pretty lake is the perfect environment for breeding the harbingers of your hard drive's doom

The hike was 5 1/2 km, and circled a small lake. It was a good length, long enough to be enjoyable without overstaying its welcome. The weather was warm and sunny, but not so hot as to be uncomfortable. In many ways the conditions for this hike were ideal. They also happened to be ideal for the terrifying force of mosquitoes that hounded us and our video files, especially the latter. For every person, I'd say there were 10-20 mosquitoes buzzing around them. They didn't manage to ruin the experience though, and I'd definitely do it all over again. Oh, and uh....some of them, err, hid inside my backpack? Yeah, sure, we'll go with that. Then they emerged to feast upon my defenseless PC or something. It was awful.

Artist's rendition of the event

Unlike most activities that I engage in, I brought my camera with me and took a few photos. Several shots came out quite nicely, so I might do this more often:

(Click any image to view at full size)

On Sunday, my family came in for a visit. They brought my bike over, so once I buy a new helmet I should be able to travel much farther in the city! After that, we went out for pizza and ice cream, then took a little stroll around Parc La Fontaine. I'm not fond of spending lots of time with family, but I really enjoyed this little outing quite a bit! They seemed pretty happy too, so it was a good day all in all. Oh, and they were...yeah, they were totally devastated at the carnage caused by those darn mosquitoes. Yup!

So that was my eventful weekend! As you can see, I was quite busy and didn't find time to make this month's update video set up adequate anti-mosquito defenses. Anyhow, this week is mostly still May so I'm still keeping to the schedule to some degree. Expect the monthly dfgame update next Sunday at the regular time.

EDIT: According to Blogger, this is post #256, so if we were counting with one byte I'd have to stop here. Thankfully, that's no longer the case!

5/21/17

A post-graduation reflection

Last May, I got my Bachelor's Degree at Champlain College. Now that May has come again, I thought I'd give a quick recap on my first year out of school.

Getting a job

I started hunting for jobs on and off several months before graduation. Unlike many of my peers, I was in the interesting position of not wanting any sort of game development job at all. For years, I'd read stories about the horrors of game development and how it churns through the annual supply of bright-eyed college grads. So, I applied to software development gigs and got ignored a whole lot!
 
I suppose it's natural. Game Programming doesn't sound like the most reliable major to pick, even with the work I've done on my own. Ultimately, I got my current job through a mix luck and networking: My friend Vince (lead programmer on The Last Light) recommended me to a recruiter from Ubisoft Montreal during the end-of-year showcase of our game, and that led to an offer. (Seriously, networking is really good and you should do it) I wanted to stay close to my home in Vermont, so I decided to take the offer rather than keep looking.

Canada!

With the offer accepted and some necessary summer prep work complete, I found myself on the other side of the border just in time for Fall. Due to a scheduling mishap, I ended up arriving a month and a half before my start date, giving me plenty of time to settle in and explore the city. In order to best take advantage of this, I spent the majority of the time sitting in my room with a tiny specter of legal and financial uncertainty drifting lazily over my head.

Now that the weather is warm and I no longer fear for my checking account, I've been spending more time going out and looking around. Overall, I'm super happy to be here! Being half-French, I'm enjoying the mix of languages especially, even if I now have an irrational fear of peanuts.
Yup definitely not made of spiders no siree
...Moving briskly on, Montreal is a really nice spot to live. I've got a nice inexpensive apartment on the Plateau, and some streets are lined with enough trees to almost give the feeling of being in the woods! As someone who grew up in a reasonably small town village, the neighborhood makes me feel at home while still providing all of the bustle and convenience of a city close by. (And of course, there are some standard socialist benefits like free healthcare and unified public transportation systems)

Work life

Unfortunately, I won't be discussing too many details of my work. I'm not 100% sure what is/isn't covered under my NDA, so for now I'm playing it safe and speaking in very general terms. If I get that cleared up I might discuss some juicy details in a future post. So far, Ubisoft has been an incredibly pleasant surprise. Being a big publisher, I was expecting them to screw me over at every opportunity, but I have absolutely no complaints about them.

I've only truly been "on the job" for a scant few months (I was in a long-term training up until mid-January), but I feel like I'm trusted and relied upon regardless. I usually get handed a bunch of requests and long-term goals, and then I'm left to my own devices until they're finished. Not only have I not done any overtime, the senior devs that I work under have made a point of reminding me to take it easy on the hours and stay fresh. Some of this can be chalked up to the fact that the production I'm on is still at a very early stage, but even so I was expecting much more pressure.

Another fear that I had was about whether or not I'd be allowed to continue my personal work unrestricted. Ubisoft requires you to send in a 'request' for side-projects, but:
  1. The restrictions that come attached are mostly just obvious things that most sane people wouldn't do in the first place
  2. The responses get back to you in a reasonably timely manner
  3. I have pushed no fewer than 19 personal projects through the official channels, and to this date not one of them has been refused.
Point is, they're pretty nice about these sorts of things. It would be even better if they didn't ask for requests at all, but at least the process is simple and painless.

The work itself has been really fulfilling and exciting for me. I've been doing tools work since it's the closest I can get to normal software development, and it's been a lot of fun! It makes me a little disappointed that Champlain doesn't cover tools programming in their curriculum at all, given how crucial good tools are to large-scale production teams. I'm mostly working in C# and WPF, but my experience with Vala and GTK are still coming in handy regardless. Indeed, it feels like both my personal and professional work are fueling each others growth.

To sum it up, I've managed to land a fun and not-too-stressful job in a city where I feel at home right out of college. I can't help but feel lucky where I am right now, and I hope my current streak of good luck lasts quite some time to come!

5/7/17

Getting Organized - 4 - Gripes and progress

Another week has passed, and here I am, still using Taskwiki. I promise that this is the last time I bring it up for a while, but I wanted to discuss some of the good and bad that I've encountered before moving on to some actual code.

This week, I haven't made too many additions to the wiki itself. My main addition was a project list, and the start of a dfgame wiki. The way the dfgame wiki is laid out, I have a task filter front-and-center. Rather than adding things to the list directly, it simply gathers all of my tasks for the project into one place. Inside the pages for each module, I can simply jot down relevant tasks, and they'll appear on the front page as a combined list.

I've also started using vimwiki (no taskwiki yet) at work! It has given me more time to get accustomed to the bindings and nuances of the plugin, so I'm pretty happy about that.

The Good

  • As it turns out, a number of annoying Taskwiki keybindings have normal Vimwiki equivalents that are much nicer! Of note is Control-Space, which creates/toggles a checkbox. Since Taskwiki runs off of checkboxes, you can use it to create new tasks or mark existing tasks as completed.

The Bad

  • Turning my first good point around: Why does Taskwiki bother making and teaching custom keybindings for Vimwiki features? They're much less convenient and harder to use in general.
  • Taskwiki doesn't seem to have any convenient ways of inputting projects and tags for your tasks. You can do it as part of a filter, but otherwise you need to edit the task after creating it.
  • I decided to give task dependencies in Taskwiki a shot, but there's one big problem that I realized: Because of my date filters, dependencies with different due dates can simply not show up sometimes. As a result, dependencies are pretty much useless outside of project pages.

Time to code!

Now that I've played around with Taskwiki long enough to make it a part of my workflow and see the uses (and flaws) of the tool, it's time to fill in the holes. I've come up with a few tasks:
  1. I don't want to open my wiki every morning. Instead, I'd like to have that happen automatically. Thankfully, this is super-easy to do.
  2. I need a timer. It's easy for me to take a five minute break, then wake up after several hours of doing something else. I could look for a timer program, but timers are pretty simple and I'd like something that fits with everything else.
  3. I need a simple way to create tasks while I'm at work. This is probably going to be a tricky one to pull off, but I have some ideas.
Now, because this post is secretly a horrifying bait-and-switch, I'm not actually going to write any code yet. Instead, I'll be teaching you the secret art of baking a delectable 12" thin-crust pizza from scratch on a weekday.


You'll need the following ingredients:
  • 1 1/4 cups of flour
  • 1/2 cup of lukewarm water
  • 1/2 tsp salt
  • 1/2 tsp instant yeast
  • 2 tbsp olive oil
  • 1/4 cup tomato sauce
  • Enough mozzarella, possibly more
  • A few pinches of thyme and oregano
  • 1 small clove of garlic (optional, but recommended)
  • 1 tbsp dry minced garlic (optional, but recommended)
  • Toppings of your choice (optional, but recommended)

A few notes

Before we begin, I want to give a quick shoutout to King Arthur Flour. They have a ton of great ingredients and recipes, and the dough for this pizza is adapted from one of their Ciabatta recipes.

Disclaimer: I'm not an expert on cheeses, this advice is based entirely on personal experience.

The night before...

  1. The night before you plan on baking, mix together 1/2 cup of flour, 1/3 cup of lukewarm water, and some yeast. The precise amount of yeast isn't too important, just keep it between a pinch and 1/4 tsp.
  2. Cover the bowl and put it somewhere warm overnight.


The next morning...

  1. In a medium/large mixing bowl, combine the the mixture that you prepared with 1/6 cup of lukewarm water, 1/2 tsp salt, and about 1/4 tsp instant yeast. Add the olive oil and dry minced garlic, and stir the mixture together until it's combined.
  2. Add 3/4 cup of flour and continue until the mixture starts to turn into a solid mass. At this point, you'll want to keep adding small amounts of flour and mix/knead with your hands until you have a ball of slightly sticky dough.
  3. Rub a little bit of olive oil into a clean bowl or rising bucket and add the dough, then cover it and stick it into the fridge. (If you're doing this step in the afternoon, skip the fridge and go directly to the next step)

That evening...

  1. After about 8 hours in the fridge, take out the dough container and let it continue to rise for an hour. If you just prepared the dough, let it rise for 3 hours instead. While you wait, prepare your toppings.
  2. After this final rise, sprinkle flour onto a clean work surface and roll out your dough into a rough circle. Don't overdo it, try to keep the circle around 10". sprinkle flour onto your pan/baking sheet, and carefully transfer the dough to it. Using your hands, spread the dough out to the desired size, pressing your fingers to leave a slight lip at the edge.
  3. Set the oven to 500F (or however high your oven goes), and immediately place your dough inside. Let it bake for a few minutes until it just barely begins to brown, then remove the dough and place it on the stove. This step will cook the dough ever-so-slightly, making for a crispier crust. If the center of the dough has begun to puff up, carefully press it back down (be careful here, you don't want to get burned).
  4. Quickly add the sauce, garlic, cheese, herbs, and toppings in that order, and put the finished pizza back in the oven to bake. There's no universal bake time for pizza, because ovens vary in temperature. Instead, I recommend watching for the cheese to melt and brown to know when the pizza is finished.
  5. Pull out your pizza, place it on a rack to cool, and enjoy! The number of steps may seem off-putting, but I assure you that this recipe can be done without too much effort. Good luck!

5/1/17

Announcement: A newer, better schedule

With a new month comes a new and shiny schedule! Up until now, I've been mostly winging it with regards to posting here. My goal was one post a week, but I had no other rules to go by. It was a lawless wasteland, here on this blog!
Pictured: A lawless wasteland of blogging
It's time to end all of that. The sheriff's back in town and he's getting organized! Apologies about that not showing up until last Thursday, by the way. It was scheduled for the Sunday before but Blogger decided not to post it for some reason???
Being just a tad more serious for a moment, now that I'm capable of reminding myself about long-term tasks I'm going to try my hand at a proper schedule again.


The schedule

New posts will appear on Sundays at 9:00 PM (EST).

The last post of every month will be a large update post about my current focus. Between now and August, that's dfgame. That post will come with higher production values than my normal posts, featuring images, videos, audio, or something else entirely.

Besides the big update, I will also make two smaller posts every month. These can be about anything I want, but will likely resemble the type of content that I've posted in the past.

On one week each month, I won't post anything. This break can be taken on any week besides the last, and it'll hopefully keep me from having to apologize about delays or throw together something uninspired at the last minute.

Announcement posts (such as this one) will not count towards the monthly post count.


Summary

Expect one fancy post at the end of each month, and two little posts in-between. Assuming they're on time, posts can be expected to arrive on Sunday evenings.

I might also try to make my posts funnier. I like to think that I'm a pretty amusing fellow in real life, but dear lord are my blog posts boring. Hopefully, that's about to change.

Expect the puns. Fear the puns. Become one with the puns.

4/30/17

Roundup, April 2017 - A hole new perspective on falling into bottomless pits

Today, I'm doing something a little bit different: I've created a video for this update!


Additional Comments

It has been a while since I last posted any videos, and this is my first attempt at making something more detailed than a simple playthrough. In my opinion, the result is ok. I think it was a pretty good decision, given that I mostly worked on graphical stuff this month.

The video contains an overview of the update, but I wanted to add a couple of details that didn't make it in:
  1. Axis inputs received a few changes that I didn't mention. First of all, they are no longer 2d. Each axis is independent. They're also missing the "joystick emulation" input smoothing at the moment. I'll be adding that back at a later point.
  2. I've made a ton of bugfixes this month. There were a lot of things (especially in the core module) that didn't quite work, but testing them didn't seem worth doing until I had an actual use for them. Now that I'm building demos, I'm running into the issues and fixing them naturally.
  3. Lastly, I've written a bunch of macros for printing out certain structs to logs. This makes debugging much easier, because I can quickly print out the value of a matrix/vector/quat with little effort.

Goals

Let's start with the current state of the project:
  • Time left: about 3 1/2 months
  • Application Module: Done 
  • Audio Module: Not Started
  • Core Module: Done
  • Editor Module: Not Started
  • Gameplay Module: 80%
    • Missing joystick emulation for input
  • Graphics Module: 40%
    • Missing sprites
    • Missing text
    • Missing framebuffers
    • Missing particles
  • Math Module: Done
  • Resource Module: Not started
I'm making pretty good time right now. My goal for May is to knock out the Audio and Resource modules, which will leave me a couple months to reimplement the more advanced graphical features and make API easier to use. I've decided not to bother with the editor module for now, because it won't be useful for game jams and concept work. Instead, I'm going to work on it after the deadline has passed.

Next week, I'll be unveiling a new schedule and discussing my forays into Taskwiki in more detail.

4/23/17

Getting Organized - 3 - Impressions on Taskwiki

It's been a week since I started playing around with taskwiki, and I'm going to share my thoughts on it so far. Two weeks isn't enough to get a truly complete view of the plugin, but I still have a few things that I can discuss.

At this point, I've set up a nice segmented todo list on the front page of my wiki. By carefully assembling some taskwarrior filters, I've created 3 main sections: Today, This Week, and This Month. The sections are pretty self-explanatory. I haven't played around with making tasks for my projects yet, so for now it's mostly a way to track chores and real life commitments. So far, it has been pretty helpful in that regard!

I gave my initial thoughts on taskwiki in my previous post, and now that I've had more time with it I've compiled a more detailed list of thoughts:

The good

  •  It takes out a lot of the tedium of using taskwarrior, and it's easier to commit to. Having an interactive interface lets me keep it open all the time, rather than forcing me to remember to pull it up regularly.
  • Using taskwarrior's filters with taskwiki makes them much easier to deal with. Without taskwiki, I'd need to type out (or tab-complete) several filters and call taskwarrior with each one. With taskwiki, I can use filters with more of a "set it and forget it" attitude.

The bad

  • I ran into an annoying bug today. Taskwiki updates the status of your tasks when you save the page. However, if a task is shown in several spots then these copies can conflict with each other. For instance, you could mark a task as done, then see it "un-mark" itself because another copy wasn't marked. I doubt it'll happen very often, but it's an inconsistency that will surely return to annoy me in the future.
  • To add a new task to a list, you can just add a new line at the end. This is good! However, adding a new line at the heading with the filter or in the middle of the list doesn't add a new task. This makes the feature much more vexing than it really ought to be.
  • Setting a specific date on a task feels pretty inflexible, because you need to write out the date (e.g. 2017-05-01 rather than 05-01 or May 1). To get around this, I've set up my lists to choose dates for me when I add tasks to them.
  • Even with my list in front of me, I still tend to ignore things outside of the "Today" category. If I set a task for something that I need to do this week, I probably won't pay it much attention until the date gets close. This isn't a taskwiki problem, but I definitely need to do something about it.

To sum up the above list, I like the convenience of taskwiki but it has several niggling issues that annoy me. For now, I think I can live with them.

Next week will be something different, but I'll be back with more thoughts once I start making wiki pages for my projects.

4/19/17

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.

4/10/17

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.

Tasky

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

Taskswamp

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.

Tasknc


(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.

Taskwiki

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.

4/3/17

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.

Something???

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.

Calcurse

 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.

Taskwarrior

...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!

3/27/17

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"
    "}\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.

Conclusion

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!

3/20/17

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.

3/18/17

DFGame - The road to 1.0

I haven't written much about DFGame in a while. At the end of last year, I gave the project two small paragraphs but didn't get into any specifics. In this post, I'll be getting you back up to speed on the project's status and where things will go from here.

The plan

When I started going back over DFGame, there were a few outstanding problems:

The build system

DFGame was started before I learned about Meson. As a result, the library was being compiled with a makefile. In order to make the project fall in line with others (and hopefully organize it better) I needed to ditch the makefiles and switch over to Meson.

Changing the way that your code compiles can be a bit drastic, especially if the two systems aren't very compatible. In order to simplify things, I decided to try and build each module of the framework as I got to it.

The modules

DFGame was started not long after I started breaking my code up into modules. For the uninitiated, modules are pieces of the codebase that are separated from the rest, and typically compile separately. This allows programmers to use their code in multiple projects, or have multiple applications in their project that share the same code in the backend. As you can imagine, this is a good thing.

The problem with DFGame was that I didn't make enough modules. I broke my code up into five parts, based on whether it was editor or game code and frontend vs backend (plus one for common code). The result is that the common module was a gigantic mess, with 46 code files spanning subjects from audio to rendering to error logging, and everything in-between.

At the tail-end of last year, I decided to try and separate things further. Now, I have 7 modules: Application (game frontend), Audio, Core (logging, memory, etc.), Editor, Graphics, Math, and Resource (asset loading/management). This keeps the different aspects of my framework separated in a more logical fashion, and makes it easier for me to find what I'm looking for.

Inexperience

I don't claim to be an expert, especially not at C. I spend a lot of time programming and practicing, but I still learn new things every day. As a result, there are many small lessons that I've learned since I started working on DFGame. As my knowledge of programming has improved, I've found better ways to do the things that I've already done, so the temptation to rewrite things follows.

With that said, I'm trying to preserve as much as possible. I'm keenly aware (from experience, of course) that rewrites can seriously slow things down, and I want to try and get things sorted out at a decent pace. To that end, I'm going over each file individually to try and improve what I have without scrapping it. I hope that this methodical approach will save some time over a simple redo.

Where are we now?

I've finished going through the core, math, and application modules, and now I'm working on the graphics module. Unfortunately, that means that I don't have much to show for my work yet. I do have this stylish hot-pink triangle though:

Thrilling, I know!
Now that things are showing up on-screen, I expect to have more to show in the coming weeks.

Coming up

Now that I've caught you up to speed, you might be wondering what I'm planning on in the long term. I'm not the best at keeping to my plans, but I do have a goal that I'm aiming for. In about 4 months, it will have been 3 years since I last participated in a Game Jam (aside from 7DRL, of course). That makes me sad, as I really enjoy doing them. Looking at the games page on my site, it seems like when I started DFEngine and AMAZE I mostly much stopped doing game jams altogether.

This year, I want to turn that around. To accomplish this, I'm setting myself a deadline now: I will have DFGame ready for an initial release by August, and I'll compete in Ludum Dare around that time. From my experience, the Ludum Dare game jam usually falls smack dab in the middle of something important and college-related, either the beginning of a semester, finals week, or the move back home. In other words, it wasn't really convenient for me to compete back in college. Now that I don't have a weird seasonal schedule to work around, it seems like a good way to get back into the rhythm of Game Jams. I think that the timeframe I have between then and now is pretty reasonable, and I expect to be finished well before my deadline. Any leftover time that I have can be spent trying things out and building tools.

Conclusion

So that's it! I'm hard at work fixing up DFGame for a release later this year, and hopefully once the dust settles I'll be able to make games again like I used to. I played around with DFGame last fall, and even though I didn't post the results were promising. Whether those results will be replicated with future projects has yet to be seen.

3/13/17

No tutorial this week

This week's tutorial has been delayed to next week. This is mostly because I fell ill recently, and wasn't really in the best shape to do anything serious like preparing tutorial content until a few days ago. I did get a few mindless tasks done on my website, but besides that I didn't accomplish much.

Not to worry, though! I'll have a new post up later this week.

3/11/17

Site Update: Updated software page and more

Last week, I mentioned that I would start posting content on non-tutorial weeks. Now, it's time to make good on that.

I was stuck home sick this week, so I took the opportunity to make some improvements to my site. Some of the changes are obvious, but others are much more subtle so let's take a closer look. Generally, the changes can be broken up into three categories:

Accessibility Improvements

When building my site, I didn't really put too much thought into it beyond how it looked. On a whim, I decided to toss my site's HTML into the W3C Markup Validator, and found its structure lacking.

The two main issues were the misuse of headings and missing alt text on images. In a few places, such as the notes in my tutorials, I was using <h1> tags. <h#> tags have a number that indicates their "level" in the document, like so:

Heading

Heading

Heading

...and so on. The numbers in these tags are used by screen readers and other applications, so it's good practice to ensure that the headings reflect the structure of the page. In my case the stray <h1> tags were breaking the structure, so I changed/removed the offending tags.

Alt text on images is the text that is displayed if the image doesn't load or you're viewing a page in a program that doesn't handle images, the alt text is displayed. Since the images on my site had no alt text, they would effectively be missing if my site were put through a screen reader. Fixing this was pretty simple, since it was just a matter of going through and adding some simple descriptions where applicable.

For the average visitor, these changes are essentially invisible. However, if I ever get any visits from someone who's visually impaired then these changes will hopefully make their life a little bit easier.


Updated Software Page

This change was a long time coming. Ever since I gave the Games Page a fresh coat of paint back in September, I've been meaning to do the same for the Software Page. I've replaced the old design with the one currently used for the Games Page and I've also added some more entries, for a new count of 5.

Right now, there isn't too much content in each entry. I'm still trying to decide what I want to put there, and I also need to get some screenshots/logos for my software. In the meantime, it's still a step up from how things looked before:
The software page (before)
The software page (after)

Mobile-Friendly Styling

Another thing that I'd been meaning to do for a while was making the site responsive. For the uninitiated, responsive websites are sites that can adapt their design to different screen sizes and orientations. Obviously, this is quite important for any site that receives mobile traffic.

A before and after comparison of the site's responsive CSS.
Now, almost all of the content on the site is responsive (there are still one or two exceptions).

Along with the above changes, I've also tried to make the site's text a little more readable by increasing the font size and line spacing. It's a small change, but from my experience it makes reading the content easier on the eyes.

If you have any feedback regarding the changes, feel free to email me or leave a comment below.

2/27/17

Let's Make a Roguelike - Generation

In a shocking turn of events, I actually finished this week's tutorial segment last night! This means that I was done a full day early, and I've opted to post the new segment this morning before I head to work.

The trick this time was starting early. I finished the followup last weekend, then did half of the work on Saturday and the rest on Sunday. I'm pretty sure that if I keep to this formula, then I should be able to keep up with the schedule without causing myself too much stress.

As for the contents, I'm continuing my policy of "give the reader some fun stuff early on" by sharing a couple simple random generation algorithms. In my old plan for the tutorial, this probably wouldn't have happened until part 6 or 7 (we're on part 4), so I think this was a good move. I'm also trying to get through things quickly because (as I said before) I'm still not 100% happy with this tutorial and would like to get it out of the way so that I can focus on making better-planned tutorials in the future.

Lastly, I wanted to say that I'm going to try and revive the old one post a week policy from my college days. I've actually been working pretty hard on a couple of interesting projects lately, so this will give me an opportunity to share them on non-tutorial weeks. I'm painfully aware of the fact that the tutorial is the only thing I've written about this year and it's nearly March.

Anyways, you can click here to read the latest part.

2/14/17

Let's Make a Roguelike: Fashionably Late

Had you worried, didn't I?

I almost had this weeks segment done last night, but I was quite tired and decided to put it off. That was apparently a good decision, since I put several hours into it today before wrapping up! This was mostly poor time management on my part, but I'm happy that the delay was small this time.

As for the content, I'm trying to accelerate the early bits a bit more than in my previous iterations. Even for a long-running series, it's important to keep the readers engaged, and the shape drawing from last time didn't seem up to snuff. I'm taking a bit of a write once, refactor later approach this time: I present the technique in a fairly simple and "bad" way first, then show how the implementation can be refined and improved later. This allows me to frontload much of the exciting stuff, while still providing some basic design lessons down the line. We'll see how that goes.

This series has really been a bit of an interesting experiment for me. There are so many things wrong with my approach to writing these that I almost want to start fresh again, but for the sake of actually getting things done I'm resisting that urge. I think this series is helping me learn a lot about tutorials though, and future seasons will benefit from those lessons.

Here's the link to the new part.

1/30/17

Let's Make a Roguelike: Back Again!

It's done!

If you've been watching the blog, you'll know that I've had some fun these past few weeks. That's been dealt with, and I can finally release the next part of my tutorial series. You can read it here.

For those of you who don't care for tutorials, but are curious about the demo that I was making, here are some links:

Windows build
Source code

It may look a tad underwhelming, but being able to distribute builds to platforms other than my own is an important first step. Now that that's been dealt with, I think things will be going much more smoothly from here on out. Keep watching this space for more updates as they come!

1/24/17

The Delay Continues, and I Explain it

As the title implies, I'm pushing last week's tutorial back another week. I realize that all of these unexplained delays make me look a bit lazy, so I'm going to give you a proper explanation of why this one "almost finished" tutorial segment is taking so long to be released, and why I've spent the last few days pulling my hair out.

Last Monday, I was mostly done with the tutorial. To demonstrate various features of curses, I made a nice little demo application. The code was still a little bit messy, but I figured that as long as I could compile a Windows version of the demo, I wouldn't have any problems.

Unfortunately, there was a small problem. I'm not sure if I've mentioned it here, but I started using Meson for builds instead of writing makefiles. This is good, because Meson works very well. However, I'd never actually tried cross-compiling code with it before, and I was having issues setting it up. In light of this, I pushed the tutorial back so that I would have some time to fix the issue and clean up the code.

Fast-forward to this weekend, when I finally have the time to sit down and figure out my problem. I got the Windows version to compile through Meson, but it would just crash immediately. I spent almost the entirety of my weekend trying various versions of PDCurses and messing with the code, until I finally tried making a stripped-down "hello world" and moving it over to my Windows machine for testing. I should also mention that due to certain circumstances, moving things to my Windows machine takes 5-10 minutes. It's a pain, but I'm working to resolve this over the next week or so.

Anyway, it's at this point that I realize that the PDCurses library really hates cross-compiling. The code is fine, and I manage to get it working by compiling it on my Windows machine. (This seems to be an issue specific to PDCurses. I've had tons of issues like this, but only when using that specific library)

On Monday (yesterday), I've figured out the problem but I still don't actually have a Windows build of the demo. Monday afternoon (after work), I realize that at some point, my fiddling has broken the demo completely on my PC, and it won't work on Linux anymore! Fixing this bug took 3 hours, because it was caused by an innocuous-looking include statement in a random header file.

After dinner I finally transfer my code over to make a Windows build. I set everything up in Code::Blocks for building, get a compiler error, open the relevant file, and Code::Blocks crashes. When I reopen the project, everything is gone. I repeat that song and dance a couple times, and it finally works. Still, the editor is stuttering a ton and making my life a pain.

I finally get the code to build, run it, and...it doesn't work. Fast-forward another 15-30 minutes, and I figure out that the window isn't resizing to fit the content, which screws everything up. When I shrink the content as a test, I come to the horrible realization that my program isn't drawing to an SDL window, it's drawing to the Windows command prompt! I HAD THE WRONG VERSION OF PDCURSES INSTALLED THE WHOLE TIME!

It's 11:00 PM at this point. I now have a Windows build, but it looks like this:

For reference, the build is supposed to look something like this, more or less:
It's at this point that I finally decide to cut my losses and delay things again. It's super late, I'm exhausted, I still don't have an acceptable Windows port, and the code is still not cleaned up, thanks to all of the delays.

So, that's the end of my tale. I'm pretty sure a less stubborn programmer would've simply given up at this point, but that's not my style. I'm going to try and get things sorted out for next week, and I think it'll be fine now that I'm aware of the issues. However, if I can't finish next week, delay again, and still can't finish it by February 6th, I'm putting the project back on hiatus and making a different tutorial series. I've lost a ton of time to some really silly and unexpected issues, and I can't afford to keep slamming my face into a wall forever.

In unrelated news, my personal projects have all been approved. You can expect some more posts about those once this stupid thing is dealt with.

1/16/17

A Small Delay

I've just about finished writing this week's tutorial, but I'm delaying its release until next Monday. While the text and most of the code is done, I'm having some issues getting the build to work nicely in a cross-platform manner. This is mostly due to my inexperience with Meson and some recent factors that temporarily reduced my free time.

Personally, I think it's more important to have this tutorial feel polished and complete than to hit every single deadline perfectly. It's still unfortunate that I have to push things back (especially this early on), but I think this is better than just throwing out something half-baked.

On the upside, once these issues are dealt with I'm unlikely to have to deal with them again, even in future projects and tutorials. I'm still in the process of feeling things out, as far as tutorials are concerned, so figuring things like this out early on is good. With that said, I'm probably going to try to complete future tutorial series before I start posting them, just to ensure that they don't get delayed.

1/2/17

Let's Make a Roguelike - Prep Work

Two weeks after uploading the first part, I've managed to keep to my schedule with a new one. With any luck, I'll keep this up!

This part started out as a lightly-edited version of the old part 1. However, I wasn't happy with it. Today, I sat down and rewrote the whole thing, and I'm very happy with the result. It's likely that I'll be deviating from the old tutorial quite a bit going forward.

So, what can I say about this new part? I mostly shifted the subject away from the limitations of curses, and more towards an explanation of the options that are available and what I plan to cover. I think the result is well-structured, and has a much better flow than the old part 1. It still has no images, since there isn't much to show, but I've got plans for part 2 that I'm hoping will help out a bit.

The other major change affects the tutorial series overall. I'm moving the tutorials away from ncurses, and focusing on the SDL version of PDCurses. I'm hoping that the narrow scope combined with better cross-platform support will make this series much more helpful. Using Meson for builds will likely help as well.