Welcome to the PokéCommunity!

Hi there! Thanks for visiting PokéCommunity. We’re a group of Pokémon fans dedicated to providing the best place on the Internet for discussing ideas and sharing fan-made content. Welcome! We’re glad you’re here.

In order to join our community we need you to create an account with us. Doing so will allow you to make posts, submit and view fan art and fan fiction, download fan-made games, and much more. It’s quick and easy; just click here and follow the instructions.

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.

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:

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:

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:

002E

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:

StartScript A6004705

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:

StartScript PlaySoundCLICK7400

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

Now the for the actual message:

Code:

StartScript PlaySoundCLICKFacePlayer 3D000004000000000000

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)

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:

DirectedMessageMSGCONSTID=0NPCIDBOTTOMNORMAL

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:

EventGreyMessageMSGIDBOTTOM

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:

BubbleMessageMSGIDBOTTOM

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:

ShowMessageAtMSGIDXY

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:

BorderedMessageMSGIDCOLOR

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:

PaperMessageMSGIDX

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:

DoubleMessageMSGCONSTMSGIDBLACKMSGIDWHITENPCIDBOTTOMNORMAL

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:

AngryMessageMSGIDBOTTOM

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!

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).

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!

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!

The PokéCommunity

Meta

Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, or The Pokémon Company International. We just love Pokémon.