A
Albeoris
Guest
As part of the OpenVIII project, I wrote a formatter for game scripts.
The idea of pseudo-code from Deling is taken as a basis.
Deling sample:
My sample:
Just keep in mind that I didn't intend to write a replacement for Deling. We do different things. Deling allows you to edit game scripts, but my task is to make the code understandable for humans.
This formatting is done for only a third of instructions. Will we finalize it - I don't know yet. But it helped a lot in understanding the code in order to implement it in a new engine.
If it is useful to someone - use it.
For me it was an interesting experience. I plan to add support for normal scripts in FF9.
There is all of formatted field scripts:
https://yadi.sk/d/MMuojnn3VZoXDg
The idea of pseudo-code from Deling is taken as a basis.
Deling sample:
Code: [Select]
Code:
if 256_uword == 612 begin ucoff() rcanimekeep(5, 25, 1) amesw(0, 42, 160, 8) aask(0, 43, 0, 4, 0, 4, 160, 8) animesync() if temp_0 == 0 begin rcanimekeep(5, 100, 72) 1027_ubyte = 0 squall.houkoku(5, EW) animesync() ranimekeep(4) amesw(0, 45, 160, 8) else if temp_0 == 1 begin 1027_ubyte = 1 squall.houkoku(5, EW) animesync() rcanimekeep(5, 72, 25) amesw(0, 47, 160, 8) animesync() canimekeep(5, 100, 72) ranimekeep(4) amesw(0, 48, 160, 8) 1027_ubyte = 2 squall.houkoku(5, EW) animesync() rcanimekeep(6, 128, 1) amesw(0, 50, 160, 8) animesync() rcanimekeep(6, 150, 128) else if temp_0 == 2 begin 1027_ubyte = 3 squall.houkoku(5, EW) animespeed(32) rcanimekeep(7, 72, 24) amesw(0, 53, 160, 8) animesync() animespeed(16) rcanimekeep(5, 72, 20) amesw(0, 54, 160, 8) animesync() canimekeep(5, 100, 72) ranimekeep(4) amesw(0, 55, 160, 8) animesync() rcanimekeep(6, 128, 1) amesw(0, 56, 160, 8) animesync() canimekeep(6, 150, 128) rcanimekeep(5, 72, 1) amesw(0, 57, 160, 8) animespeed(32) animesync() animespeed(16) rcanimekeep(7, 50, 24) amesw(0, 58, 160, 8) animesync() rcanimekeep(7, 100, 50) else if temp_0 == 3 begin 1027_ubyte = 4 squall.houkoku(5, EW) animesync() canimekeep(5, 100, 72) rcanimekeep(6, 20, 1) amesw(0, 60, 160, 8) animesync() rcanimekeep(6, 105, 20) amesw(0, 61, 160, 8) animesync() rcanimekeep(6, 128, 105) amesw(0, 62, 160, 8) animesync() canimekeep(6, 150, 128) rcanimekeep(5, 72, 1) amesw(0, 64, 160, 8) animespeed(32) animesync() animespeed(16) rcanimekeep(7, 50, 24) amesw(0, 65, 160, 8) animesync() animespeed(32) canimekeep(7, 100, 50) animespeed(16) rcanimekeep(4, 80, 1) amesw(0, 66, 160, 8) animesync() rcanimekeep(4, 105, 80) else if temp_0 == 4 begin 1027_ubyte = 5 squall.houkoku(5, EW) animesync() rcanimekeep(5, 100, 72) amesw(0, 68, 160, 8) animesync() ranimekeep(4) amesw(0, 69, 160, 8) else end ucon() animesync()endret(8)
My sample:
Code: [Select]
Code:
public void Talk() { // ScriptId: 52 if(((UInt16)G[256] == 612)) { IGameplayService.IsUserControlEnabled = false; // UCOFF this.Animation.Play(animationId: 5, firstFrame: 1, lastFrame: 25); // RCANIMEKEEP // Headmaster Cid // “What shall we talk about?” await IMessageService.ShowDialog(channel: 0, messageId: 42, posX: 160, posY: 8); // AMESW //☞ (I want to make a report) // (The real meaning of SeeD) // (About Sorceress Edea) // (About Master NORG) //☜ (About what to do next) await IMessageService.ShowDialog(channel: 0, messageId: 43, firstLine: 0, lastLine: 4, beginLine: 0, cancelLine: 4, posX: 160, posY: 8); // AASK await this.Animation.Wait(); // ANIMESYNC if((R0 == 0)) { this.Animation.Play(animationId: 5, firstFrame: 72, lastFrame: 100); // RCANIMEKEEP G[1027] = (Byte)0; REQEW(priority: 5, GetObject<squall>().houkoku()); await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 4); // RANIMEKEEP // Headmaster Cid // “No, no. // It’s not necessary.” // “I can guess what must’ve // happened.” await IMessageService.ShowDialog(channel: 0, messageId: 45, posX: 160, posY: 8); // AMESW } else if((R0 == 1)) { G[1027] = (Byte)1; REQEW(priority: 5, GetObject<squall>().houkoku()); await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 5, firstFrame: 25, lastFrame: 72); // RCANIMEKEEP // Headmaster Cid // “SeeD is SeeD. The elite // mercenary force of {Term Balamb} Garden.” await IMessageService.ShowDialog(channel: 0, messageId: 47, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC await this.Animation.Play(animationId: 5, firstFrame: 72, lastFrame: 100); // CANIMEKEEP this.Animation.Play(animationId: 4); // RANIMEKEEP // Headmaster Cid // “Hmmm, do you know // something about SeeD?” await IMessageService.ShowDialog(channel: 0, messageId: 48, posX: 160, posY: 8); // AMESW G[1027] = (Byte)2; REQEW(priority: 5, GetObject<squall>().houkoku()); await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 6, firstFrame: 1, lastFrame: 128); // RCANIMEKEEP // Headmaster Cid // “SeeD will defeat the sorceress. // The Garden will train SeeD members.” // “The many missions around the world // are only training for the final // battle against the sorceress.” // “But now that the sorceress has become a // major threat, our true mission // has begun.” await IMessageService.ShowDialog(channel: 0, messageId: 50, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 6, firstFrame: 128, lastFrame: 150); // RCANIMEKEEP } else if((R0 == 2)) { G[1027] = (Byte)3; REQEW(priority: 5, GetObject<squall>().houkoku()); this.Animation.FPS = 64; // ANIMESPEED this.Animation.Play(animationId: 7, firstFrame: 24, lastFrame: 72); // RCANIMEKEEP // Headmaster Cid // “You’re quite right...” await IMessageService.ShowDialog(channel: 0, messageId: 53, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.FPS = 32; // ANIMESPEED this.Animation.Play(animationId: 5, firstFrame: 20, lastFrame: 72); // RCANIMEKEEP // Headmaster Cid // “She had been a sorceress since childhood. // I married her, knowing that.” await IMessageService.ShowDialog(channel: 0, messageId: 54, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC await this.Animation.Play(animationId: 5, firstFrame: 72, lastFrame: 100); // CANIMEKEEP this.Animation.Play(animationId: 4); // RANIMEKEEP // Headmaster Cid // “We were happy. // We worked together, the two of us. // We were very happy.” await IMessageService.ShowDialog(channel: 0, messageId: 55, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 6, firstFrame: 1, lastFrame: 128); // RCANIMEKEEP // Headmaster Cid // “One day, Edea began talking about // building the Garden and training SeeD.” // “I became obsessed with that plan. But // I was very concerned with SeeD’s goal, // that one day SeeD might fight Edea...” await IMessageService.ShowDialog(channel: 0, messageId: 56, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC await this.Animation.Play(animationId: 6, firstFrame: 128, lastFrame: 150); // CANIMEKEEP this.Animation.Play(animationId: 5, firstFrame: 1, lastFrame: 72); // RCANIMEKEEP // Headmaster Cid // “She laughed and told me // that would never happen.” await IMessageService.ShowDialog(channel: 0, messageId: 57, posX: 160, posY: 8); // AMESW this.Animation.FPS = 64; // ANIMESPEED await this.Animation.Wait(); // ANIMESYNC this.Animation.FPS = 32; // ANIMESPEED this.Animation.Play(animationId: 7, firstFrame: 24, lastFrame: 50); // RCANIMEKEEP // Headmaster Cid // “However...” await IMessageService.ShowDialog(channel: 0, messageId: 58, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 7, firstFrame: 50, lastFrame: 100); // RCANIMEKEEP } else if((R0 == 3)) { G[1027] = (Byte)4; REQEW(priority: 5, GetObject<squall>().houkoku()); await this.Animation.Wait(); // ANIMESYNC await this.Animation.Play(animationId: 5, firstFrame: 72, lastFrame: 100); // CANIMEKEEP this.Animation.Play(animationId: 6, firstFrame: 1, lastFrame: 20); // RCANIMEKEEP // Headmaster Cid // “He is from the Shumi tribe. // A black sheep of the tribe, one might say.” await IMessageService.ShowDialog(channel: 0, messageId: 60, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 6, firstFrame: 20, lastFrame: 105); // RCANIMEKEEP // Headmaster Cid // “We met while I was running around // trying to find funds to build the Garden.” // “He became interested in building // the Garden, and we hit it off. // Thanks to his funding, it was completed.” await IMessageService.ShowDialog(channel: 0, messageId: 61, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 6, firstFrame: 105, lastFrame: 128); // RCANIMEKEEP // Headmaster Cid // “However, we needed an enormous // amount of funds to run the Garden.” // “So we began dispatching SeeDs // around the world as a means // of supporting the Garden.” await IMessageService.ShowDialog(channel: 0, messageId: 62, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC await this.Animation.Play(animationId: 6, firstFrame: 128, lastFrame: 150); // CANIMEKEEP this.Animation.Play(animationId: 5, firstFrame: 1, lastFrame: 72); // RCANIMEKEEP // Headmaster Cid // “NORG’s idea was // right on the money.” // “An enormous amount of capital // began flowing into the Garden.” await IMessageService.ShowDialog(channel: 0, messageId: 64, posX: 160, posY: 8); // AMESW this.Animation.FPS = 64; // ANIMESPEED await this.Animation.Wait(); // ANIMESYNC this.Animation.FPS = 32; // ANIMESPEED this.Animation.Play(animationId: 7, firstFrame: 24, lastFrame: 50); // RCANIMEKEEP // Headmaster Cid // “And the Garden began to change.” // “Lost sight of our high ideals, // the truth was covered up...” await IMessageService.ShowDialog(channel: 0, messageId: 65, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.FPS = 64; // ANIMESPEED await this.Animation.Play(animationId: 7, firstFrame: 50, lastFrame: 100); // CANIMEKEEP this.Animation.FPS = 32; // ANIMESPEED this.Animation.Play(animationId: 4, firstFrame: 1, lastFrame: 80); // RCANIMEKEEP // Headmaster Cid // “That’s probably enough.” // “In the end, it was my fault, // for giving up control.” await IMessageService.ShowDialog(channel: 0, messageId: 66, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 4, firstFrame: 80, lastFrame: 105); // RCANIMEKEEP } else if((R0 == 4)) { G[1027] = (Byte)5; REQEW(priority: 5, GetObject<squall>().houkoku()); await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 5, firstFrame: 72, lastFrame: 100); // RCANIMEKEEP // Headmaster Cid // “We must stop // drifting around soon...” await IMessageService.ShowDialog(channel: 0, messageId: 68, posX: 160, posY: 8); // AMESW await this.Animation.Wait(); // ANIMESYNC this.Animation.Play(animationId: 4); // RANIMEKEEP // Headmaster Cid // “I only hope that we can get things // back to the way they were.” await IMessageService.ShowDialog(channel: 0, messageId: 69, posX: 160, posY: 8); // AMESW } else if((R0 == 0)) { // do nothing } IGameplayService.IsUserControlEnabled = true; // UCON await this.Animation.Wait(); // ANIMESYNC } return IRET(8); }
Just keep in mind that I didn't intend to write a replacement for Deling. We do different things. Deling allows you to edit game scripts, but my task is to make the code understandable for humans.
This formatting is done for only a third of instructions. Will we finalize it - I don't know yet. But it helped a lot in understanding the code in order to implement it in a new engine.
If it is useful to someone - use it.
For me it was an interesting experience. I plan to add support for normal scripts in FF9.
There is all of formatted field scripts:
https://yadi.sk/d/MMuojnn3VZoXDg
Last edited: