Wednesday, February 26, 2014

The Narrative Map

As we mentioned in previous posts, Hellenica features a broadly branching narrative with a bunch of custom dialogue to help wrap the story around whatever set of choices the player has made. We're putting a lot of work into these features and wanted to make sure the player can get the most out of them. Because, as this Player's Delight blog post highlights, it can be easy to miss a bunch of non-obvious ways your choices might be influencing the story.

To combat this, we created a narrative map (an early version of which can be seen below) that displays the current social hub the player is in, as well as the plethora of other nodes available. The nodes all start out as question marks but are revealed after a player visits them. In order to encourage the player to explore different paths throughout the game, this screen also provides the option to go back to any social hubs she had previously visited. Each social hub automatically saves the state of the game when it was last visited, which allows us to effectively "rewind" the game to that point. (It also unfortunately means that you can overwrite your data by taking a different path to the same hub; we're still trying to find an elegant way of handling that...)

Early version of narrative map, using placeholder art.

To help the player keep track of the story path she’s taken (especially given the option to replay hubs), we felt it was important that the narrative map display social hub descriptions specific to the path taken to get there.

As an example here are two narrative map descriptions that could display for the same hub.

==Heading to Delphi from Corinth==
The adventurers decide to head to Delphi to seek the oracle's guidance. They are accompanied by Castor, who after learning his missing brother is likely dead, has resolved to undertake a quest to save their ruined home, Corinth.

==Heading to Delphi from the Isle of Circe==
Fed up with Circe's vague answers, Diona and Nephele decide to seek advice at the oracle of Delphi. They also hope to find the "fool" that Circe said was about to embark on a quest to save Corinth. Before they depart, Circe presents them with Brasidas, a Spartan that she previously kept as a pet turtle.

Wednesday, February 19, 2014

Hellenica Characters: Diona!

This week we're revealing character art for our main protagonist, Diona, the huntress of Artemis.

Diona is fiercely independent, spending most of her time in the wilderness, away from the bothersome laws and customs of Greece's more metropolitan areas. As a disciple of the Goddess of the Hunt, she excels at hunting and survival, and she prides herself on her abilities and strength. Along with that pride comes a general disdain for other humans, and her interactions with them are usually as short-lived as her hunting quarries.

For Diona, we had a fairly clear image of what we wanted visually. There are a lot of great examples of hunters out there. San from Princess Mononoke was certainly a major influence for us. We also looked to characters like Aragorn, as well as more generic reference material like Ranger, Druid and Barbarian archetypes in various role-playing games.

Once again, our talented artist, Cotton, was able to quickly transform our ideas into sketch form.

The key elements we focused on to capture the huntress look were the draped fur, the animal teeth pendant and knife, the body paint, and the long, wild hair. We also introduced some smaller details to ground her in ancient Greece: the thin sandals, the geometric details on her tunic, and a moon icon on her headband to signify her relationship with Artemis.

Next we tackled the pose. We really wanted Diona to come off as the natural predator she is, perhaps stalking her prey or actively pouncing for an attack. Cotton put together this pose, with her knife drawn and ready to strike.

For colors, we wanted her to look natural as well as sensible. Her self-reliance meant that her clothing would likely be self-made, and she would need darker colors to allow her to stalk her prey effectively. The headband and icon are sacred relics, so we chose a slightly more ethereal blue color to contrast with the rest of her huntress garb.

Thanks for taking a look at how we developed Diona! There will be more character updates to come in the future so check back soon.

Wednesday, February 12, 2014

It's All Greek to Me

When I first mentioned the possibility of making a JRPG in a Greek steampunk setting, my friend (and college RA) Bergy was estatic. In addition to being a JRPG aficionado, Bergy was a classics major with great familiarity and interest in ancient Greece. He's been invaluable in all kinds of brainstorming, world building, and editing, but for the purpose of this blog post, I'd like to focus on a particular skill—Bergy can speak ancient Greek.

Among other benefits, this means that if we ever wanted to invent a word for a unique concept in our setting, we could ask Bergy the ancient Greek translation of the concept. While there're all kinds of situations where we could use this power, we're trying to keep XKCD's advice in mind, even with our glossary system helping us out. Specifically, we try to invent words only for new concepts, where we'd have to teach the player the definition even if we weren't using ancient Greek.

For example, one of our characters is a sort of druid or ranger (in the D&D sense) devoted to the service of Artemis, the goddess of hunting. Rather than trying to force that whole connotation onto an English word, we borrow the ancient Greek word for bear (a reference to some of the character’s abilities) and refer to her as arktos.

We also wanted a phrase for the steampunk devices and technologies that permeate the setting. At first, we tried combining the Greek words for "steam" and "machine" to make "Atmomechanai". However, our early playtests saw people stumbling over the word (or misreading it as "Automechanai"). We tried again with "god" and "machine" (reflecting the divine influence in developing this technology) and got the much more pleasant theomechanai.

One concept we’re still struggling to put a name to is the mystical devices the Pythagorean order has been creating in their quest to make machines with souls. Our first attempts at combining Greek words sounded really awkward to English speakers.

Biomechanai (“living” + “machine”)
Metiomechanai (“advice/wisdom/strategy” + “machine”)
Psychomechanai (“soul” + “machine”)

We alternately tried adding the “descendants of” ending on some mythical half-human, half-mechanical beings.

Talonidai (referencing Talos)
Galateïdai (referencing Galatea)
Paphidai (referencing Paphos, the son of Galatea)

We’ve also considered going half Greek with something like “Children of Galatea” or “Talos Spawn” though those phrases are somewhat more cumbersome. A quick survey of friends has suggested Talonidai as the best current option, but we’d be happy to hear your feedback in the comments.

Wednesday, February 5, 2014

A simple logger class for Unity projects

Today I thought I'd share a simple utility that you can drop into your own projects to help manage your debug (or release!) logs at run-time.

Unity's included Debug class has some great functionality for logging, raising warnings, and raising errors. Over the course of a project, however, regular use of these functions can lead to a very noisy log, which can make debugging tedious.

With that in mind, I set out to create a custom logger with the following requirements:
  • quick to drop into a new project
  • easy for a person to use for the first time
  • easily filterable at run-time
  • zero overhead outside of DEBUG builds

To address the first two constraints, I made the Logger class a static singleton that creates itself whenever any of the public logging functions are invoked. This also means that a new user simply needs to register their logging channel and start logging to start using the Logger in their project. Here's a simple example:

  Logger.register_channel(Log_Channel.Combat, Logger.E_Level.Verbose);

  Logger.log(Log_Channel.Combat, "Really super important combat event!");

By using Unity's Object.DontDestroyOnLoad() function on the Logger object, I guarantee that it will stick around for the lifetime of the game, even across level loads, unless you explicitly destroy it. This keeps lifetime management simple as well.

To be able to modify the filters at run-time, I set up a simple inspector (Logger_Inspector.cs) for the Logger class that generates drop-down lists for each channel that has been registered with the logger.  It looks a little something like this:

From here you can set the logging level of any channel directly allowing you to filter out exactly what you want, when you want it.

Finally, to make sure that none of our logging statements have any impact on our final release builds, every publicly accessible member function of the Logger class makes use of the System.Diagnostics.Conditional attribute.  Here's an example of what this looks like:

  public static void log(string channel, string message)

When the DEBUG flag is unset during compilation, none of the public Logger functions will be compiled and calls to these functions will become empty statements (or no-ops). This translates to zero memory and processing overhead in non-DEBUG builds, which makes programmers everywhere happy. Hats off to the .NET and Mono guys!

So that's about it. There's still a good bit of room for extension here: adding different log output streams, adding hierarchical filters, or anything else your heart may desire. You can find all the code and a containing .unityPackage file here in our public BitBucket repo.

I hope this code helps you out in your projects. Let us know what you think!