GIFs FTW

It was time to get cutscenes playing in the game. I did some research on free software codecs, licenses, etc.. I tried converting our cutscene from animated gif into an ogg-theora file… and it looked awful. Sure, I could have turned up the quality settings, and then the artifacts would not have been as visible, but it got me thinking: I wonder if there's a video format that does lossless compression, and is optimized for large solid areas, and possibly low color palettes. You know, something for video, like what PNG and GIFs do for images… wait… GIFs!

Seriously? Is it really a good idea to use GIFs in the game?

I don't particularly like gifs. First they were used to make most of the internet annoying (if you weren't surfing the internet over dialup in the 1990s… you didn't miss much), then random people were getting sued for patent infringement… but all the patents have expired, and there's a nice free library (very old, and sill maintained) that makes it really easy to open up GIFs, and get at the frames, palettes, etc.

So I incorporated giflib into the project, wrote some code to convert between the data structures you get from giflib and those that SDL2 needs, and voilà! We have cutscene (singular at this point) in the game!

Yay!

But wait, now that we have GIF support, can we use it for sprites in the game too? Answer: yes!

A bit more code later (and some preprocessing, so I don't have to support every GIF feature) and we've got a lively little talking goblin head in the game.

My GIF code has two modes:

  1. Movie: everything is opaque, supports partial-screen updates (great for the little camp fire in the main menu background)

  2. Sprite: supports transparency, and efficient access to frames in any order

The game is starting to look pretty slick! The GIF gameplay video last post is fun, but doesn't quite do the game justice, since it is short, low res and low frame rate.

One of these days, I'll have to do a real gameplay video, including the menu, cutscene, etc. at high resolution and a good frame rate. Hopefully we can make something like that look good on youtube or vimeo or something.

I've got an initial draft of a new "feature" code-named PainCloud. It's a pulsating red area that wanders about your brain obscuring your thoughts. You'll get these if you're injured… I think. You can get rid of them by clicking on them, but then your goblin audibly groans, which isn't great for rapport (and makes your thoughts wobbly for a bit).

Today I changed the way the code creates links to new thought bubbles. Now, instead of creating all the links right away when you move, there's a checkup that runs regularly and creates new links/thoughts as needed. This paves the way for us to add new effects that destroy thought bubbles, and the code will automatically add things back in if needed, so you don't get stranded.

Gameplay Video

Well, so much for weekly coding updates… but now you get updates when I have something cool to say/share…

And I do :)

I’ve added some code to make the game run at a fixed frame rate and export screenshots at regular intervals.

Then a script to cram most of those into an animated gif… in other words…

Our First Gameplay Video!

Gameplay 01

In this video you see the main game mechanic of scrambling to find a word to finish a sentence while a human is occasionally shouting at you.

You can see some stuff that might be more-or-less finished, like the way the thought bubbles move/look, and some stuff that needs a lot of work, like the spreading red (caused by my characters phobia of sheep) which needs to be way more panic-y and be more obviously chasing you down.

Weekly Coding Update #21

This week I fixed a fluke where you could get stuck on a thought bubble with no links. I fixed it just for this particular case (mind-blank when on a node that doesn’t have any natural links.) But it got me thinking that I should implement a more general solution where links are added periodically if there aren’t many of them.

I met with Evan, with this fresh in my mind, and we discussed some fun effects we can do, that will be much better if they can destroy thought bubbles without worrying about stranding the player. There’s some fun stuff coming!

It seemed about jolly time I implemented an effect that’s not just more/fewer thought bubbles, so I started on the pain/injured effect. This is pulsating clouds that drift by in the foreground, obscuring parts of the web. I wasted some time debugging a couple typos, and needed a nap, so it’s not screenshot-worthy yet.

Weekly Coding Update #20

I spent most of my time this week on frame rate. First, I switched to API calls that give me sub-millisecond timing information (nanoseconds on my computer, but YMMV.) Then I changed the algorithm for calculating the frame rate (now I’m finding the average time for all the frames in the last second).

I audited the code for limiting the frame rate. This code was supposed to stop the frame rate from going over 60fps, but was sometimes also slowing it down below that unnecessarily.

I updated the conversation scripting capabilities, and updated our placeholder script so you get a speech bubble with the word you find (if you find it in time.)

I incorporated new art from Evan: the main menu background, and the graphic for the pause menu.

You can see the frame rate indicator, the new speech bubble and the pause menu in the screenshot below:

screenshot

Weekly Coding Update #18-19

Had deadline rush last week (#18) so no progress then.

This week I updated to the latest (release) version of duktape, the minimal, embeddable javascript engine I’m using for the game logic.

Then I build a frame rate counter/display into the game. Then I ran all kinds of tests on the code to see what was slow.

My conclusion: javascript is running slow. I read up on how to get duktape to run faster, and the answer was that they haven’t gotten to optimizing yet, and plan to do that starting Spring 2015 (ie now.)

So, with luck they’ll speed up code execution considerably before we’re ready to release Goblin Diplomat, and I won’t have to do anything. If the javascript is still too slow as we’re approaching our release date, I’ll have to switch to a different javascript engine.

In other news, Evan made awesome art for the pause screen. I hope to get that into the game, and into a screenshot in next week’s update.

Weekly Coding Update #17

Now you can pause the game! This involved changing the way everything looks so it’s a bit grayed out, and hiding the words (no fair browsing through the thought bubbles while paused.) As you can see I’m using a placeholder graphic for the pause menu:

Gameplay Screenshot #04

I also beefed up the keyboard event handling, so I can be notified of any key press (before you had to list the keys you wanted to hear about.) It checks for specific key handlers first, so, as you can see in the screenshot, I can register to be notified of “any other key”.

On a much less interesting note, I ripped out the rest of the old code for the “conversation progress bar” that we used in early development. Now all time limits come from script, and are managed by the conversation engine and/or the brain. Yes, there’s a class called Brain :)

Aaand… one more bugfix. A little syntax error in the timers made it so it’d crash if you tried cancel one. I think that’s the last of the occasional crashes at/near the end of the game.

Weekly Coding Update #15-16

#15: Had a big big work deadline last week, so no no progress that week.

#16:…

This week I reworked the way links work. I added a fourth bubble, which looks a little cooler, but mainly fixes the issues I was having where there would sometimes be an awkward gap at one end or the other. I tweaked the canonical location of each bubble, and the timing at which they appear, the way the move, and made them grow/shrink semi-randomly over time.

I also finished (for now) the “infection” effect, which turns everything red. This work was mainly making it so the link could turn red from either end, and making sure the red starts at the correct end.

Weekly Coding Update #14

Slow week this week due to low energy, and a leaky foundation (yay almost spring!)

I did manage to finally track down a bug that’s been making the game crash occasionally (usually right at game-over.) Turns out there was a bug in the javascript interpreter, not my code. Guess it serves me right for running git master (of the interpreter) from a year ago and never updating.

I also made it so that code can be notified of a “click anywhere”, and used that to make it so you can skip the parallax scene with the mouse, if you’ve already seen it a bazillion times.

I also started creating another of the mind effects: “Infection”. In this effect, thoughts turn a dangerous red, then the red spreads to nearby/connected thoughts. I’m at a rather goofy problem: when fading (from white) to red, right in the middle is pink… not what we’re going for. I’ll have to figure out a more complex way of fading the color so it goes to grey first, or maybe a dirty yellow.

Weekly Coding Update #13

This week I rewrote most of the Paralax (scrolling scenery) code again. This time, I think I finally got it right, and I added some nice new features, like being able to scale the layers independently, and also have the sky move at a constant rate, while the other layers can pause, move, etc. I scripted a nice sequence of fade in, move, fade out. This sequence plays between the main menu and gameplay.

Speaking of the main menu, I finally got a proper image on the main menu, so you can see the name of the game and everything :)

Then I did a bunch of research on what video decoding library I should use to play cutscenes. I only need support for one codec, and I’m not all that picky about which one, since we’ll be pre-processing all the videos anyway. My priorities with the codec are that it works well, and that it will be easy to add to my cross-compiling for windows. I’m using MXE for cross-compiling for windows, so I went through the list of MXE packages, and found three candidates: ffmpeg, xvid and theora. ffmpeg seems a little overkill, and there’s been problems in the past with ffmpeg changing their API frequently (we had to do a lot of extra work on cmus to deal with compatibility with different ffmpeg versions.) It was a bit of a toss-up between theora and xvid. I’m trying theora first, because they have API documentation on their website.

Weekly Coding Update #12

This week I replaced the old code that arranged the links, and set their angles. It served well for a time, but it wasn’t able to deal very well with links being removed, or new links being added later. The new code arranges links randomly at first, and then has nearby nodes repel each other so that they make space where needed.

After some amusing/wild bugs, I got this code working nicely. When I went to test it I was surprised how hard it was to focus on the nodes adjusting their positions. It’s so good that fades into the foreground. I feel like I hit that weird rule of design, that goes something like “When it’s designed really well, you don’t think about the design”.