New York Times!

Wow! We had a great GDC, which included chatting with Chris Suellentrop from the New York Times. Then, today, this was on the frontpage of NYTimes.com!

New York Times

Here’s a link to the story: http://www.nytimes.com/2013/04/01/arts/video-games/game-developers-conference-celebrates-indie-creators.html?hp&_r=0

We will post more about the conference soon, but wanted to share this post haste. It seems the article may be in the physical edition of the NY Times on 4/1 as well, so check your local newsstand!

GDC!

Posted in Press | 1 Comment

Riot Grrrl Style Now

We have an exciting announcement to make… in the form of a brand new Gone Home trailer!!

(or check it out on YouTube)

That’s right– we’re proud to announce that Gone Home will feature the music of original ’90s Riot Grrrl bands Heavens to Betsy and Bratmobile!

A big part of teenhood is being introduced to new music and art that broadens your horizons and makes you see the world differently. For Samantha Greenbriar in Gone Home, that music is Riot Grrrl, an indie feminist punk scene that started in Olympia, Washington in the early ’90s. So we’re just incredibly excited to be able to put some of that actual, authentic music into Gone Home, so you can hear what Sam heard– the music that fuels a friendship that will change her life.

FYI: the song in the trailer is “Some Special” by Bratmobile. Gone Home will feature six tracks total from the albums Pottymouth by Bratmobile and Calculated by Heavens to Betsy. (Heavens to Betsy, btw, was the first band fronted by Corin Tucker, who would go on to form Sleater-Kinney with Carrie Brownstein and Janet Weiss. So, one more thing to be psyched about.)

We’re gearing up for GDC around here, but I’ll leave you with a few new screenshots to accompany the trailer:

Basement MovieTicket Bedroom Zine

See you in San Francisco!!

Posted in Announcements, Media | 17 Comments

The Fullbright Company at GDC!

Hi folks! Steve here. Just wanted to mention that Johnnemann and I are both going to appear as speakers at GDC this year!

I’ll be part of the “Level Design in a Day” Bootcamp:
http://schedule2013.gdconf.com/session-id/822397

It’s a full-day tutorial series on Tuesday of the conference. There are a ton of awesome designers that will be up on stage– guys who have worked on Skyrim, Dead Space, BioShock Infinite, Gears of War… oh, and Gone Home.

All aspects of level design will be covered, from planning and layout to pacing and tuning. I’ll be doing half an hour on “Narrative Techniques for In-Level Storytelling,” where I’ll talk about nuts-and-bolts methods of conveying story without taking control away from the player.

Johnnemann is going to be part of “Ask the Experts: Professional Programmers Panel”: http://schedule2013.gdconf.com/session-id/823856

Along with Johnnemann repping The Fullbright Company, the session will feature programmers from Bethesda, Double Fine, Insomniac and more. The panel will answer the audience’s questions about overcoming specific technical challenges, the ins and outs of working on a larger dev team, and general thoughts about life as a programmer.

And of course, since we’re nominated in the Independent Games Festival, we’ll be at our kiosk in the IGF Pavilion throughout the Main Conference, letting people get hands-on with a playable version of Gone Home!

If you’ll be at GDC, we hope to see you there!

Posted in Announcements | Comments Off on The Fullbright Company at GDC!

Gone Home’s Input System

Input, on the face, seems pretty boring. “What happens when the player hits the spacebar?” seems like a pretty easy question to answer and a pretty simple thing to implement.

And in some cases it is. But think for a second about a modern game. What’s the answer? Maybe, in a platformer, the character jumps. But does the character always jump? What about when the game is paused? What if spacebar means “jump” most of the time, but if the character is standing next to a gun, she picks it up? What if you give the player the ability to re-map buttons, so that spacebar could mean jump, run, or quicksave? What if you support a gamepad, so there’s no spacebar any more?

These intersecting questions pile on the complexity, and in fact in Gone Home (which doesn’t even have jumping) the input system is the single most complex system I wrote. Of course, Gone Home doesn’t have a lot of complex AI code or gameplay interactions, but even in a more traditional title input is something that, done right, represents a lot of complex choices and abstractions.  Gone Home does support a wide range of input features, though, such as choosing between mouse/keyboard and gamepad, remapping keys, and a number of behind-the-scenes features that make for a smooth experience.

Input Context Composite

A selection of input contexts. Clockwise from top left: Default, Examine, Journal, Map

The first question I considered is “How do we handle the same button doing different things?” This may seem like an uncommon situation, but, for example, most of the time in Gone Home pressing the left mouse button does nothing. When the player has moused over an interactive object, however, it triggers the interaction (or “frobs” the object, http://en.wiktionary.org/wiki/frob). So that’s two states that need to be accounted for. Plus if the game is paused, we don’t want to frob things, if we’re holding an object we want to let go of it, and so on. The response to pressing the left mouse button depends on the context.

And so the first abstraction our input system uses is “input contexts”. We always have a current InputContext that the player is in, that defines a number of things about how input works while that context is active. It lists the commands available to the player, as well as things like whether the mouse cursor is visible, whether the simulation is paused, whether this context changes the player’s mouse sensitivity or FOV, and a lot of other useful information. Some InputContexts only allow the player access to the commands they explicitly provide, where others are additive on top of whatever other contexts are active. So, for example, the “Crouched” InputContext only adds the ability to Uncrouch on top of everything else the player can do, while the “Main menu” InputContext drastically limits the available actions. We keep a list of all the active InputContexts in the order they were applied. For the most part, this conforms to the classic definition of a stack, and it was originally implemented that way, but occasionally we want to remove an element that is not the top of the stack.

InputContext Screenshot

What an input context looks like in the Unity Inspector

In addition to InputContexts, there are a few other abstractions that the system uses: Controls and Commands. (Contexts, Controls, and Commands – this is really confusing naming and I wish I had done a better job. Don’t do this.) A Control represents the action the player is trying to perform. For instance, in the default context there’s a Control “crouch”. Controls also track whether they can be remapped by the player, the desired key state for triggering, and whether the control is exclusive to its current context.

A Command is a way to represent the actual code that is executed when the Control is triggered. It takes the form of a callback to some function. In the case of “crouch” we have a CrouchManager component on the player object that tracks crouching state and interpolates camera position. The Control and Command are decoupled because, based on context or other changes in game state, we might want to respond differently to the same Control.

Those abstractions explain how we deal with the player attempting to frob objects when the game is paused, or how we might change the crouch button to stand up when the player is already crouched. In order to answer the questions of how the game deals with remapping buttons, though, there are yet more abstractions!

A KeyMapping is a simple mapping of a key code (what Unity reports when the player hits a key) to a Control. Whenever the player chooses to remap an input, we change the key code associated with that Control. Unity already has an InputManager that tracks this, but it’s not possible to change anything about it while the game is running, sadly. In order to avoid having to quit the game to remap keys, I had to write my own solution. Hopefully in the future Unity will correct this oversight. Hey Unity, feel free to use this blogpost as inspiration!

KeybindUI

The control binding screen (Not final UI)

The last piece of the puzzle is dealing with a different sort of input entirely, such as a gamepad. Instead of pressing “c” to crouch, we want to be able to click the left stick, and instead of clicking the mouse button to interact, we want to be able to press the big green A button. Which sounds an awful lot like remapping controls! Except it’s every control, and we want to be able to switch back and forth at will. Gone Home deals with this by having a pre-set group of KeyMappings that we switch in and out on demand, called a ControlScheme. We keep at least four versions of this: the defaults for keyboard/mouse and gamepad, as well as user-remapped versions of each (we don’t want to lose your custom keybindings if you try the gamepad!). Because we want these bindings to last between play sessions, we save these out to disk in files. That means that switching between keyboard and gamepad, or reloading the default keybindings, is as simple as deserializing a file.

We do a couple of other things to make working with gamepads easier. The first is a system for translating analog inputs, such as from the joysticks or triggers, into regular discrete button presses. We don’t always want this; for things like movement analog inputs are preferred, but for some features we only care if an input has occurred at all. We also have a system for automatically replacing button references in our UI text, so that no matter what key or button an action is mapped to, the game will correctly display “Press <whatever> to crouch”.

New-Sheet_63vba

Diagram of the relation between various input systems

So to show how all these pieces fit together, here’s the basic flow of the main Update function of the InputHandler:

First we test the analog key bindings:

        foreach (AnalogKeyBinding KeyBind in AnalogBinds)
        {
            float AxisValue = Input.GetAxis(KeyBind.AxisName);
            AxisValue = KeyBind.PositiveAxis ? AxisValue : -AxisValue;
            if (AxisValue > KeyBind.ButtonThreshold && KeyBind.LastFrameValue <= KeyBind.ButtonThreshold)
            {
                KeyBind.ButtonDown = true;
            }
            else if (KeyBind.LastFrameValue >= KeyBind.ButtonThreshold && AxisValue < KeyBind.ButtonThreshold)
            {
                KeyBind.ButtonUp = true;
            }
            KeyBind.LastFrameValue = AxisValue;

        }

Then we iterate through our InputContexts, testing each Control it contains against the state of the key it’s currently mapped to. If the state matches the activation state, we trigger the callback of the associated Command.

        foreach (InputContext context in ContextStack)
        {
            int i = 0;
            bool ShouldBreak = false;
            foreach (InputContext.Control control in context.Controls)
            {
                if ((control.DesiredState == InputContext.KeyState.DOWN && ControlDown(control.ControlName))
                    || (control.DesiredState == InputContext.KeyState.UP && ControlUp(control.ControlName)))
                {
                    if (CommandCallbackMap.ContainsKey(context.Commands[i]))
                    {
                        CommandCallbackMap[context.Commands[i]]();
                        if (control.Exclusive)
                        {
                            ShouldBreak = true;
                            break;
                        }
                    }
                    //Tell uScript about it
                    SendMessage("OnCommandIssued", control.ControlName, SendMessageOptions.DontRequireReceiver);
                }
                else if(control.DesiredState == InputContext.KeyState.AXIS)
                {
                    float AxisValue = 0.0f;
                    if (control.Raw)
                    {
                        AxisValue = Input.GetAxisRaw(control.ControlName);
                    }
                    else
                    {
                        AxisValue = Input.GetAxis(control.ControlName);
                    }

                    if (control.Raw || Mathf.Abs(AxisValue) >= AxisThreshold)
                    {
                        if (AxisCommandCallbackMap.ContainsKey(context.Commands[i]))
                        {
                            AxisCommandCallbackMap[context.Commands[i]](AxisValue);
                            if (control.Exclusive)
                            {
                                ShouldBreak = true;
                                break;
                            }
                        }
                        //Tell uScript about it
                        SendMessage("OnCommandIssued", control.ControlName, SendMessageOptions.DontRequireReceiver);
                    }
                }

The rest of the work in the InputHandler is all of the support functions for this loop, as well as the functions needed to deal with key remapping.

This system, while complicated, allows Gone Home to have a robust, powerful, and flexible system for user input that can handle almost any situation we want to create for the player with minimal work on the content side.  Because of it we’ll be able to support an arbitrary number of control schemes, full control remapping on both mouse/keyboard and gamepad, and offer a smooth painless experience for interacting with the game.

Posted in Programming | 2 Comments

Unexpected Reference

Gone Home presents an interesting situation for an environment artist. Usually the spaces we’re tasked with creating are locations and time periods we might have very little personal experience with – space freighters, mythical temples, high tech labs, etc. Outside of researching the heck out of these locales, you kind of have to wing it.

Trying to pin down the feeling of a North American home in 1995 is something I have a little more personal experience with, and when I went home for Christmas this year I was able to dig through artifacts of my teenage years in an attempt to lend a little more authenticity to the house.

While sorting through my old Pogs and splatter-painted snap bracelets, however, I came across something unexpected with my mother – two old boxes, smelling like mildew, that hadn’t been opened since they’d been given to my family 14 years earlier. In them, my family’s history, meticulously collected by my late grandmother, boxed up and quietly forgotten about.

I unpacked them, laid their content out across the basement, and took some quick reference photos and scans. Here are just a few. (Click for detail.)

– The London Free Press (a Canadian newspaper) from 1943.
London Free Press -  1943

– This amazing list of social etiquette advice from 1921. (Number 5 is my favourite.)
Etiquette tips

– A telegram from 1905, where I can’t help but feel bad for my great grandfather.
Telegram

– This amazing monkey puppet, sans face. He’s my favourite.

Monkey puppet

The photos go further back, too. There are portraits from the 1870s, stately snaps of unnamed relatives, and dateless tintypes of women whose wardrobes put everything I own to shame.

Tintypes

There’s a family tree with names going back to 1850, camping photos of Canada in the 20s and 30s, an envelope stuffed full of correspondence (typed and handwritten) from 1903-1905, souvenir programmes from the first world war, one cent stamps, road maps, snippets of poetry, a casual mention of a dispute over a missing whiskey bottle (it was under the floorboards) and an account of my (then eight year old) great grandmother being stalked by a wolf over the Canadian prairie.

Small woman's portrait

There was also the written story of a rug – a rug that I’d walked over and dismissed as ugly countless times while living at my parent’s house. According to one handwritten letter it’d been inside a POW camp during the Korean war, nailed over the window of a tiny shack to prevent the snow from coming in. How it made it all the way back to Canada is a mystery.

bill and note book and envelope

I’m really grateful to be working on this game with the Fullbright team for a number of reasons, but I can honestly say I never thought that in the process of researching a game about familial histories I’d find out so much about my own.

Old photo booth pictures

Posted in Uncategorized | 2 Comments