So, this is the very first lesson. It is designed to introduce PKSV-UI to the most basic level as possible. However, before we begin, make sure you have
A GBA Emulator (I prefer VBA)
A pokemon rom (FR/LG or R/S/E are both okay, since the concept are not too different in either.)
Advance Map (Mapping/Tile tool)
PKSV-UI (Scripting Tool)
Advance Map and PKSV-UI can be downloaded in the links at the home page.
(I go in a lot of depth, so if there is stuff you already know, or you don't want most of the technical details, you can skip some parts. However, if this is your first time attempting to script, I recommend you read EVERYTHING.)
A GBA Emulator (I prefer VBA)
A pokemon rom (FR/LG or R/S/E are both okay, since the concept are not too different in either.)
Advance Map (Mapping/Tile tool)
PKSV-UI (Scripting Tool)
Advance Map and PKSV-UI can be downloaded in the links at the home page.
(I go in a lot of depth, so if there is stuff you already know, or you don't want most of the technical details, you can skip some parts. However, if this is your first time attempting to script, I recommend you read EVERYTHING.)
What is a Scipt?
A script is a written line of code generally used to allow the software to execute some commands we want.
(Click on the image to get a better view). It may look intimating (I used a custom made script for a youtube tutorial lesson, sound/music play), but PKSV-UI is not hard to learn at all. What's really neat about this tool is that if you still have trouble writing certain types of scripts, just click the 'pen and pencil' button.
It will give you a list of the type of scripts PKSV-UI can generate.
Just click on the one you want, type in the stuff the program asks you, click 'OK', and you have a generated script.
However, you can't make your own Pokemon game by just using generated scripts, or learn any scripting. That's why your here right? You want to learn about the meaning of some of the lines you see in a script? Well, look no further. I explain everything in as much depth as possible, to help you guys understand the meaning of the words you type into PKSV-UI.
Basic scripting is the easiest type of scripting: a person talking. When you talk to an NPC (clicking the 'A' button), you usually are given a dialogue box with the text.
Basic scripting is the easiest type of scripting: a person talking. When you talk to an NPC (clicking the 'A' button), you usually are given a dialogue box with the text.
That's what we will learn today. So, lets open PKSV-UI. You will come up with a blank page. Now, remember the generated 'Person Talking' script (go back to the picture if you do not). Let us explore the meaning of those command lines.
The first line you see is '#dyn 0x740000'. Now, what could this mean? In pokemon games, there are hundreds, thousands, millions, billions (maybe not that much) scripts the game uses. The game uses 'offsets' to classify the script. 'Offsets' are a combination of 6 numbers and hex letters in the game. 'Dyn' is short for "Dynamic offset". What this line does is create a new 'offset' for the game to use.
But, what about the '0x740000'? The '0x' will tell the script that we are entering a hex value, allowing the script to function. '740000' is a special offset number. Normally, you could use any random combination of 6 hex numbers and letters. However, what happens if you accidentally use an offset number that was already used in the game? You would replace that original script with your new script, and that could cause problems later on. To avoid this problem, the offset number '0x740000' will find an offset number not used in the game.
For example: if the offset 54E2AC is not used in the game, when you compile (explain this a bit later) the script, '0x740000' would find a non-used offset number. It could pick '54E2AC', and becomes '#org 0x54E2AC' in the compiled version of our script.
The next line you see is '#org @start'. What could this mean? Well, it's also an offset number. Now, this offset is also unique in it's own way. This offset number is the offset number of your script. In your version of the script, '#org' will define a specific offset for the script to use. '@(word)' can be anything. You can use '#org @main'(which is what I use a lot), '#org @begin',' #org @cookies', etc. Just make sure to be sure that when you are defining an '@' offset (which we will discuss later), it is EXACTLY the same spelling (I don't know about case sensitivity, but make identical offsets case sensitive to be safe) as the definition of the offset (I'll explain more about this later).
'Lock' and 'Faceplayer' require less explanation, so I will merge the 2 commands in one paragraph. In the game, neither the player nor the NPC being talked to ever 'moves' while a dialogue box is showing. To prevent any character from moving, 'Lock' will 'lock' the characters involved in an event (talking in this case), to prevent them from moving.
'Faceplayer' is just as straightforward as it sounds: make the NPC FACE the PLAYER when talking. With this command, the person you are talking to in the game will always 'face' you.
'Msgbox @text ' Hi, I'm a cow[.]\nMoo.' is the 'message' you see in the game when you talk to an NPC. As you can guess, 'Msgbox' (you can also write 'message', which is what I prefer and will use) will tell the game to open a 'message box'. You once again see the '@(word)' offset. Now, remember when I told you to make sure when you determine the offset's value, you want to spell the 2 offsets EXACTLY THE SAME? Now I will go in more depth. If you go to the very last line of text in the script, you see a line
#org @text
= I'm a cow[.]\nMoo.
In the 'message' line, all you stated was to make a 'message box' with the values of '@text'. However, you never specified what '@text' is. At the bottom of the script, you clarify what '@text' is, which are the 2 lines listed above in red. Make sure the spelling, case, number, letter, symbols, EVERYTHING is exactly the same for the offset value (@text), or else you will be defining the value of an offset that doesn't exist in your script, and also not classifying what the offset is that you are using in the script.
Now, you may be wondering what the lines in green are (' I'm a cow[.]\nMoo.) Other than a single quote, you'll notice that the text is exactly the same as the '#org @text'. All that is happening is that the single quote is defining what the '@text' is. When you see green text, it means that is just for the scripter to see, and will not be seen in the game.
(Tip: If you use the double slash '//', you will be able to insert comments into the script. This is very handy to use, especially if your script contains a lot of lines. Only the person reading the script can see the comments, and the comments will not be seen in the game).
Now, we have 'callstd MSG_NOMRAL'. After you use a 'message' command, you have to classify the 'type' of 'message' you want to use. There are many types of messages used in the game (sign, yes no questions, etc.).
'Release' and 'End' are the last two lines to describe. After the script is over, you will not be able to move, because you are still 'locked'. So, how will you fix this? Yes, 'Release' is the opposite of 'Lock'. 'Release' will 'release' the player from 'lock', to allow the player to move again. But, what does 'End' do? Well, when you see something like 'End', you can probably guess that it signals that the script is going to 'end'. 'End' will finish the script, and allow the player to move/run/battle pokemon again after the script is over. If you do not have an 'End', the game will think the script is not over, and your game will freeze (not allowing you to do anything, just stare at a screen that will never change, making you reset your rom).
*Phew*, that's about as in depth I can get about a couple of commands in PKSV-UI. Now, no more stalling. Lets write our own script.
Our Goal: Make a person say 'This is my text.' in the game.
Okay, so open PKSV-UI (if you haven't already). However, we need to tell PKSV-UI which rom we want to add offsets to. So first, after you have PKSV-UI open, at the top of the window (with the tabs), click on ROM->Open Rom. Afterward, just select which rom you want to open.
Lets write our first line. We need to give the script a 'dynamic offset', so a new offset number can be put into the game for our script.
#dyn 0x740000
Next, we need to classify our "script's offset'. You can use any word. I use '@main', since I like that offset.
#org @main
Afterwards, we need to make sure the player and the NPC cannot move around while talking, and the NPC will face the player when talking.
Lock
Faceplayer
Now, we need the message box to appear in the game, along with the text that will be displayed. For now, we will just set the offset that the text will be, and worry about the actual text later.
message @talk
Next, we need to classify the type of 'message' we want. Since this is just a basic talking script, we will use 'normal' message.
callstd MSG_NORMAL
Now that the main part of the script is done, we can end the script. However, before we end the script, we need to 'release' the player from the 'lock'. Afterward, we can 'end' the script.
Release
End
Now that the main part of the script is done, lets classify the text offset (@talk for my case). So, we will write that "@talk is equal to 'This is my text.'"
#org @talk
= This is my text.
Make sure to add a space in between the '=', and the first letter of your dialogue. So, the final version of the script should look like this
#dyn 0x740000
#org @main
lock
faceplayer
message @talk
callstd MSG_NORMAL
release
end
#org @talk
= This is my text.
(Here's my file. Compare my script to yours. Other than some stuff like the text offset, it should be mostly the same).
The first line you see is '#dyn 0x740000'. Now, what could this mean? In pokemon games, there are hundreds, thousands, millions, billions (maybe not that much) scripts the game uses. The game uses 'offsets' to classify the script. 'Offsets' are a combination of 6 numbers and hex letters in the game. 'Dyn' is short for "Dynamic offset". What this line does is create a new 'offset' for the game to use.
But, what about the '0x740000'? The '0x' will tell the script that we are entering a hex value, allowing the script to function. '740000' is a special offset number. Normally, you could use any random combination of 6 hex numbers and letters. However, what happens if you accidentally use an offset number that was already used in the game? You would replace that original script with your new script, and that could cause problems later on. To avoid this problem, the offset number '0x740000' will find an offset number not used in the game.
For example: if the offset 54E2AC is not used in the game, when you compile (explain this a bit later) the script, '0x740000' would find a non-used offset number. It could pick '54E2AC', and becomes '#org 0x54E2AC' in the compiled version of our script.
The next line you see is '#org @start'. What could this mean? Well, it's also an offset number. Now, this offset is also unique in it's own way. This offset number is the offset number of your script. In your version of the script, '#org' will define a specific offset for the script to use. '@(word)' can be anything. You can use '#org @main'(which is what I use a lot), '#org @begin',' #org @cookies', etc. Just make sure to be sure that when you are defining an '@' offset (which we will discuss later), it is EXACTLY the same spelling (I don't know about case sensitivity, but make identical offsets case sensitive to be safe) as the definition of the offset (I'll explain more about this later).
'Lock' and 'Faceplayer' require less explanation, so I will merge the 2 commands in one paragraph. In the game, neither the player nor the NPC being talked to ever 'moves' while a dialogue box is showing. To prevent any character from moving, 'Lock' will 'lock' the characters involved in an event (talking in this case), to prevent them from moving.
'Faceplayer' is just as straightforward as it sounds: make the NPC FACE the PLAYER when talking. With this command, the person you are talking to in the game will always 'face' you.
'Msgbox @text ' Hi, I'm a cow[.]\nMoo.' is the 'message' you see in the game when you talk to an NPC. As you can guess, 'Msgbox' (you can also write 'message', which is what I prefer and will use) will tell the game to open a 'message box'. You once again see the '@(word)' offset. Now, remember when I told you to make sure when you determine the offset's value, you want to spell the 2 offsets EXACTLY THE SAME? Now I will go in more depth. If you go to the very last line of text in the script, you see a line
#org @text
= I'm a cow[.]\nMoo.
In the 'message' line, all you stated was to make a 'message box' with the values of '@text'. However, you never specified what '@text' is. At the bottom of the script, you clarify what '@text' is, which are the 2 lines listed above in red. Make sure the spelling, case, number, letter, symbols, EVERYTHING is exactly the same for the offset value (@text), or else you will be defining the value of an offset that doesn't exist in your script, and also not classifying what the offset is that you are using in the script.
Now, you may be wondering what the lines in green are (' I'm a cow[.]\nMoo.) Other than a single quote, you'll notice that the text is exactly the same as the '#org @text'. All that is happening is that the single quote is defining what the '@text' is. When you see green text, it means that is just for the scripter to see, and will not be seen in the game.
(Tip: If you use the double slash '//', you will be able to insert comments into the script. This is very handy to use, especially if your script contains a lot of lines. Only the person reading the script can see the comments, and the comments will not be seen in the game).
Now, we have 'callstd MSG_NOMRAL'. After you use a 'message' command, you have to classify the 'type' of 'message' you want to use. There are many types of messages used in the game (sign, yes no questions, etc.).
'Release' and 'End' are the last two lines to describe. After the script is over, you will not be able to move, because you are still 'locked'. So, how will you fix this? Yes, 'Release' is the opposite of 'Lock'. 'Release' will 'release' the player from 'lock', to allow the player to move again. But, what does 'End' do? Well, when you see something like 'End', you can probably guess that it signals that the script is going to 'end'. 'End' will finish the script, and allow the player to move/run/battle pokemon again after the script is over. If you do not have an 'End', the game will think the script is not over, and your game will freeze (not allowing you to do anything, just stare at a screen that will never change, making you reset your rom).
*Phew*, that's about as in depth I can get about a couple of commands in PKSV-UI. Now, no more stalling. Lets write our own script.
Our Goal: Make a person say 'This is my text.' in the game.
Okay, so open PKSV-UI (if you haven't already). However, we need to tell PKSV-UI which rom we want to add offsets to. So first, after you have PKSV-UI open, at the top of the window (with the tabs), click on ROM->Open Rom. Afterward, just select which rom you want to open.
Lets write our first line. We need to give the script a 'dynamic offset', so a new offset number can be put into the game for our script.
#dyn 0x740000
Next, we need to classify our "script's offset'. You can use any word. I use '@main', since I like that offset.
#org @main
Afterwards, we need to make sure the player and the NPC cannot move around while talking, and the NPC will face the player when talking.
Lock
Faceplayer
Now, we need the message box to appear in the game, along with the text that will be displayed. For now, we will just set the offset that the text will be, and worry about the actual text later.
message @talk
Next, we need to classify the type of 'message' we want. Since this is just a basic talking script, we will use 'normal' message.
callstd MSG_NORMAL
Now that the main part of the script is done, we can end the script. However, before we end the script, we need to 'release' the player from the 'lock'. Afterward, we can 'end' the script.
Release
End
Now that the main part of the script is done, lets classify the text offset (@talk for my case). So, we will write that "@talk is equal to 'This is my text.'"
#org @talk
= This is my text.
Make sure to add a space in between the '=', and the first letter of your dialogue. So, the final version of the script should look like this
#dyn 0x740000
#org @main
lock
faceplayer
message @talk
callstd MSG_NORMAL
release
end
#org @talk
= This is my text.
(Here's my file. Compare my script to yours. Other than some stuff like the text offset, it should be mostly the same).
person_talking_script.pks | |
File Size: | 0 kb |
File Type: | pks |
Now, congratulations, you have written a script! However, the script is useless right now. Yes, sadly the game will not be able to use the script right now. Why? Because the computer can't understand your 'script'. It's like trying to communicate with someone in a language they don't know. The only way to be able to communicate would be to translate the language to a language they do know. In programming and scripting, we call that translation 'compiling '. When you compile your script, you will translate your script into a language the computer can read and use. So go ahead, compile your script. Click on the little 'gear' button to compile your script (or press F9).
After you click on that button, you will get a little pop up that shows your compile log. If there was an error in your script, your log will tell you where your script went wrong.
Scroll down your 'compiler log' until you find the offset of your script (@main for the script we wrote). You will see an offset number next to our offset value. Copy down that number, since we will need it. You can also go to the 'Dynamic Offsets' message window next to your compile log, and find the offset that way as well.
Now we can add this script into the game. So first, open AdvanceMap (it's icon is a green pokeball with spider legs).
Select File->Load Rom, and open the exact same rom you opened in PKSV-UI.
You should now see some new things in the giant white area to the left.
'From Header', 'Connection List', and 'Map Files' are the 3 categories in the new white area. Lets edit Pallet Town, since it's the first town you start off with, so you can quickly check if your script works in game. Click on 'From Header'->'3'->'PALLET TOWN (3.0)' You should see the map of Pallet Town in the giant white box area. Above the map, there are five tabs:Map, Movement Permissions, Events, Wild Pokemon, and Header. Click on 'Events', and you will see a bunch of colorful boxes all over the map. If you want to see how the NPCs look like in the game, click on the giant 'playable boy from pokemon emerald' button. Now, go to the very right, and scroll to the bottom. You will see 'Amount of Events', all the type of events and the amount in the map. Lets add another person event. Click on the little up arrow for the 'Number of Person Events', and then click 'Change Events'.
You should get a new person (the boy player sprite) in the very top left corner. Drag the NPC to a place on the map where you can get to, and change the sprite image with 'Picture no.' in the right side section if you like. After that, find the line in the right column that says 'Script offset', following by '$00000000'. That is what determines what script the person has. Now, just copy paste the offset number you got from PKSV-UI (if you didn't copy the offset number or just don't have it, compile the script again, and get the offset number) over the last 6 zeros. Don't touch the first 2 zeros. After you input your script offset, the 'Open Script' button should be click-able. If you want to double-check your script after you compiled (which I highly recommend), just open your script. The script will not look exactly like the script you wrote (all of you '@' offsets will be replaced with the 6 number and hex offsets, and some stuff change), but the general stuff should be the same.
After you checked your script, and made any changes (compile the changed script), click on the GBA game card with an arrow pointing down in the top section of Advance Map (with all the pictures), to save your game.
Note: Create backup files often, so in case you accidentally screw up your rom, you don't have to lose all your files.
After you save, open your 'hacked' rom file, and find the person with the script you wrote. Try talking to the person. If you see your script written correctly, then you did everything correctly.
Note: Create backup files often, so in case you accidentally screw up your rom, you don't have to lose all your files.
After you save, open your 'hacked' rom file, and find the person with the script you wrote. Try talking to the person. If you see your script written correctly, then you did everything correctly.
And that is basic text scripting. However, there is one more aspect I would like to address. As you noticed, a pokemon message box has 2 lines, with about 35 characters for each line. If you type a message that is too long, your message will go out of the border of the message box. So, how would you fix this?
There are 3 commands you can use: '\n', '\p', and '\l'. If you remember the generated 'person talking' script, there was a '\n' in the script.
Using '\n' will tell the game to break the message, and start in a new line.
For example: 'This is my text.\nThis is also my text.' will become
This is my text.
This is also my text.
Use '\n' only once per box. After you used one '\n', use a '\p before using another '\n'.
Using '/p' will make the little red arrow in the dialogue box appear to scroll to a new set of messages.
For example: 'This is my text.\nThis is also my text.\pI can say even more.' will become
This is my text.
This is also my text. (little red arrow pointing down)
(when a button is pressed)
I can say even more.
(blank line)
Use '\p' when you have no more room in your dialogue box, and you want the person to say more.
Using '\l' will also make the little red arrow appear in the message box, but when you press a button, the next line will automatically scroll down. This means that you won't get a 'full' message box, as only the next line of text will appear.
For example: 'This is my text.\nThis is also my text.\lI can say even more.' will become
This is my text.
This is also my text. (little red arrow)
(when a button is pressed)
(This is also my text. will remain in the dialogue box)
I can say even more.
Since '\l' is a scrolling option, you use have used a '\n' before using a '\l'. This one is a bit hard to explain, so try playing with this command yourself.
New Goal: Make the NPC say about 3 boxes worth of text.
Okay, so lets make another script to make the person say more than ever. Type up the original script we made. Now, for the text offset, lets make the NPC talk about his/her hobbies.
(I will make the NPC talk about enjoying bird watching. I recommend you try to write your own dialogue, rather than just copy me. Use my script as a reference.)
I want the NPC to say:
I love to watch birds.
Birds are very amazing animals.
Did you know some birds can't fly?
I want to see all the birds I can
(auto scroll)
Oh sorry, I got so caught up. Bye.
I won't show you my final script. I want you guys to try and write your own. However, if you tried, and continued to get errors no matter how hard you tried, you can download my script for this exercise.
There are 3 commands you can use: '\n', '\p', and '\l'. If you remember the generated 'person talking' script, there was a '\n' in the script.
Using '\n' will tell the game to break the message, and start in a new line.
For example: 'This is my text.\nThis is also my text.' will become
This is my text.
This is also my text.
Use '\n' only once per box. After you used one '\n', use a '\p before using another '\n'.
Using '/p' will make the little red arrow in the dialogue box appear to scroll to a new set of messages.
For example: 'This is my text.\nThis is also my text.\pI can say even more.' will become
This is my text.
This is also my text. (little red arrow pointing down)
(when a button is pressed)
I can say even more.
(blank line)
Use '\p' when you have no more room in your dialogue box, and you want the person to say more.
Using '\l' will also make the little red arrow appear in the message box, but when you press a button, the next line will automatically scroll down. This means that you won't get a 'full' message box, as only the next line of text will appear.
For example: 'This is my text.\nThis is also my text.\lI can say even more.' will become
This is my text.
This is also my text. (little red arrow)
(when a button is pressed)
(This is also my text. will remain in the dialogue box)
I can say even more.
Since '\l' is a scrolling option, you use have used a '\n' before using a '\l'. This one is a bit hard to explain, so try playing with this command yourself.
New Goal: Make the NPC say about 3 boxes worth of text.
Okay, so lets make another script to make the person say more than ever. Type up the original script we made. Now, for the text offset, lets make the NPC talk about his/her hobbies.
(I will make the NPC talk about enjoying bird watching. I recommend you try to write your own dialogue, rather than just copy me. Use my script as a reference.)
I want the NPC to say:
I love to watch birds.
Birds are very amazing animals.
Did you know some birds can't fly?
I want to see all the birds I can
(auto scroll)
Oh sorry, I got so caught up. Bye.
I won't show you my final script. I want you guys to try and write your own. However, if you tried, and continued to get errors no matter how hard you tried, you can download my script for this exercise.
person_talks_more_script.pks | |
File Size: | 0 kb |
File Type: | pks |
After you got your script offset, put it into the game with Advance Map, save, and try the script in the game.
If you got everything correct, congratulations, you have mastered 'basic talking' scripts. If you got an error, review the information in here (it's a lot, since I like to go into detail to make sure I didn't lose anyone). Now, when you do master this lesson, go to the next lesson, "Yes/No Questions".