Connect: Let’s Build a Game

Part 1: Gameplay, Libraries, Scaffold

Mark Fayngersh
5 min readMay 23, 2016

In this blog series I will explore my attempt at building an iOS / Android puzzle game from scratch. I hope you’ll enjoy following along as much as I enjoy sharing it. The code is up on GitHub, feel free to check it out and contribute. Let’s get started! 😀

In this post:

  • Introduce game mechanics
  • Describe libraries and tools that will be used
  • Create a basic project scaffold

Game Mechanics

My girlfriend was introduced to this game while traveling through Norway. A fellow wwoofer showed it to her over dinner one evening and, well, she was hooked. After playing a few games myself it occurred to me that I could try and make a mobile version, so here we are.

The rules are simple. Two players take turns connecting consecutive circles on a triangular grid up to 4 in a row. The goal of the game is to avoid being the player left with an empty circle.

Consider the sample game below between 💙 and 💛

players take turns connecting ⚪️ rectangle highlights current move 💙 loses after 4 turns because she’s left with an empty ⚪️

After 4 turns, 💙 loses the game since she’s left with an empty ⚪️. Although in this game both players connect at least 3 circles each turn, nothing’s stopping you from connecting fewer, though you need to fill in at least 1 each turn. That’s pretty much it!

Libraries and Tools

There are many different languages, libraries, platforms, and tools we could use to build this game. Here’s what I ended up settling on and why:

  • React Native — Based on a rendering model I’m already familiar with on the web, also comes packaged with handy native components.
  • ClojureScript — A simple language with rich data structures that supports very dynamic development in short cycles (more on that later).
  • Om.next — ClojureScript interface to React that comes with tools for managing application state in a flexible, predictable way.
  • Figwheel — Builds ClojureScript and hot loads it into the running application.
  • Re-Natal — Combines all the libraries above in a scaffolding tool that takes care of setting everything up.
  • Spacemacs — Suite of plugins and enhancements on top of Emacs that make working with ClojureScript an ergonomic and fun experience.

If this list seems daunting, that’s ok! As we begin to build out the application, hopefully it will become more apparent how these tools simplify reasoning about the interface and game state.

Getting Started

I’ve already taken care of setting up the project scaffold using re-natal so we can go ahead and clone the repo, additional instructions are available in the project README.

$ git clone https://github.com/pheuter/connect-game
$ cd connect-game && npm install

One nice thing about using a platform-agnostic view layer like React Native is that we can write generic code and have it run on both iOS and Android. For this reason, most utilities and components will reside in the src/connect_game/shared directory, such as the Board Component:

Right now this component doesn’t do much other than render a basic text view with some styling, but we can worry about refactoring that later. There are 3 main takeaways from this module:

  1. You define React Components in Om.next using the defui macro.
  2. Instead of using JSX, you call factory functions that take 2 parameters: attributes map and child. In this case, we’re calling text and passing it some style attributes and the “Board” string literal.
  3. In order to use the components you define, you’ll need to create a factory function which should be called by the parent that renders the component.

Speaking of these parents, let’s take a look at the iOS AppRoot in src/connect_game/ios/core.cljs (the Android version is pretty much identical at this point):

There’s a bit more housekeeping going on here to setup the main root node and register the Om.next Reconciler (more on that later), but similarly we define an AppRoot Component that renders a view with board as the only child. In this case we’re not passing any attributes or children to board.

A JavaScript equivalent may look something like this:

class AppRoot extends React.Component {
render() {
return (
<view style={AppRootStyle}>
<board />
</view>
);
}
}

Let’s try and run the application on an actual Android device (I happen to have a Nexus 5 handy but you could also configure an emulator).

You’ll basically need to execute 3 commands:

  1. Start the React Native packager: $ npm start
  2. Start Figwheel for the appropriate platform: $ lein figwheel android
  3. Run the application: $ react-native run-android

The README in the repo has instructions for executing on iOS as well.

If all goes well, you should see something like this:

If you don’t see the screen above, please open an issue to get help.

I briefly mentioned earlier that using a language like ClojureScript enables dynamic development. Part of that is due to the design of the language where you have a Reader that evaluates code directly, which in turn makes room for awesome tools like Figwheel that takes advantage of that evaluation model to enable live editing across platforms.

If we go ahead and edit the Board component, we should see changes reflect in the running application almost immediately. We won’t see it now since we haven’t introduced state yet, but hot loading will preserve any existing state as well. This will become super useful later on when we get into the core business logic of the game!

Conclusion

In this first post, we learned about the rules of the game as well as libraries and tools we’ll use to build it. We’ve also taken a look at some core modules including basic components that render as native views on mobile platforms.

Stay tuned for more posts as we continue to build out Connect and dive deeper into React Native, ClojureScript, Om.next, Emacs, and more! 🙂

--

--

Mark Fayngersh

Co-founder @CareSwitch ➖ Philosophy nerd ➖ T1D 🩸