Jump to content

  • Log In with Google      Sign In   
  • Create Account

etodd makes games

Screenshot Saturday 211

Posted by , 13 February 2015 - - - - - - · 1,294 views

Last Saturday we had the Short North gallery hop. Hundreds of people came through our gallery to see art. The guys helped me set up the Oculus and a projector on the wall.

Sometimes I had to go out and pull people in, but most of the time, there was a line. My favorite customer by far was this kid:

Posted Image
He jumped right in and played like a pro. The mother (recording video) was super supportive and excited.

At past expos, I dropped players into a bespoke demo level that skipped a lot of story and jumped straight into the tutorial. In December, I revamped the "real" first level (called "Rain") to be more like the demo level. If your game can't entertain people in two minutes at an expo, what's going to keep them playing if they buy the game?

After the gallery hop, I checked my Git logs. "Rain" was present in the game without a major overhaul for the past two years. I rebuilt every other level. Time to throw Rain in the trash.

For something that has received constant attention and iteration for two years, I was surprised how quickly I replaced it. Here's Rain 2.0:

Posted Image
It accomplishes all the same goals, teaches the same mechanics, and introduces the same (optional) story elements, but it's much more simple, streamlined, and just fun.

Rain 1.0 was the first level I ever made. At that stage I didn't entirely know what the game was. I had no level design vocabulary. I didn't even know how big the level should be or where it fit into the overall experience. I patched those details in later.

For Rain 2.0, I knew every goal from the start. I made decisions easily by asking which option best fit those goals. For once, my design tasks aligned in the correct order. As a result, I replaced two years of iteration in a single long work day.

Of course it's not perfect. Playtesting and iteration will reveal potential improvements, but it's already miles ahead of the old level. As a side note, here's a fun glitch I discovered during the redesign:

Posted Image

But that's not all! Oh no, that was just Monday. I built another level in the "aqua" biome, bringing the count to 18 out of 20.

Posted Image
One more aqua level, then the ending level, and it's a wrap. The rest of development will be tweaking, polishing, and bugfixing, which at least for me is much easier than pulling creative content out of thin air. Hang in there. Thanks for reading!

Mirrored on my blog

Screenshot Saturday 210

Posted by , 06 February 2015 - - - - - - · 1,446 views

I finished last week's map. It has some spinny things.

Posted Image

Then I made this week's map.

Posted Image

Posted Image

Who knew purple and green could look so... not terrible?

Anyway, this puts me ahead of schedule. There are three levels remaining. My goal is to for the game to be playable from start to finish by the end of February. It's ambitious, but I'm confident I can do it!

Today I took a break from level design to do some hardcore coding for the first time in a while. It was a breath of fresh air, which definitely reinforces the realization that I'm a programmer first and foremost. I optimized a ton of stuff, cut the level data size in half, and killed a metric crap-ton of memory leaks, but I'm way too tired to write about it right now. Maybe later!

That's it for this week. Thanks for reading.

Mirrored on my blog

Screenshot Saturday 209

Posted by , 30 January 2015 - - - - - - · 1,280 views

This week was crazy productive. I finished last week's level, finished another level, which looks like this:

Posted Image

...which also included some story-related writing and scripting, and actually started working on NEXT week's level, which looks like this:

Posted Image
I seem to be on a purple streak lately. Actually, purple may rise unintentionally to be the most prominent color in the game. Also, this last level is apparently a subconscious ode to Monument Valley.

Amidst all this I'm constantly tweaking and fixing things, which isn't particularly exciting. However, this week did bring one interesting story: a playtester reported their graphics card overheated. Apparently, the poorly designed card couldn't run at 100% utilization for any significant stretch of time.

The playtester asked for a framerate limiting feature to prevent the card overheating. So now, I cap framerate at 120 FPS, a number which is adjustable via a slider in the options menu. Details like this take up an increasingly large proportion of development time as the project nears completion.

That's it for this week. Thanks for reading!

Mirrored on my blog

Achilles + Screenshot Saturday 208

Posted by , 23 January 2015 - - - - - - · 1,192 views

This past weekend I participated in the CivicHacks "Game Jam for Good". The goal was to raise awareness of the global water crisis and ultimately promote PackH2O, a Columbus-based startup that designs water backpacks for developing water-stressed regions.

The jam lasted 48 hours. My entry is called "Achilles".

Posted Image

Achilles is a multiplayer text-based simulation. You the player must manage a village in a third-world country experiencing a water crisis. You can play it here (bit.ly/waterjamachilles) assuming I haven't stopped paying for the cloud server.

It's incredibly depressing. Really, only bad things can happen. I had plans to add pregnancy and childbirth, but ran out of time. Here's a video of it in action:

The core idea was this: to convince people of the effectiveness of the PackH2O backpack, a promotional game should put players in the shoes of the people who will use it. And I think I accomplished that. In the game, the backpack allows people to carry twice as much water. The player experiences first-hand through gameplay how useful the backpack is.

Despite the game's inherent awfulness, it won an "honorable mention", which actually turned out to be good for a $500 gift card. Posted Image You can check out the other winning games on the CivicHacks website.

On the backend, I wrote Achilles in Python using Flask as a web server framework (highly recommended).
I used gevent for greenlets, which made it very easy to write time-based procedures for each character. For example, here's how a man builds a hut:
if village['build_material'] > 0:
    village['build_material'] -= 1
    notify(world, village['id'])
    state['state'] = 'building'
    notify(world, man['id'])
    gevent.sleep(world_seconds(world, 60 * 60 * 17))
    village['huts'] += 1
    notify(world, village['id'])
    man['state'] = None
    notify(world, man['id'])
    send(village['id'], { 'event': '{0} finished building a hut.'.format(man['name']) })
    send(village['id'], { 'event': 'Not enough build material for a hut.' })
The "notify" and "send" functions send JSON objects to the relevant clients over WebSockets.
On the frontend, I only used jQuery (no plugins) and Mustache.js for templating.
If you're interested, check out the code here on Github.

Compression-based programming
I used this game jam as an opportunity to try out compression-based programming as advocated by the excellent Casey Muratori. The idea is, instead of spending time upfront designing a complex cathedral-like architecture, you should write straightforward, ugly, even repetitive code (copying and pasting). When it's done, you go back and "compress" the code into something nicer via refactoring.
Of course, some things are straightforward enough that you can compress them as you go. For example I always knew there would be a "send" function.
Casey says one of the big problems with "normal" programming is that you assume you know everything at the beginning of a project, when in reality, you often don't. Compression-based programming has you architecting things only after you've seen the whole picture.
After a weekend of experimentation, I think this pattern of coding results in plain, boring, easy to understand code, which is definitely a good thing. Normally I come up with some super fancy way to write everything very elegantly, which creates more work than it's worth in the end.
Another paradigm Casey rails against is object-oriented programming, so I also tried writing everything procedurally. The result was again boring but simple and easy.
The biggest win was separating state from behavior. On both the client and server, all the state lived in a single object, parts of which were operated on by various procedures.
Normally, I often link state and behavior so closely that they're impossible to separate. Every time I write a closure (probably my favorite bad habit), I squirrel away an opaque bit of state inextricably tied to an anonymous bit of behavior.
Time to wrap this up: you should try coding in a boring, straightforward, state-separated-from-behavior, procedural style. The result is a breath of fresh air in a world of increasingly clever object models and cathedral architectures.

Screenshot Saturday 208

This week's level is not quite done yet, but I have an excuse! Power was out at the incubator for two days, and the internet didn't come up fully until just yesterday.

Still, the level should be done some time this weekend and is already looking pretty good.

Posted Image

I finalized the promotional graphics and published the game to Steam in "coming soon" mode. I'm incredibly grateful to Sam Gebhardt for contributing his Hollywood artistic talent!

Posted Image
I updated the website to feature Sam's artwork and shot a brand new trailer:

The 5 second cuts didn't turn out to be as good of an idea as I hoped, but it works for now.

Progress continues. Lord willing I will finish this game with or without power!

Mirrored on my blog: Achilles

Mirrored on my blog: Screenshot Saturday 208

Screenshot Saturday 207

Posted by , 16 January 2015 - - - - - - · 1,108 views

Records continue to be broken. This week's map was actually done on Wednesday!

Although most of Lemma is a strange hybrid of natural and alien-looking architecture, my design calls for a few "industrial / man-made" themed maps. For story reasons, and also because I just want to parkour through a skyscraper.

So on Monday I asked Twitter this question:

Would people be upset if I do a few levels in the visual style of Mirror's Edge? Would that be tribute or rip-off?

Answers varied, but unfortunately I had already started working on it, and it turned out so awesome that I had to keep going. At this point I don't care if people think it's a rip-off.

Posted Image

Posted Image

Posted Image

Reinforcing the notion that 90% of my dev time is spent picking colors, I also revamped the skybox on Valley.

Posted Image

Some friends at imaekgames recommended that I get the Steam page for Lemma up as soon as possible to ensure a spot in the "Coming Soon" list, so I started crafting some assets:

Posted Image

Currently working with an artist to redesign the main capsule (top left), but I'm pretty happy with the other assets. Here's what the page looks like so far:


So yeah, crazy busy. This game might actually get done on time.

That's it for this week, thanks for reading!

Mirrored on my blog

Screenshot Saturday 206

Posted by , 09 January 2015 - - - - - - · 1,048 views

I moved my office into an incubator / art gallery this week.

Posted Image
The move is mostly for my own sanity. Turns out, working alone in your apartment for 9 months isn't the most fun in the world. It's a Herculean effort just to stay motivated. I also lost all semblance of a disciplined sleep schedule.

Productivity has been great since the move, and I'm back on a normal sleep schedule. Having people around is great, even if I mostly tune them out to focus on work (sorry guys).

In keeping with the production schedule, I finished the last frost level today. Unfortunately its massive size doesn't lend itself too well to screenshots. I tried my best:

Posted Image
I also completed the dialogue and cutscene for the first major player decision in the story. Sorry, no screenshots. It isn't much to brag about, but spoilers are spoilers.

Lastly, I updated the visuals for the movement prediction / block creation mechanic. Someone pointed out a while back that the old visuals made it difficult to distinguish overlapping shapes. Here's how it used to look (I always love sneering at old screenshots):

Posted Image
And here's the new effect with edge highlights:

Posted Image
I could have used a texture, but I ended up doing it in the shader based on UV coordinates:
const float radius = 0.15f;
float2 diff = float2(min(max(uv.x, radius), 1.0f - radius), min(max(uv.y, radius), 1.0f - radius)) - uv;
float highlight = 0.6f + (5.0f * (diff.x * diff.x + diff.y * diff.y) / radius);
I seem to recall reading a way to do it with only arithmetic primitives, but I couldn't remember it or figure it out.

A bunch of other stuff also happened that I won't bother listing. If you are for some reason interested in nitty gritty details, the Steam beta tester group has extensive changelogs.

That's it for this week! Thanks for reading.

Mirrored on my blog

Screenshot Saturday 205

Posted by , 02 January 2015 - - - - - - · 867 views

For the first time in the history of Lemma, I'm actually keeping up with my self-assigned pace of one new level per week.

These past two weeks I made two more frost levels. The plan calls for one more frost level, then it's on to the other two biomes.

Clicky for giffy

Posted Image
Both of these levels have interesting quirks and unique features. They're probably too tough right now, but I'm scheduling plenty of time to playtest and sand down the sharp edges.

For me, the biggest challenge is to start with a blank slate and form new shapes out of nothing. It's much easier to playtest an existing design and think of ways to improve it. So I'm getting all the hard work out of the way first.

As I build these levels I finally get to implement story elements which have languished on the drawing board until now. I already have code for very simple cutscenes, and one of the five endings is basically done already.

Posted Image

I continue to solve old, long-standing gameplay annoyances.

Normally in Lemma, you can build floors by rolling or sliding off an edge, causing a blue platform to appear beneath you.

Posted Image

The problem is, you can spam this move and build an infinitely long blue platform. I originally prevented this with a strict rule: you can't build a platform if you're already standing on a blue surface. This rule gets the job done, but it's clunky, unintuitive, and difficult to explain to players.

I thought about another bothersome exploit that used to plague Lemma. In older versions, you could get in a corner and climb up indefinitely by jumping between the two perpendicular walls. The clunky solution was to nerf the wall-jump, which was admittedly ridiculous. But the over-powered wall-jump was fun.

Posted Image

So I kept the crazy wall-jump and wrote code to specifically detect the corner case (ha). I kept a running counter of spammy corner jumps. After a certain number, it disables wall-jumping in that area.

Now, the proper solution is to design a game with mechanics so elegant and simple that this whole situation never arises in the first place. But it's way too late for me to do that now, so we're stuck with this. Surprisingly, it doesn't bother people at all. Experienced gamers immediately try to exploit the wall-jump, see that it doesn't work, and move on. The rest of the game is unaffected, and I can keep my insane OP wall-jump.

Given the success of this exploit patch, I decided to do something similar to fix the issue with building floors. Now, when you try to build a floor on a blue surface, I do a breadth-first search to find solid ground. You can build on blue surfaces as long as you don't stray too far from solid ground.

Just like the wall-jump, the code is actually much more complicated now, but it boils down to this: you can always build floors unless you're trying to exploit.

And now for some random technical oddities. First, a quick tip if you're developing a game from scratch on Windows: make sure to handle DPI scaling properly. Lemma boots in fullscreen borderless window mode, and if the DPI scale setting is above 100%, Windows automatically scales the entire game window, which pushes most of it offscreen.

Here's a Gist that features an app manifest which will disable auto DPI scaling for your game.

In other news, I stumbled on the TextBelt library this week, which allows you to send SMS messages from a server for free. It's a Node project, but the concept is simple enough to easily replicate in your server framework of choice: blast emails to every single mobile provider gateway, knowing that only one provider owns the phone number and will allow the message through.

I imagine it would be fairly easy to optimize if the gateways send back email errors. At any rate, I'm tempted to take a weekend, write a fun SMS-based party game using this library, and try it out on some friends.

That's it for this week! Thanks for reading.

Mirrored on my blog

Screenshot Saturday 203

Posted by , 19 December 2014 - - - - - - · 1,144 views

Big update this week!

My voxel renderer now has the capability to overlay everything with any texture I want. I'm using it on a new set of interconnected winter levels. This way I don't have to manually come up with a frosty version of each texture.

Posted Image

Without giving away too much, this week I built a new system that has implications for both puzzle solving and movement mechanics.

Posted Image

I also went back to several levels and fiddled with lighting again. Basically 90% of my development time is spent adjusting colors. Before / after:

Posted Image

Clearly, the old version relied heavily on bloom. I'm trying to avoid that a bit more now. Bloom is like crack cocaine to game developers.

Other random things:
  • When you walk off an edge, there is now a split second of forgiveness during which you can still jump. Just filing down another edge to make player movement less frustrating.
  • I finally killed an old glitch that subconciously annoyed me for years. Lemma has "bullet time", and up until this week it stuttered noticeably when running in slow-motion, despite maintaining a high framerate. I peeked into the BEPUPhysics source code and realized it runs on a fixed timestep with an accumulator. It updates at 60 FPS regardless of the actual framerate. So when I changed the time scale, that 60 FPS dropped to 30 FPS. But no more! I now scale BEPUPhysics' target framerate as well, and the result is silky smooth slow motion.
  • I liked using Jekyll for my blog so much, I also migrated the Lemma website, and updated it in the process. The site was already hosted on S3 so half the work was already done.
That's it for this week. Thanks for reading!

Mirrored on my blog

Screenshot Saturday 202

Posted by , 12 December 2014 - - - - - - · 1,129 views

I've come to several realizations this week.
  • Lemma is going to be good, but not great. I have to accept my limitations and finish the thing to the best of my ability.
  • Lemma is more of an experience than a traditional video game.
With these two ideas in mind, I am focusing the next few months on making Lemma the least frustrating, most enjoyable experience I can.

So I'm trying to come up with puzzles that seem difficult but are actually simple to solve. The wonderful Monument Valley did a great job of this.

Posted Image

Fun fact: that's actually a public domain composite image of the dark side of the moon. I wrote a custom "sky decal" shader to paste it up there while still cooperating with the distance fog.

Posted Image

I kind of want to live there.

So that's where I'm at. I've been stressing a lot lately but I think I can actually finish the game in April. Whether I think I can or not... I have to.

That's it for this week. Thanks for reading!

Mirrored on my blog

New blog, new app, new screens

Posted by , 05 December 2014 - - - - - - · 1,498 views

Lots of stuff going on this week.

New dev blog

First off, my website got a much-needed overhaul. The horrible slowness of Wordpress.com was driving me nuts, so I switched to a custom-built site.
I used Jekyll, which is a static site generator. It spits out a bunch of HTML files which you can upload to a server, as opposed to Wordpress, which generates fresh HTML every time someone loads your page.
  • Absolute control. You can customize the site theme without dealing with mountains of horrible PHP. And I can finally post HTML5 videos.
  • You can host your website on Amazon S3, which is about 50 cents per month, 10x faster than a normal server, and pretty much guaranteed to never go down. Wordpress absolutely crawls in comparison.
  • Perfect for coders, because you can write articles in raw HTML or Markdown in your favorite text editor, and you can track your site in a Git repository.
  • No easy way to offer email subscriptions to readers. RSS is easy to set up though.
  • Jekyll is written in Ruby and thus has a bunch of annoying dependencies to install. Still, the whole process is definitely easier than setting up a fresh Wordpress install.
Migrating the comments to Disqus was super easy. I use s3_website to deploy the site to S3. It only updates diff'd files, so it only takes a few seconds in most cases.
Overall I recommend it if you're a coder.

New app

I got hired this summer to do a mobile game as part of a franchise tie-in. The game is finally out today for free on Android.
Here's some (raw, uncut) gameplay footage:

grepr patch

grepr has garnered a modest but promising amount of attention. Most notably, iDubbbzTV had some great things to say about it. (warning: language)

I mostly agreed with his bigger complaints, so I made a few tweaks:
  • The terminal menu is now more simple and straightforward to operate
  • The enemy AWK drone is now larger and easier to spot
  • The third level, where the enemy AWK first appears, is now greatly simplified
  • Some glitchiness pertaining to the data node collision volume is now fixed
More importantly, the game now runs on Linux! It's 64-bit only at the moment, but everything seems to run just fine. If the game glitches on you, make sure you have libsdl2-2.0.0 installed.

New screens

Amidst all this craziness you might think I've abandoned Lemma. And you'd be wrong. Here are some fresh new screens:
Posted Image

Posted Image

I also fleshed out a whole ton of writing:
Posted Image
So yeah, lots of stuff happening. Stay tuned.
That's it for this week. Thanks for reading!
Mirrored on my blog

August 2016 »

28 293031