The Let's Play Archive

Transistor

by Non-EuclideanCat

Part 2: Deep Dive 2

Deep Dive 2

So I've been going on for a while about how easy Transistor is to modify, and I figure it's time to show just what I mean. Let's head on back to the Content folder, and then into Scripts.


This folder holds all of Transistor's scripts, of which there are three types: .txt, .scripts, and .world_scripts.


The .world_scripts aren't really relevant to us. They control things like camera position. It's the other two we care about.



The .scripts contain all the event triggers. Things like scene transitions, the start and end of fights, designating Use Points for jump pads and elevators, all that good stuff.


They also, notably, contain certain conversation triggers, especially for Royce.


Finally, the .txt files are what the .scripts reference to determine what audio files to play and when.


Now, there's two kinds of speech triggers: continuous and conditional. Continuous Speeches are used for the monologues Royce gives when you talk to his proxy. The conversation is loaded up as a single unit and plays all the way through, uninterruped.


Conditional Speeches exist for when there's a chance a given line might not play. If a line is based on a specific action, like most of Jack's reactions to Red are, could be interrupted, like Asher's speeches if you ditch the terminals quickly, or have a chance of not going off, like much of Royce's dialogue in his studio if you hurry through, the line is queued based on certain conditions being met (or not being met).

Also take note of a few things: first, the programming language Supergiant uses has "--" as a way to dummy lines out. Any lines starting with that aren't read by the game as active lines to be used. This can be used to make notes, as with the in-code subtitles for the voice lines, but also to prevent certain events from firing if the creators deceided they don't want to use them but also want to leave them in for whatever reason. Second, all of the paragraphs for dialogue make reference to "/VO/~", where ~ is some kind of file name. It's these two notes that let us make changes to the game's dialogue.


So let's get to that. Back to Content, then into Audio. A few more files deep and we find 7 files: 5 .bank files, a .bank.strings, and a .fsb. The .banks house all the game's sound effects, and I honestly don't know what the strings file is all about. It's VO.fsb that really matters. Within that file is every single voice clip recorded for this game, even the ones that didn't make it in. It's this file that all the /VO/~ calls are referencing



Using an extractor we can get a look at and copy any of these files into a .ogg file, which can be trivially converted into any playable audio format. The files are broken up first by game level (Fairview, Goldwalk, Elevators, etc.), then numbered (Fairview_1 to Fairview_109), then subdivided by letter if a line is part of a series (Asher_5a to Asher_5i). Extracting these files lets us play them for ourselves so we can find out what's what.


So take, for example, Royce's lines. Royce has 374 voice files, most of which are used but certainly not all. So what do we do if we want to put them in? We've got a couple of options. First is to find lines whose triggers were dummied out and remove the -- to make them active again. Second is to add them into Conditional Speeches and add or adjust the conditions to make it all work. We'll see a lot of this in the finale episode. The final way, as I did here:

is to add in an entire Continous Speech into the .txt and corresponding trigger in the .scripts file. All of this can be done pretty trivially so long as you know the file names you want to play and copy the format excatly (failure to do so with Continuous Speeches will lock Red into an endless, silent staring contest with Royce, forcing you to kill the game via task manager or alt+f4).

Now I'll show you how I changed all the names.



From Content into Game we find files containing unit information and animation data. Units contains all the information for enemy units in easily editable .xml files. Their health, movement data, AI, sound effects, upgrades (including the unused Level 4 forms I mentioned), and display names can all be easily viewed and modified by popping any of those files into any word processor. The information for all of our Functions is on similar .xmls, over in Game/Weapons.

Next, let's take a look at how Transistor does its graphics.

The game does its graphics via a combination of sprites and clips.


The Clips are used for especially complex or flowing items: things like Red, Royce's fight avatar, Fetch animations, etc. Everything else are sprites. The Clips exist in .bik files in Content/Movies: a collection of a given animation played in each of the 32 directions an object can face in this game. Presumably these files are all interchangable, meaning Red could be turned into a dog or a headless Man with a simple find-replace.


The sprites all exist on a series of sprite sheet packages over in Content/Win/Packages. Loading them up into a viewer lets us see how they're laid out.


Everything's in here: the backgrounds, most of the particle effects (including Functions), all the objects, everything. Let's take a look at our humble little chicken friend for an example.


All of the Lobber's textures are here, subdivided by purpose:


Attack animations.


Walking animations and death effects.


They're all sprites called up by the reference bins in the various packages, which are themselves called by the animation code in their Units .xml files.

Finally let's take a look at subtitles.


All the game's subtitles exist in a series of .csv files that are married to their respective level scripts.


Each line is assigned to a matching voice file name and is displayed as the file plays. Since these are all simple spreadsheets, they can be modified as easily as all the others. In fact, you've already seen that. The subtitles for Royce's bit about Sybil that I put in did not match the voiced line. I had to delete a sentence out of the file to make it match properly.