1. Genesis Noir
  2. News
  3. June Dev Update: Scripting + Spelunking

June Dev Update: Scripting + Spelunking



We hope you’re doing well and getting good sleep (and that the phenomenon of non-stop fireworks hasn’t hit your town; NYC's a surreal place these days). We’ve been making good progress across many areas of GN. Jeremy has been working on our script and translation system and Evan has been refactoring a bunch of our early code (as well as animating some abstract animation for the introductory credits) and we thought we'd share how theses tasks are going with you.

Jeremy’s Script Shenanigans

Contrary to most of our screenshots, our game does have some text in it, about 3000 words in total! Since our lovely backers come from all over the world, we’re translating this text into a bunch of different languages. We’re working with several different people to do these translations, and since we can’t all have them working in the actual game engine itself, we had to put the text into a big spreadsheet in order to allow all our translators to access it.



Here you’ll see the text used at the very beginning of the Improvisations level, which was featured in our recent Steam demo. Each piece of text has a unique identifying key assigned to it, and then after that is each translation of that piece of text in all the languages we’re localizing the game in. These columns are labeled with each language’s IETF language tag.



But how do we get all this fancy translated text into the actual game? This is where “PO files” comes into play. Each language has a PO file, which maps each original English source text to the translated text. Unreal Engine can read these files and will put the translated text into the right places, and it even allows you to switch languages while the game is playing.

We’re still missing a few steps though. How do we go from a spreadsheet to a PO file? Well this is where it gets a bit complicated. In order to convert from spreadsheet to PO file, we’ve written programs in 3 different scripting languages that all work together in order to allow us to press just one button in order to convert the entire spreadsheet into PO files the game can use. Let’s go through the process!

Here’s all the steps we need to do:
  • Download the script spreadsheet from Google Drive
  • Open it in Microsoft Excel
  • Oh jeez, I guess we need to save a copy as “macro-enabled” so that we can write code to process stuff...
  • Close the old script and open the macro-enabled copy…
  • Inject our “convert to PO file” macro program into the spreadsheet and run it. This makes our PO files.
  • Seriously close Excel
  • Oh jeez our PO files can’t have any linebreaks in them, so run a javascript program to convert all of them into “\r\n” instead…
  • All done!


This is a lot of work to do every time the game’s script is changed. The whole process takes about 5 minutes of manual work, and that’s 5 minutes I could be spending fixing bugs or whatever, so let’s automate this whole process!



It turns out that Windows has a pretty powerful scripting tool that lets you automate tasks in most Microsoft programs. It’s called PowerShell, and it basically allows you to programmatically do most things you can do in any Microsoft Office program. These programs are very picky though, which means we have to do things in a very particular way.

Excel won’t let just anyone run programs on random spreadsheets, no sir! You have to first enable some weird registry key thing to allow access to something called a “VBProject object”. Then you have to convert the spreadsheet itself from “Regular Microsoft Excel” into “Regular Microsoft Excel, Now With Spicy Macros!” Then we close the old script spreadsheet and open the Spicy Macro version, and now we can actually run code to read from the spreadsheet itself and process the contents.

This involves an arcane programming language called “Visual Basic for Applications”, or VBA. I don’t know VBA, but I know someone who does!



Meet PJ DiCesare, accomplished speedrunner and actual Excel wizard. In just a couple of hours, he wrote us a lovely macro to convert our spreadsheet into PO files, with all the translations in the right place. PJ is well-known for his uncanny ability to cause strange things to happen to any piece of technology he touches, so of course the moment I ran his Excel macro for the first time, one of the fans in my laptop literally exploded.



I ordered a replacement for $13 from ebay, and it was easy to fix. This felt like a fair trade in order to avoid having to learn or write VBA myself.

OK! So now we have our PO files, we can close Excel now. This requires 5 lines of code where we tell Excel to really, seriously close in about 3 different ways. If we don’t do this, the Excel program might still be running on the computer, hidden and invisible, which isn’t very nice. You might think we’d be done now, since we have all the PO files, but oh no, we are not: our PO files are full of highly illegal linebreaks!



No linebreaks are allowed within the “msgid” and “msgstr” blocks, so we need to get rid of those. The last thing I wanted to do was write complicated text processing code in VBA or PowerShell, so it’s time for the third programming language: javascript! A friend we’ll call “Growfy” wrote us a handy javascript program to replace all the illegal linebreaks with “\r\n”, which Unreal understands as “just put a linebreak here”. After running this program on all the PO files, our final output looks like this:



Finally, after all this work, it’s done! Now we can cram these PO files into Unreal Engine, and here’s the final result:



Thanks to the power of automating things with programming, I can now press a single button to run this entire process in a few seconds, from downloading the script to generating the PO files without linebreaks. But will this be a good use of time in the long run? It took us probably 10 hours of work to write the automation pipeline, and it takes me 10 minutes to manually do this process myself, so we’ll need to update the script document 60 times in order for the automation work to be worth it, time-wise. I’ve already updated it about 20 times now, so I think this will work out to save time. If not, at least I know how to bend Excel to my will, which is probably a useful skill.

To wrap things up, I’d like to say thanks to all of our translators for helping localize our game, so that people all over the world can enjoy it!

---

Evan’s Ramblings on Creativity

One of the advantages of our delay is that we now have time to restore some elements of the game that were on the chopping block.



When we first started building GN, we began working on probably the most complex level. Our idea was that this level would contain many small gardening type interactions which would be repurposed elsewhere. In the context of the game, the level would be an introduction to the tone and range of interaction. For us, however, it was a trial ground for building components for the rest of the game.

This level became a part of our “vertical slice” which, like a slice of layered cake, contains a small portion of every ingredient in the game. The level contains exploration, a range of mini-interactions, item inspection, and some fun animation. This proved valuable to show to publishers, create our Kickstarter campaign, and get feedback from collaborators who would help us make the rest of the game over these past 3 years.

Since those early days, we’ve learned a lot about game development. Those initial little interactions were not as fleshed out or as well-engineered as the rest of the game and required some serious refactoring. It’s dirty work, but I’ve been glad to wade in over the last week.

As I audit the code, I discover some older approaches that have fallen away or solutions that I had forgotten. There are a lot of jank that I’m correcting with my additional years of experience in game dev, but it also feels a bit like I’m collaborating with my younger self. Mostly correcting, but interestingly collaborating too...

Over the course of development, the visual language, interaction patterns, and storytelling solidified as we identified the most successful aspects of what we were making. Refactoring these initial stabs at GN is offering a nice reminder of our initial goals, assumptions, shortcomings, etc. To directly see where we were 3 years ago and contrast with our skills and taste today is an opportunity to extrapolate our future growth, reflect on our work from a more naive vantage, and gain confidence in our development as artists + engineers. I believe this perspective will be very useful to consider what GN has become and how to best polish the experience over the coming months.

As this is my first project of such a large multi-year scope, the idea of becoming an archaeologist of one's own process is new to me. Perhaps for future projects we should schedule some spelunking expeditions through earlier work or pre-mortem dissections.

---

Thanks for following our project! See you next month :)

E+J