November 14, 2016

Designing a Pixel Art Character in 10kB

Categories: 
Published: 14 November 2016 

Back in mid August, one of my friends sent me a link to the 10k Apart contest announcement. How do you build something in as small as 10kB? And the core experience has to work without JavaScript. Challenging limitations can be fun to work inside, because you have very clear boundaries and it forces you to be creative. So this is the process I went through to set about making my project!

What to make?

I was immediately interested, because I love CSS (and a good challenge). But I had absolutely NO idea what to make. I took a few days to think about it and scribbled some thoughts in my notebook.

10kb-initial-sketches

One of the things I've enjoyed building in my spare time over the last few years is dress-up games. Was it possible to make one of those? Without JavaScript? Maybe? YES.

I could use the checkbox hack. It's a hack, but it would work to toggle the clothing choices. Using a form for the elements would also mean the clothing choices could easily be sent to the server for processing to flatten the items into a single image. No JS necessary!

Creating the Sprites

The main challenge I knew I would be facing would be keeping all the image assets within the budget requirements. I settled on the idea of using pixel art and had some very vague idea of a style. By carefully choosing a style, budgeting a couple of kBs for a sprite and using the rest for the markup and CSS, it seemed somewhat possible.

Here's a couple of the early concepts that were heavily stylised:

10kb-pixel-art-concepts

Very quickly, it became obvious that the style would have to be severely limited. Pixel art is perfect for this, because it's traditionally limited in colour and size. The sprites could be tiny, up-scaled and it would still work stylistically.

After going back to the drawing board (Photoshop), I drew a few of my team mates (they were perfect guinea pigs for this, thanks guys!).

10kb-sprites

This style suited much better. It's fairly generic, so the same base body could be used for different genders and with most of the detail removed, the file size would be small. Win win!

After building a quick HTML prototype, the concept was working. Time to move to PHP and Sass - because honestly, who likes repetitively copying things?

10kB, is tiny.

The interesting thing with moving to Sass and PHP is that it makes it much easier to build out your markup. It also means it's easy to bloat said markup. Running into the issue of your markup being larger than your CSS and images COMBINED, is something I can honestly say I've never encountered before (╯°□°)╯︵ ┻━┻.

So, the task began of paring down the markup to include only what was necessary. CSS classnames were also pared down to be teeny tiny. Text styling classes were prefixed with t- and all the prop types were shortened to two character name prefixes. Anything that was single purpose was made into an ID, because this could double as a #target to switch between 'views' or 'screens'.

public function render_item( $item, $itemnum, $legend, $selected ) {

    $type = $this-">shorten_css_class_name( $legend );

    echo '<input id="' . $type . '-' . $itemnum . '" name="' . $type . '" type="radio" value="' . $itemnum . '">';
    echo '<label for="' . $type . '-' . $itemnum . '">' . $item[ 'name' ] . '</label>';

}

The result was just under 10kB, but there were only a few props, which was pretty limiting for creating a character. And up-scaling pixel art in Internet Explorer looked TERRIBLE, because I wasn't able to set nearest-neighbour interpolation. Wonderful. What about SVG? That scales nicely!

6.68kB. Darn. That doesn't fit the budget.

At this point, it was looking pretty grim. The markup had been cut down as much as possible, the CSS was pretty lean, there were only a few props. What to do? Oh right, GZIP. Oops.

GZIP to the rescue!

Moving back to using an up-scaled PNG image that would display relatively nicely in Internet Explorer, with GZIP enabled brought the whole filesize down to just over 5kB. YES! More props were made and the design of the splash screen was considered and quickly mocked up in Photoshop.

10kb-pixel-art-hero

At this point, the project was working and mostly complete. With many bytes to spare! I showed a few people how it was going and one of the suggestions was to add a small animation when changing clothes. It's subtle, but adds just a little bit of fun.

10kb-clothing-transition

The result?

10kb-requests

The final project outputs just over 8.1kB and the character sprites can be saved, which is all handled through PHP. And I won the Best Design Award!

It was SO much fun to build something with such clear limitations, combining several of my outside-of-work hobbies. And while several issues came up during the course of the project, each one of these was able to be overcome.

10kb-screenshot-maker


Get it on Github

If you want to check out the code for yourself, you can view the code and assets for the project on Github.

Get the code!

Back in mid August, one of my friends sent me a link to the 10k Apart contest announcement. How do you build something in as small as 10kB? And the core experience has to work without JavaScript. Challenging limitations can be fun to work inside, because you have very clear boundaries and it forces you to be creative. So this is the process I went through to set about making my project!

What to make?

I was immediately interested, because I love CSS (and a good challenge). But I had absolutely NO idea what to make. I took a few days to think about it and scribbled some thoughts in my notebook.

10kb-initial-sketches

One of the things I've enjoyed building in my spare time over the last few years is dress-up games. Was it possible to make one of those? Without JavaScript? Maybe? YES.

I could use the checkbox hack. It's a hack, but it would work to toggle the clothing choices. Using a form for the elements would also mean the clothing choices could easily be sent to the server for processing to flatten the items into a single image. No JS necessary!

Creating the Sprites

The main challenge I knew I would be facing would be keeping all the image assets within the budget requirements. I settled on the idea of using pixel art and had some very vague idea of a style. By carefully choosing a style, budgeting a couple of kBs for a sprite and using the rest for the markup and CSS, it seemed somewhat possible.

Here's a couple of the early concepts that were heavily stylised:

10kb-pixel-art-concepts

Very quickly, it became obvious that the style would have to be severely limited. Pixel art is perfect for this, because it's traditionally limited in colour and size. The sprites could be tiny, up-scaled and it would still work stylistically.

After going back to the drawing board (Photoshop), I drew a few of my team mates (they were perfect guinea pigs for this, thanks guys!).

10kb-sprites

This style suited much better. It's fairly generic, so the same base body could be used for different genders and with most of the detail removed, the file size would be small. Win win!

After building a quick HTML prototype, the concept was working. Time to move to PHP and Sass - because honestly, who likes repetitively copying things?

10kB, is tiny.

The interesting thing with moving to Sass and PHP is that it makes it much easier to build out your markup. It also means it's easy to bloat said markup. Running into the issue of your markup being larger than your CSS and images COMBINED, is something I can honestly say I've never encountered before (╯°□°)╯︵ ┻━┻.

So, the task began of paring down the markup to include only what was necessary. CSS classnames were also pared down to be teeny tiny. Text styling classes were prefixed with t- and all the prop types were shortened to two character name prefixes. Anything that was single purpose was made into an ID, because this could double as a #target to switch between 'views' or 'screens'.

public function render_item( $item, $itemnum, $legend, $selected ) {

    $type = $this-">shorten_css_class_name( $legend );

    echo '<input id="' . $type . '-' . $itemnum . '" name="' . $type . '" type="radio" value="' . $itemnum . '">';
    echo '<label for="' . $type . '-' . $itemnum . '">' . $item[ 'name' ] . '</label>';

}

The result was just under 10kB, but there were only a few props, which was pretty limiting for creating a character. And up-scaling pixel art in Internet Explorer looked TERRIBLE, because I wasn't able to set nearest-neighbour interpolation. Wonderful. What about SVG? That scales nicely!

6.68kB. Darn. That doesn't fit the budget.

At this point, it was looking pretty grim. The markup had been cut down as much as possible, the CSS was pretty lean, there were only a few props. What to do? Oh right, GZIP. Oops.

GZIP to the rescue!

Moving back to using an up-scaled PNG image that would display relatively nicely in Internet Explorer, with GZIP enabled brought the whole filesize down to just over 5kB. YES! More props were made and the design of the splash screen was considered and quickly mocked up in Photoshop.

10kb-pixel-art-hero

At this point, the project was working and mostly complete. With many bytes to spare! I showed a few people how it was going and one of the suggestions was to add a small animation when changing clothes. It's subtle, but adds just a little bit of fun.

10kb-clothing-transition

The result?

10kb-requests

The final project outputs just over 8.1kB and the character sprites can be saved, which is all handled through PHP. And I won the Best Design Award!

It was SO much fun to build something with such clear limitations, combining several of my outside-of-work hobbies. And while several issues came up during the course of the project, each one of these was able to be overcome.

10kb-screenshot-maker


Get it on Github

If you want to check out the code for yourself, you can view the code and assets for the project on Github.

Get the code!

Ben Maden

Read more posts by Ben

Leave a Reply

Your email address will not be published. Required fields are marked *

Shares