• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Pokemon BW: Scripting Lessons.

153
Posts
18
Years
  • Seen Jan 14, 2016
Foreward

Hi, everyone!
I've noticed that your latest effort is trying to figure out how scripting works in BW, and I want to add my contribution.
Really, I started researching about two years ago, for a future addition of PPRE, but nothing happened, and my work remained private.
Now, I want to share my knowledge about scripts with you, so let's go!
(This tutorial assumes that you know something about hex and programming)

How Nintendo Links Maps with Scripts.

In a Nintendo DS Pokemon ROM we must distinguish three differents sections of a map.

- Model Structure : 3D Graphic (BW ROM: a/0/0/8)
- Events : NPCS, Warps, Signs (BW ROM: a/1/2/5)
- Scripts: auto-explicative (BW ROM: a/0/5/7)
- Text: auto-explicative (BW ROM: a/0/0/3)

Each of sections are stored in a different archives int the ROM, apparently unlinked - this is not true.
There's actually a table (stored in RAM) that "links" all of these different files.
In a BW rom, this table is saved to the a/0/1/3 file.
Each row of this table (0x30 bytes length) represents a "gamezone".
Example:
Code:
 00 00 02 00 00 00 [B][COLOR="Red"]0a 03 [/COLOR][/B]0b 03 [B][COLOR="SeaGreen"]ac 01[/COLOR][/B] fa 03 fa 03 fa 03 fa 
03 ff ff [COLOR="Blue"][B]85 01[/B][/COLOR] 85 01 04 04 40 00 40 ec 00 00 00 00 0e 03 
00 00 00 00 00 00 ee 02 00 00

This represents the "zonedata" of Nuvema Town.
There is a lot of data in this sequence, but need to focus on:
  • Script Id = 0a 03
    Nuvema Town's script file is a/0/5/7.778.
  • Text Id = ac 01
    Nuvema Town's text file is a/0/0/3.428
  • Event Id = 85 01
    Nuvema Town's event file is a/1/2/5.389
We now have scripts, events, and text.
We just need to know how events refer to scripts, and scripts refer to events... How?
Simple: use an Identifier.
Each script, event, and text has a unique ID in its file.
So if we go to a/1/2/5.389 we can find NPC 0, 1, 2, 3 , 4...
Or if we go to a/0/0/3.428 we can find Msg 0, 1, 2, 3, 4...
And if we go to a/0/5/7.778 we can find Script 0, 1, 2, 3, 4...

Is that clear? I hope it is.
Now we analize the a/0/5/7 files, which contain scripts.

Script Structure

In a BW file, like DPP and HGSS, the scripts are divided into two main sections: declarative and command section.

Declarative Sections

Declarative part contains all "offsets" of the scripts (start offset in particular).
Each script offset is saved as a UInt32 (4 bytes), which we call "offsetPad".
To get the real offset, we need to follow this formula: reader.Position + offsetPad.
This section is terminated by 0x13FD.
Example:

Code:
 0A 00 00 00 08 00 00 00 FD 00 00 00 13 FD

This is a declarative part for a/0/5/7-0, containing 3 scripts.
1st script's offset: 0x0A + 0x04 = 0x0E
2nd script's offset: 0x08 + 0x08 = 0x10
3rd script's offset: 0xFD + 0x0A = 0x107

Command Sections

The command section contains the actual commands that will be executed by scripts.
There are 800+ different commands, but the main structure is this:

Code:
UInt16 (2bytes) - Command ID
 (Various parameters)

Lesson 1: Simple Message Script

First, we'll start with something of simple: we wanna a overworld say a simple message, like "Hello, world!".
So, after we open our file to edit, go to offset of the our script (Lesson 0 - Declarative Part) and start writing. (I'll use red for commands and blue for parameters)
So, the first command we need to insert is:

Code:
[B][COLOR="red"]002E [/COLOR][/B]

This command represents the beginning of the script.
It doesn't have any parameters. We'll call it StartScript.
After, we should want to "hear" the famous 'click' sound when talking to someone.
So, we then add that and have:

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]A600[/COLOR][/B] [B][COLOR="blue"]4705[/COLOR][/B]

This new command plays a generic sound, in this case 4705, which is the 'click' sound. If you want another sound, you can change the parameter. We will call this command PlaySound.

Now, we want to talk to a well-mannered person, so we want him/her to face us when speaking.
To do this, we'll use:

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]7400 [/COLOR][/B]

This command forces the person to face the player. We'll call it FacePlayer.

Now the for the actual message:

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]FacePlayer [/COLOR][/B]
 [B][COLOR="red"]3D00[/COLOR][/B] [B][COLOR="blue"]0004[/COLOR][/B] [B][COLOR="blue"]0000[/COLOR][/B] [B][COLOR="blue"]0000[/COLOR][/B] [B][COLOR="blue"]0000[/COLOR][/B]

This command is a little more complex. There are a lot of different commands for showing a message, but this is the simplest. Now we'll analized each parameter.
  • 0004 : Constant.
    We always need to insert it.
  • 0000 : Message Id.
    Differently from GBA games, we don't insert the offset of the message.
    In fact, each map is linked with a file of Msg.Narc ( a/0/0/3) that contains an ordered sequence of "messages". So the parameter tells us that the message is the 0x0 message in linked msg-file.
    (Later I'll give you all the association of the script-message files, I promise)
  • 0000 : Top/Bottom View.
    Indicates where the message is show on the screen. (0000 = Bottom, 0001 = Top)
  • 0000 : Type of Border.
    Indicates which type of border the message has. (0000 = Simple)
Now we have finally inserted message, but we need other commands to close the script.
First:

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]FacePlayer [/COLOR][/B]
 [B][COLOR="red"]Message[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [B][COLOR="blue"]ID=0[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]
 [B][COLOR="red"]3200 [/COLOR][/B]

This command forces the message to remain open until you click a botton.
We'll call it WaitButton.

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]FacePlayer [/COLOR][/B]
 [B][COLOR="red"]Message[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [B][COLOR="blue"]ID=0[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]
 [B][COLOR="red"]WaitButton [/COLOR][/B]
 [B][COLOR="red"]3E00[/COLOR][/B]

This command closes the message. We'll call it CloseMessage.

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]FacePlayer [/COLOR][/B]
 [B][COLOR="red"]Message[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [B][COLOR="blue"]ID=0[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]
 [B][COLOR="red"]WaitButton [/COLOR][/B]
 [B][COLOR="red"]CloseMessage[/COLOR][/B]
 [B][COLOR="red"]3000[/COLOR][/B]

I don't know what this command does, but you always need to insert it after CloseMessage.

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]FacePlayer [/COLOR][/B]
 [B][COLOR="red"]Message[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [B][COLOR="blue"]ID=0[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]
 [B][COLOR="red"]WaitButton [/COLOR][/B]
 [B][COLOR="red"]CloseMessage[/COLOR][/B]
 [B][COLOR="red"]3000[/COLOR][/B]
 [B][COLOR="red"]2F00[/COLOR][/B]

This command closes the script. We'll call it EndScript.

The last command is 0200, which ends the entire routine. So, we'll call it End.
We now have this sequence of commands to put in our Hex Editor:

Code:
[B][COLOR="red"]2E00[/COLOR][/B] [B][COLOR="red"]A600[/COLOR][/B] [B][COLOR="blue"]4705[/COLOR][/B] [B][COLOR="red"]7400[/COLOR][/B] [B][COLOR="red"]3D00[/COLOR][/B] [B][COLOR="blue"]0004[/COLOR][/B] [B][COLOR="blue"]0000[/COLOR][/B] [B][COLOR="blue"]0000[/COLOR][/B] [B][COLOR="blue"]0000[/COLOR][/B] [B][COLOR="red"]3200[/COLOR][/B] [B][COLOR="red"]3E00[/COLOR][/B] [B][COLOR="red"]3000[/COLOR][/B] [B][COLOR="red"]2F00[/COLOR][/B] [B][COLOR="red"]0200[/COLOR][/B]

The "human-friendly" version of the script is:

Code:
[B][COLOR="red"]StartScript [/COLOR][/B]
 [B][COLOR="red"]PlaySound[/COLOR][/B] [B][COLOR="blue"]CLICK[/COLOR][/B]
 [B][COLOR="red"]FacePlayer [/COLOR][/B]
 [B][COLOR="red"]Message[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [B][COLOR="blue"]ID=0[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]
 [B][COLOR="red"]WaitButton [/COLOR][/B]
 [B][COLOR="red"]CloseMessage[/COLOR][/B]
 [B][COLOR="red"]3000[/COLOR][/B]
 [B][COLOR="red"]EndScript[/COLOR][/B]
 [B][COLOR="red"]End[/COLOR][/B]

Lesson 2: Simple Message Script with variations.

There are lost of different message commands, which gives very powerful ways to say things.
Let's begin.

003D (Message)

We already saw this command, but now we look more closely at it.
The last parameter, what we called NORMAL, can be changed to give another whole aspect to the box.
Here there's a list of values that we can use:
  • 0000 : NORMAL.
  • 0001 : ANGRY.
003C

This command has a similar syntax to Message, but there is a new parameter, called NPCID, that represents the person to which the box's arrow points to.
We'll call it DirectedMessage .
The format of the command is:

Code:
[B][COLOR="red"]DirectedMessage[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [B][COLOR="blue"]ID=0[/COLOR][/B] [U][B][COLOR="blue"]NPCID[/COLOR][/B][/U] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]

We can use this command when we want that other people speak during script.

0034

This command is more simple than the other two.
It shows a message in a grey box, used mostly when you received an item.
We'll call it EventGreyMessage.
The format of the command is:

Code:
[B][COLOR="red"]EventGreyMessage[/COLOR][/B] [B][COLOR="blue"]MSGID[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B]

Important: To close this message, we need to use 0036, instead of CloseMessage.
We'll call this command CloseEventMessage.

0038

It shows a message without arrow, used mostly when we don't know who's speaking.
We'll call it BubbleMessage.
The format of the command is:

Code:
[B][COLOR="red"]BubbleMessage[/COLOR][/B] [B][COLOR="blue"]MSGID[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B]

Important: To close this message, we need to use 0039, instead of CloseMessage.
We'll call this command CloseBubbleMessage.

003A

With this command, we show a bubblemessage at specific coordinates.
We'll call it ShowMessageAt.
The format of the command is:

Code:
[B][COLOR="red"]ShowMessageAt[/COLOR][/B] [B][COLOR="blue"]MSGID[/COLOR][/B] [B][COLOR="blue"]X[/COLOR][/B] [B][COLOR="blue"]Y[/COLOR][/B]

Note: The (0,0) position is on upper-left point of screen.

0043

Shows a message with a colored border, used mostly when we read a city's sign or target.
We'll call it BorderedMessage.
The format of the command is:

Code:
[B][COLOR="red"]BorderedMessage[/COLOR][/B] [B][COLOR="blue"]MSGID[/COLOR][/B] [B][COLOR="blue"]COLOR[/COLOR][/B]

The color values are:
  • 0000 : PINK.
  • 0001 : BROWN.
  • 0002 : BLUE.
  • 0003 : GREEN.
Important: To close this message, we need to use 0044, instead of CloseMessage.
We'll call this command CloseBorderedMessage.

0045

Show a strange transparent message, like a destroyed paper.
We'll call it PaperMessage.
The format of the command is:

Code:
[B][COLOR="red"]PaperMessage[/COLOR][/B] [B][COLOR="blue"]MSGID[/COLOR][/B] [B][COLOR="blue"]X[/COLOR][/B]

This command needs some more research.

Important: To close this message, we need to use 0046, instead of CloseMessage.
We'll call this command ClosePaperMessage.

0048

This command is the same as DirectedMessage.
The only difference is another last parameter, that is always 0.
We shouldn't use it, for now.

0049

This command is similar to DirectedMessage, but with an important differences: the message changes based on if we are playing Black or White.
So we'll call it DoubleMessage

The format of command is:

Code:
[B][COLOR="red"]DoubleMessage[/COLOR][/B] [B][COLOR="blue"]MSGCONST[/COLOR][/B] [U][B][COLOR="blue"]MSGIDBLACK[/COLOR][/B] [B][COLOR="blue"]MSGIDWHITE[/COLOR][/B][/U] [B][COLOR="blue"]NPCID[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B] [B][COLOR="blue"]NORMAL[/COLOR][/B]

004A

This shows an angry Message, when we want the person to "shout",
We'll call it AngryMessage.
The format of the command is:

Code:
[B][COLOR="red"]AngryMessage[/COLOR][/B] [B][COLOR="blue"]MSGID[/COLOR][/B] [B][COLOR="blue"]BOTTOM[/COLOR][/B]

Important: To close this message, we need to use 004B, instead of CloseMessage.
We'll call this command CloseAngryMessage.

All of these commands we can use with our simple message scripts, just remember the close ht messages with the correct command!
Today's lessons are finish
Next, we'll see messages that contain variables (Like Hiro's name and other types)
Stay tuned!

pichu2000
 
Last edited:

miksy91

Dark Energy is back in action! ;)
1,480
Posts
15
Years
This is a really nice scripting guide here and I can tell you had hard time writing all this. Anyway, I've to say it's still pretty difficult to understand what you wrote before Lesson 1; how the scripts are called and all that.
Perhaps someone could help you out with this (translating your findings into good english I mean) so that you could even make a proper, well-explained compendium out of it (Example: http://hax.iimarck.us/files/scriptingcodes_eng.htm).
 
153
Posts
18
Years
  • Seen Jan 14, 2016
This is a really nice scripting guide here and I can tell you had hard time writing all this. Anyway, I've to say it's still pretty difficult to understand what you wrote before Lesson 1; how the scripts are called and all that.
Perhaps someone could help you out with this (translating your findings into good english I mean) so that you could even make a proper, well-explained compendium out of it (Example: http://hax.iimarck.us/files/scriptingcodes_eng.htm).

Hmm, I know that my English isn't perfect, and if someone could translate my work (from Italian to English) I can explain easily my findings...
But I haven't much time to make a full compendium for now, so I can release these "little" lessons...
I'm very glad if someone can help me!
 
3,830
Posts
14
Years
  • Age 27
  • OH
  • Seen Feb 26, 2024
Hmm, I know that my English isn't perfect, and if someone could translate my work (from Italian to English) I can explain easily my findings...
But I haven't much time to make a full compendium for now, so I can release these "little" lessons...
I'm very glad if someone can help me!

I don't really know very much Italian, but I'd definitely be willing to help clean up your English, if you'd like.

Anyways, this is some really interesting stuff here!
 
Last edited:
153
Posts
18
Years
  • Seen Jan 14, 2016
Thanks agentgeo, I appreciate it...
I added a better explanation on how scripts is linked with events and maps...
I hope now It's more clear xD.
 
Last edited:
Back
Top