Angel Beats Post-Mortem: Part 1/4

Omg I can add alt text to these I'm gonna have so much fun with this

An overview and The Nickname Thing

Hello! Ojive here! You might know me as the guy who translated most of Angel Beats: 1st Beat, and oh goodness am I still traumatized from the experience. This will be the first installment in a four(?) part series in which I’ll be going over the precise details of how and why Angel Beats drove us all absolutely up the wall over the course of our time working on it.

If you followed any of Alka’s staff on Twitter or checked out any of our q/a sessions, you probably already have an inkling about the fact that Angel Beats was, umm, something of an experience to work on. Between the feverish mutterings of omelettetes and the crazed ramblings about game-breaking bugs spawning from a single misplaced >, you may have gotten the impression that there were a couple technical difficulties over the course of the project. I’m here to tell you that it was so, so much worse than you could ever possibly imagine.

In this installment, I’ll be giving a basic overview of what the Angel Beats script files look like, and walking you through the first of many, many problems we had to overcome just to get the game in a basically workable state. Let’s jump right in! I present an excerpt from the Day 0 file, the first scene in the game:

Doesn't look so bad, right? Ha. Ha ha. Ha ha ha ha haaaaaaaaaa...

The structure of the script’s pretty straightforward. Each line is present twice, with the first instance commented out. Our standard workflow is to only alter the lower, uncommented line, leaving the commented one in Japanese for future reference. The line numbers help us find and reference lines during the testing and editing process. Note that the structure of our script files and the line numbers themselves have more to do with the script extraction program we use them than the inherent properties of Siglus Engine scripts themselves—buuuut I don’t really know what I’m talking about when things get that technical, so I’ll leave it to the tech team to talk about nitty gritty extraction details if they ever feel up to it.

What’s really important about this scene, though, is that not all of the lines that you’re seeing in the image are actually a full, in-game textbox’s worth of content. You’ve probably already guessed that the ‘nothing’ lines don’t actually display in-game (their purpose has been a matter of hot and repeated debate among Alka staff but the tl;dr of it is that we have no clue what they’re for), but it goes, err, a bit deeper than that. Allow me to present the same image with all of the actual lines of dialogue/narration that require translation highlighted:

...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

Yeah. One. Seriously.

And it’s still worse than it looks.

Breaking it down: all the lines above the actual dialogue line are part of what I’ve come to refer to as the Otonashi Nickname Block. The lines below the nothings, meanwhile, are Angel’s (much smaller) nickname block of her own. Characters have their name displayed at the top of the text box when they speak, and most characters are called by a number of names over the course of the game. For who knows what reason, the developers decided that the most efficient way to handle this would be to list every single potential nickname for characters with a multitude of them above every single line of their dialogue. We know for a fact that this isn’t actually mandatory, as characters who only get called either ‘???’ or their real name (Fujimaki, Ooyama, etc.) only have a single name tag for the majority of the game, but they sure did it anyway, probably for some obtuse technical reason I haven’t considered. The ramifications are profound.

See, Otonashi has a lot of nicknames. Otonashi has a lot of nicknames. Literally every single line of Otonashi’s dialogue is proceeded by the following text:

//<1442> 音無
<1442> 音無

//<1443> クソ坊主
<1443> クソ坊主

//<1444> 代理人
<1444> 代理人

//<1445> 微妙すぎるイケメン
<1445> 微妙すぎるイケメン

//<1446> ロリコン
<1446> ロリコン

//<1447> メガネ仲間
<1447> メガネ仲間

//<1448> 暗算日本記録保持者
<1448> 暗算日本記録保持者

//<1449> 通り魔
<1449> 通り魔

//<1450> 記憶ナシ男
<1450> 記憶ナシ男

//<1451> 音速
<1451> 音速

//<1452> 無限
<1452> 無限

//<1453> エロ侍
<1453> エロ侍

//<1454> エロエロ団ナンバー1
<1454> エロエロ団ナンバー1

//<1455> ただのエロ少年
<1455> ただのエロ少年

//<1456> ユリブサイク
<1456> ユリブサイク

//<1457> ドピュッシー
<1457> ドピュッシー

//<1458> アメリカンエロドッグ
<1458> アメリカンエロドッグ

//<1459> ゼウス
<1459> ゼウス

//<1460> 日向markⅡ
<1460> 日向markⅡ

//<1461> 糞虫
<1461> 糞虫

//<1462> 量産型日向
<1462> 量産型日向

//<1463> ??
<1463> ??

EVERY. SINGLE. LINE.

That’s 65 text file lines’ worth of nicknames, and over the course of the entire game Otonashi has 11,122 lines of dialogue. In other words, throughout all the script files, 722,930 text file lines are occupied exclusively by 22 lines worth of actual translation work. That’s more than 15x the number of actual, proper script lines in the entire game, and that’s not taking into consideration Hinata, Yuri and Angel’s own nickname blocks, all of which are reasonably extensive as well. Bonus points because ドピュッシー isn’t even actually in the final game (That’s ‘Depussy’, if you’re curious, and no we have no clue what it means either beyond ‘probably a Debussy joke’. Probably not the obvious one, though, the writers 100% didn’t know enough English to pull that one off). It probably goes without saying that this renders the script borderline unreadable!

So, how did we deal with it? Naturally, an incredibly stupid problem calls for an incredibly stupid solution. I’m a big Notepad++ fan, and one of its best features is a regex compatible find/replace function. I wrote up a (ginormous) block of regex code that detected each instance of the Otonashi Nickname Block in a file, removed them, and replaced them with a single line string that contained all the data necessary to put them back later. Regex is bad at counting, see, so I had to preserve the line numbers if I wanted them back (it was only later in the process that I discovered that the line numbers do literally nothing, but that’s a story for part 3 probably). For instance, running that regex code on the file I’m writing this very post in condenses the above nightmare down to:

Otonashi Nickname Block: 1442144314441445144614471448144914501451145214531454145514561457145814591460146114621463

So basically, I’d run said code on each file when I started working on it, then run a secondary block of regex code when I was finished that took the numbers in that string in groups of four and put the full nickname block back with said numbers in their proper places. A slight snag came up where my code didn’t successfully detect nicknames with five-digit line numbers (and yes, the line numbers in this game genuinely got into the five digit range sometimes) but a bit of rewriting solved that problem without too much trouble, and it only irreparably broke the scripts if you accidentally ran them in the wrong order, so it basically worked just fine. Like I said: an incredibly stupid solution.

And that’s how we solved the problem of Otonashi’s nickname nonsense rendering the scripts borderline unreadable! With that out of the way, we could finally dig in… and discover that the scripts were still almost unreadable for a whole mess of other reasons.

Buuuut this blog’s already dragging a bit long and that’s a whole story in and of itself, so tune back in next time for part 2, in which I’ll discuss the complete, stunning, hysterical lack of any sort of coherent structure to the script as a whole, and why that made translating certain segments in-context all but impossible.

Anyway, that’s all for now! Thanks for reading this first installment of the Translators’ Corner, in which I, umm, didn’t actually discuss translation at all. Err. Yeah.

Hmm.

See you next time!

2 thoughts on “Angel Beats Post-Mortem: Part 1/4

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.