There are a lot of posts going around this week about women in tech, compensation equality (or the lack thereof), and how to ask for raises. I want to cover these topics, but I want to do so at a future date when I’ve had some time to carefully articulate my points. MSFT CEO Satya Nadella was a prime example this past week, I believe, on what happens when someone is not articulate with their point.
Instead, I want to talk a bit about one of the major modes of our first game. This is one of the game modes I started working on first, because it is most unlike other games out there, and while I had a good idea of the experience, the actual mechanics have evolved a lot over time. The basic concept is that we have a configurable circuit board, and there are components that we can add, remove, or replace on this board. In the spirit of great games that teach a player the underlying logic and mechanics of a game mode before ramping up to more complex scenarios (“Portal” and “Braid” are two games that do this particularly well), I knew what early puzzles I wanted to present. I also knew that I wanted to get to the point where complex puzzles should have multiple possible solutions, so that players could attempt different approaches and still be successful. For example, a player may start out by “fixing” a broken board by replacing a burned out resistor, but later on, they may have to spy on a corrupt businessman by replacing his cablemodem’s motherboard with a similar board that duplicates the sent data and resends it over a wireless connection, all while drawing no more power than the original board. (“Let’s see, I need a repeater, a transmitter, somehow I need to lower the power draw of the existing components, or maybe I add a battery?”)
There’s a wide range of possibility there (hopefully, a wide enough range to last for dozens of hours of gameplay), and the next question was how to implement it. In a previous post, I wrote about splitting up data and code, and that was the approach I took. While there were early stabs at hardcoded solutions to prove out the concept, in the end, I knew I would need a wider, more data driven solution. So I took a logical approach.
First, I drew up a classic grid, like a Truth Table, with columns and rows marked Power In, Power Out, Data In, Data Out. I could cross out the diagonal (where the rows and columns matched) and then start to fill in the squares. A Resistor has Power In and Power Out, and so does a Wire (which is really just a degenerate case of Resistor with 0 resistance). A Splitter also has Power In and Power Out, but we have two Power Outs, and we decide how much power goes to each output. A Repeater is a Data Component, with Power In, Power Out, Data In, and two Data Outs, where we duplicate the data stream from the input to both outputs, but we potentially also resample the output at a new data rate (never lower than the original, or else we’ll lose data. Thanks, Nyquist!). We also need to note the Power Draw for this component (difference between Power In and Power Out), and we need to note the Max and Min Power; too little and the circuit won’t operate, too much and the circuit burns out! There are other components, but having populated this chart, I was ready to start consolidating.
Just as the Wire became a degenerate Resistor (a Wire is a Resistor object with a Power Draw of 0), other ideas for components began to consolidate as it became clear that their behavior and list of inputs/outputs was similar. Coding up a Base Class would cover 90% of the common functionality, but each individual component would need a derived class that had, at the very least, a configure() method to store the unique values for this instance, and a validate() method to walk the input values, run some code, and determine the state of the component and the potential output values. Configure would be passed a string with the unique configuration values for this component (Min Power, Max Power, Power Draw, Required Input Data Rate, etc.), and we could have some other methods in the base class to handle common configuration settings for all components.
And that’s it! With a handful of classes, I can now define a really broad array of potential components. Internally, the class hierarchy (actually the V-Table) handles mapping the correct behavior on validation (I just pass around an IComponent, which is an interface to the BaseComponent), and the BaseComponent class tracks the state, along with a mapping of state to visual representation. This last part is great, as I can simply call validate() on my component, then have my View layer (because of course we’re MVC) ask the component to hand me back the image identifier for whatever it’s current state is. If Power In was too great, the state should now be BURNED_OUT, and the component will tell the display to show it’s “burned out” image.
There’s a lot more to this game mode that I believe is going to be a lot of fun, as players reconfigure and hack hardware, learn a little bit about circuitry, and advance their character in the game world. For now, I’m scrambling to get this mode fully implemented so that I can start to engage with artists and designers to make it look really wonderful and engaging. The code is one part, but bringing it to life for the player, with sparking circuit boards and pulsing LEDs is the level of polish that I want to reach within a few months.