It starts with Chipotle

David, Henry, and I are front end developers at Caleres in St. Louis, MO. Our main gig there is famousfootwear.com. We love CodePen at Caleres... we even have a Pro Team account! We walk from our office to Chipotle for lunch at least once a week. During one of our walks to Chipotle, Henry was overcome with the scenic journey (It's a beautiful area) and said something like, "Guys, we need to make a game out of this... where you walk to Chipotle."

Today, I'm happy to report that we have a demo to share. Check out the Pen here: The Danger Crew demo

It's just a demo. We're not finished with the game yet... still no Chipotle, but I hope to keep evolving this post as we go.

CodePen is mega handy

Like I mentioned at the top, Henry, David, and I are part of a Pro Team account. That means that our personal accounts are super powered with Pro features!

We are using many, many, many Private Pens for storing prototypes and forked copies with small variations. We're serving audio and images from our Asset Manager buckets. We have Collections full of Pens that document every step of progress. We are able to share ideas quickly and preserve them in time without complicated git branching. It's like a history log of our progress. Heck, our whole Walking engine started as a Collab Mode session.

Many pieces of our game were developed on the side first, then brought in to the main project. Here is a Pen of our first Battle Terminal interface:

React & Webpack

I have a bunch of React experience, so it was easy to choose that over anything else. The rendering performance alone is a big deal when you're throwing a lot of game elements on the screen, but I was mostly worried about maintainabililty.

RPGs are BIG in project scope. There is a lot of depth to consider: characters, items, menus, experience points, etc. Each piece contains a little world of state that needs visual representation. I've found React projects to be pretty easy to maintain because each piece is contained in its own file and can't really touch anything else. React's console debug logs will yell at you if you try to do anything weird. It's pretty easy to keep all of your files working in the same way.

The React community is pretty vocal about requiring a build process. This project has a lot of React component files and a lot of unit tests. CodePen's editor does a great job of supporting a React friendly workflow, but this project grew too quickly for one little window.

We are pulling a few JavaScript files from cdnjs.com, and one of my other Pens using CodePen's JavaScript API. That file is a wall of mangled code from Webpack. I didn't want to overload the Pen view with our compiled JavaScript, but some of our Pens leading up to the demo did that and it worked fine. (Doesn't really matter if you are sharing /debug links with your team)

Learning to Walk

We decided early on to adopt a top-down world view, like in the classic Game Boy Zelda and Pokemon games. Jacob, the protagonist character, is one cell on a grid with x/y coordinates. Jacob isn't the only character on the map. Other characters live on the same grid and move in the same way, so a reusable React component was in order:

  <Person isPlayer={true} x={4} y={4} personId="player" />
<Person isPlayer={false} x={3} y={2} personId="npc_001" />

The inPerson prop allows Jacob to be moved with user input from the arrow keys. WASD work too, for PC gamers out there. A Person's x and y props determine CSS left and top positioning. When a character is in transit from one cell to another, a requestAnimationFrame updates a transform:translate3d(..,..,..) inline style. When the requestAnimationFrame loop is complete, the new x or y coordinate value is repiped through props, and React will rerender the non-moving character in his or her new coordinate position.

We used pure CSS transitions early on, but the result wasn't as smooth as requestAnimationFrame. It took a few iterations to make it feel right. Here is an example of one of the earlier iterations: (map artwork is from Pokemon)

Person components that are not the player receive AI instructions according to their personId values. The currently loaded map config object has specific dialog and AI instructions for each personId. Some characters walk on a designated path, others simply rotate. Excited characters may talk fast, nervous characters talk slow in awkward situations. We worked in an expressive dialog system that allows us to define the rollout speed of each segment in a conversation string.

Animating Characters

I wasn't sure how far we could go with animated graphics. Too many moving things on the screen might make the browser laggy and gross. We started testing the limits by making a Jacob Adder:

We had a self imposed limitation to not use <canvas>. I think HTML canvas is awesome, and the game would probably be a lot smoother with it, but we were on a mission to push the limits of classic web elements. Also, the game is about being a Front End developer, so I thought it would be cool to keep the game characters and environments to <div> elements. A game in divs about people who write divs. We have a running joke that the sequel will defintely be in canvas.

Each character in the game is a single div with a SVG spritesheet declared as a background-image. background-position and background-size control which cell of the sprite sheet is visible. A @keyframe animation using steps(4, end) gives the illusion of an animated walking gif. Click the "Add Jacob" buttons to try it out!

Chrome on my Macbook Pro didn't chunk until the 900's Jacob mark. Phones started clunking a lot sooner, the capabilities of the mobile browsers were still pretty good. Your experience may vary, but the results were good enough to keep us motivated.

Art & Music

David coded the character and map SVGs manually. I can't comprehend how that is even possible, because the internals of SVG code looks like a bunch of jibberish to me. He used it as an opportunity to really understand how SVGs work, rather than jumping to a common pixel art tool. Some of the objects and signs were drawn by hand, scanned into Illustrator, exported as SVGs. The coffee shop area especially comes to life with creamer pitchers and coffee mugs.

Coffee Shop

Henry is not only a great developer, but also a talented musician. He wrote and produced the game's music and sound effects. We do include a "mute" option for no audio playback, but the music and sounds are what really give life to the characters. Henry implemented Howler for playing the sounds and music in the browser. All of the audio files are also hosted in CodePen's Asset Manager.

Battles

We decided on a turn-based combat system because it seemed way more "doable" in a web browser than some live-action thing. The user interacts with a form, submits his or her move, then observes the outcome. Repeat this process until one character is left standing.

These types of battles require a lot of state: what is my health now? What is his health? How much damage will this attack do if my attack stat is temporarily high but he just used a Defense item? Which do I have, and are they relevant to me right now? All of these questions were stressing me out.

This is where Redux came into the picture. It's hard to learn about React today without Redux sneaking into the spotlight too, because the two are a match made in heaven. Redux advises you to keep all of your application state in one top level spot: the single source of truth. It's basically a big Javascript object, sometimes even simpler. If something in your application changes, (like a comment count increases, or the user submits a form) update the single source of truth and let the views reflect whatever data is in the state object.

I used the Redux website and this tutorial to learn Redux. Then, this amazing tutorial series was released by Egghead.io and Dan Abramov. (Egghead.io is also a great place to learn React, Angular, and many other things)

Tutorials are great for getting started, but I need real projects to learn new things. I learned Redux by taking a first stab at a turn-based battle game:

Be sure to play with stat sliders at the bottom. A strong Harry Potter can indeed beat the evil Lord Voldemort. (Credit to David Stout for the graphics! He drew them in one take on one of our whiteboards at Caleres.)

I might do a follow-up post on the nitty gritty details of coding a battle system, but it basically boiled down to this: let the players be configurable by JSON, calculate the state-changing result of the turns, incrementally roll out the state changes to the User as they "click through" the story.

Our second version of the battle engine was less visual, but had more features. It introduced the concepts of items, item theft, status changes, more than 2 combatants, and multiplayer through Firebase. A refactored third version was what ended up in our game demo above, where we improved almost everything. The engine could also "auto play" itself to run a few hundred battles at once. The results of these "auto battles" helped us design fair battle mechanics. I plan on making a fourth engine soon to implement the lessons I've learned from the third. (Even after that, there will probably be a fifth version...)

We are still going

"Release early, release often", right? We're still chugging away at The Danger Crew. If you're interested in the project, we'd love to keep in touch.

Sign up to receive game updates on our website: http://thedangercrew.com

Let's be friends on CodePen!

David Stout http://codepen.io/davidastout3/

Henry Leacock http://codepen.io/henryleacock/

Drew Conley http://codepen.io/punkydrewster713/

Thank you for reading.


6,820 4 41