This document describes Valkyria engine reverse-engineering process. This manual assumes, that you already unpacked scripts. Commands arguments meaning are reversed by examining Mahou Shoujo Erena script.
mkdir utf8
for f in *; do iconv --verbose -f SJIS-WIN -t utf-8 $f > utf8/$f; done;
grep -ohEr "%[^\(]{1,}" . | cut -c 2- | sort | uniq
grep -ohrE "SetSE\(.{0,}[0-9]{1,4}" . | cut -c 6- | awk '{$1=$1};1' | sort | uniq
- 0000 (empty)
- 0014 (empty)
- A LOT...
Mostly these BGs is a wiered green screen
- 0005
- 0010
- 0025
- 0026
- 0082
- 0083
- 0351
- 0352
- 0353
AddCount(counterIndex, value) // counterIndex=3, var2=1 // Increments counter CP_Start() // Memory scene start CP_End() // Memory scene end CallScript ( scriptNumber ) // Load script and then jumps to it's start CallScript ( var1, var2, var3 ) // Used in menu scripts to do some jumps ChangeBackGround (backgroundIndex, var1, var2) // var1=1,2 var=0,1 ChangeCharactor(charactorIndex, x1, y1, x2(?),y2(?), resX(?), resY(?), var1, var2) var1=0,2 (show time?) var2=0,1 (charactor number on scene?) EraseCharaAll(var1, var2) // var1=3, var2=0 args EraseCharactor(var1, var2) //var1=2, var2=0,1 (charactor number on scene?) EraseMenubar() // Menu only. EraseMessage(var1) var1=0 EraseNameWindow(var1) //var1=0,1 EraseWindow(var1) // var1=0,2 FadeIN (var1) //var1=0 FadeIN (var1, timeS) // Menu only. timeS=2,3 var2=0 FadeOUT (backgroundIndex, var2, var3) // backgroundIndex=0008,0009(black,white respectively), timeS=0,1,2,3, var3=0 Game_END (used only once) GetCount(counterIndex, value) // Jumps to #0 if counter equal to value, otherwise jumps to #1 (TODO: check) GetLAverage(var1,var2,var3) // Menu only. Convert to percentage comment in code GetLOmake+ (var1, var2, var3) // Menu only. Loop and check flags comment in code GetOmake(flag1, flag2) // Menu only. Check flag. Jumps to #0 if true, otherwise jumps to #1 LoadScript(scriptNumber) // Loads script to memory (after current script is finished, executes loaded script) MoveAll(var1) // var1=1 ReleaseScript() // Used twice in menu code... Reset() // Used only in menu, maybe resets variables, etc. SetBGM(bgmIndex) // Play music SetBackGround(backgroundIndex, var1, var2) //var1=0, var2=0 May not affect? SetBuffer(var1) //var 1=0,0001 SetCVEx(voiceIndex, charaNum) //charaNum=0,1,2,3 // Play voice. charaNum corresponds with the snd/data__.odn archive (on Mahou Shoujo Erena) SetCount(var1,var2) //var1=3, var2=1 (used only once) SetEffect(var1, var2 ,timeMs) //var1=2, var2=1, timeMs=500,1000 // 2,1 - shaking SetInitialize("", "", "", "") (used only once) SetLCount(varIndex, value) // Set variable? SetMenu( scriptNumber ) // Jump to menu... script. SetMenu( x, y, w, h, activeBtnImgX, activeBtnImgY, actionScript, btnIndex ) // Adds button to menu SetMenubar ( scriptNumber, menubarText ) // Menubar return button? SetMessage(messageText, colorR, colorG, colorB) // The most useful command. Displays VN messages SetMode(modeIndex) modeIndex=0(game),1,17,23 SetNameWindow(charaNum,var2) // Sets charactor name sprite from image file. //charaNum=0-18 //var2=0 SetOmake(flagNumber) // sets flag. For gallery? SetOptionSetup (used only once) SetRButton(var1) // Menu only. var1=0008,0009,0010 SetSE(seNumber) // Play Sound Effect SetSaveSysSetup(var1,var2) Only menu. Used only once. var1=14, var2=16 SetSelectEx(choice1Text, choice2Text, var1) // Displays choices. var1 are always 2 (maybe 2 choices). Jumps to #-indexed choice (0 or 1) SetTitle(chapterText) //Sets chapter name (for saves) SetURL(urlText) // Set URL for open in browser (maybe, do open command) SetWait(timeoutMs, skipable=0) // wait. When skipable=1, timeout can be skipped. SetWindow(var1, var2) //var1=2, var2=1,10 StopBGM(var1) //var1=2
grep -r "commandname" .
- data00 - background images
- data01 - foreground images
- data02 - main script and menu logic
- data03 - BGM
- data04 - sound effects
- data05 - not opens
- data06 - menu elements positions
for f in data03/*; do mv $f data03/bgm$(basename $f | cut -c 5-); done;
for f in data04/*; do mv $f data04/sfx$(basename $f | cut -c 5-); done;
for i in {0005..0084}; do mv data$i.png erena\ $i.png; done;
for i in {0085..0116}; do mv data$i.png emiru\ $i.png; done;
for i in {0117..0127}; do mv data$i.png karen\ $i.png; done;
for i in {0128..0139}; do mv data$i.png ovi\ $i.png; done;
for f in ~/erena/data02_utf8/gamescript/*; do ~/erena_workspace/convertValkyria.py $f ~/Mahou\ Shoujo\ Erena/game/gamescript/$(basename $f).rpy; done;
for f in ~/Mahou\ Shoujo\ Erena/game/gamescript/scrp*.rpy; do ~/erena_workspace/replaceTranslation.py ~/erena_workspace/translate_names.csv "$f"; done;
for f in ~/Mahou\ Shoujo\ Erena/tl/Lang/gamescript/scrp*.rpy; do ~/erena_workspace/replaceTranslation.py ~/erena_workspace/translate_pair.csv "$f"; done
- Convert entire script to UTF-8
- Separate menu logic from main gamescript
- Convert gamescript to RenPy (convertValkyria.py). If you already have translate_names.csv file, names will be replaced to aliases, then do p.6, p.10
- Extract charactors' names string literals from script and place it in translate_names.csv file, assign aliases to its
- Replace charactors' names string literals to its aliases (replaceTranslation.py)
- Generate translation via RenPy
- And extract dialogs to table
- Translate game (by MTL or manually)
- Make original text - translated text dictionary table (pairTranslation.py)
- Inject translation into RenPy's tl scripts (replaceTranslation.py)