View Single Post
Old September 22nd, 2009 (6:22 PM). Edited February 26th, 2012 by Full Metal.
Full Metal's Avatar
Full Metal Full Metal is offline
C(++) Developer.
  • Silver Tier
Join Date: Jan 2008
Location: In my mind.
Age: 22
Gender: Male
Nature: Timid
Posts: 806

Scripting is just sticking one command ontop of another.
Each command does something different.
Usually, just reading the command name tells you what it does.
Every script is stored at an "offset"
An offset is just a number representing a place in your ROM
So if you store your script in 0x800000, then that's your offset
In order to store your script you must know where to put it.
Well...I usually cheat and let PKSV decide for me xD
This is called DYNAMIC offsets, and for this tut, we will only use these
Dynamic offsets work like this
[Commands start now]
#dynamic OFFSET
[No more commands]
OFFSET is just where PKSV starts looking for a place to store your script
Usually, I use "#dynamic 0x740000"
That is where a good chunk of free space begins, so we hackers like to use it
Comments (stuff that PKSV will ignore) are allowed after a single spoiler character ( ' )
uncommmentedd and creating bugs 'Commented, but not making bugs
lock 'Locks our player
faceplayer 'look at player
PKSV can be found HERE!

Hello World!

A script always starts somewhere
So we'll declare a script like this

#dynamic 0x740000
#org @start
'pretty simple

"#org @start" is declaring a dynamic label.
the "@start" part of your script is dynamically placed in your ROM based on the offset PKSV
found when you used "#dynamic 0x740000"
This is how you store an offset to anything
if you call a message the syntax looks like this
message @textlabel

#org @textlabel
= Text...what else? xD

cripts, Text, Movements, and Pokemart data are all called in the above manner

Okay, whenever you talk to someone you don't want them wondering all over the place right?
Wouldn't it be nice to lock them down in chains?
Well now you can! With this awesome command your players will never move again!
What is the command you ask? Simple!
But that's not all, you also want the speaker to look at the talker right?
This one is simple to!
that's it!
Now there are two parts to displaying a message
Loading the message
And showing it
“message @textlabel” will load the message stored in your textlabel
“callstd MSG_NORMAL” will show the message just loaded in normal format
So now you've shown a message, great!
But..your player can't move anymore!, atleast, not yet anyways
Before the player can move again, he/she has to be “released” from the “lock” we put on them
the command to do this is
and finally, to prevent a crash of your ROM we will put
“end” is a necessity to your script, just always keep it there and you'll be good to go!

So to put it all together

#dynamic 0x740000 'Start looking at 0x740000
#org @start 'This is our start label for our script
lock ' Keep player from moving
faceplayer ' Make the speaker face the player
message @offset1 'load the text in the offset1 label into memory
callstd MSG_NORMAL 'show the message in memory
release 'Let our player move again
end 'End the @start label of our script

#org @offset1 'This is our text label
= So you got it to work eh?\nGood Job! 'I'll explain this in just a second I promise

There are problems with text being to long.
The messagebox can hold a max of about 35 characters per line, and 2 lines per “box”
So there are “symbols” to get around this

\n The text following will be in a new line
\l scrolls the bottom line up, and adds the following text in a new line (use only after \n)
\p starts a new box
\v\h01 Players name
\v\h02 buffer 0
\v\h03 buffer 1
\v\h04 buffer 2
\v\h05 buffer 3
\v\h06 Rivals name

which means
So you got it to work eh?\nGood Job! Would display as

So you got it to work eh?
Good Job!


In order to variate your message you just have to change a single command
callstd 2 This will rid you of needing a “lock” , a “faceplayer” , or a “release”

#dynamic 0x740000
#org @main
message @text
callstd 2 'Or 0x2, 0x just means it's in hex, without it use decimal numbers
#org @text
= Text

As opposed to...
#dynamic 0x740000
#org @main
message @text
callstd MSG_NORMAL
#org @text
= Text

callstd 3 commonly used for signs
nothing special, displays the message and thats it

callstd 4 ensures that the message won't go away until the command “closemsg” is called

message @txt
callstd 4 'Could also use MSG_NOCLOSE....
callstsd 5 (AKA MSG_YESNO)
displays your message and a yes/no dialog
to find out what the player pushed
add the following
#dynamic 0x740000
#org @main
message @question
callstd MSG_YESNO
if 0x1 jump @pushy
jump @pushn

#org @pushy
[…]' Do stuff if they pushed yes

#org @pushn
[...]'Do stuff if they pushed no

2 new commands were introduced here
jump- continues script somewhere else
jump also has a similar, call, call is used to go to a script, but still comeback (using the command “return” instead of “end”)

if (value) (command) (label)

callstd MSG_YESNO
if 0x1 jump @pushy 'This will jump to pushy if the value returned from yes/no box is 1
jump @pushno

since we aren't using “Call” there is no need for an “end” command in our main script, instead place the end command in the places where the script would actually end (in this case it is pushn and pushy) Also, since the script would continue at pushy if the user pushed yes, then there is no need to waste space with another if statement. Instead, just use “jump @pushno” since you know the only other possibility is that the user pushed no.

Giving Things.

In this lesson we will learn how to
give AND take items
give pokemon
give eggs

the commands for each are simple
giving a pokemon:
addpokemon PokemonName (level) itemname (0) (0) (0)
addpokemon BULBASAUR 25 00 0 0 0'Gives a level twenty five bulbasaur, not holding 'an item
addpokemon PIKACHU 25 LIGHTBALL 0 0 0 'Gives a level 25 pikachu holding a 'lightball
just always ALWAYS ALLLLLWWAAAYYSS remember to add three '0's

giving an item:
additem itemname (amount)
additem POKEBALL 50 'Gives 50 pokeballs to the player
giving an egg:
giveegg PokemonName
giveegg Pichu 'Gives us a pichu egg


flags are amazingly useful, the equivalent of BOOLEAN values in C/C++
They allow you to do an event ONLY once, do it again when something happens, etc
This time I'll start with an example first
#dynamic 0x740000
#org @main
checkflag 0x200
if 0x1 jump @haveit
message @want
callstd MSG_YESNO
if 0x1 jump @pushedyes
jump @pushedno

#org @haveit
message @howsit
callstd MSG_NORMAL

#org @pushedyes
setflag 0x200
giveegg PICHU
message @herego
callstd MSG_NORMAL

#org @pushedno
message @dontwant
callstd MSG_NORMAL

#org @want
= Hey, do you want this Pichu egg?

#org @howsit
= Here you go!\nPlease raise it well.

#org @dontwant
= Oh, ok. Maybe someone else will take it.

Setflag – This will make checkflag return 1
Clearflag – This will make checkflag return 0
Checkflag-- This will compare a flag for it being raised,or lowered. Afterwards you want to add “if 0x1 [jump/call] @[scriptlabel]”


The pokemon games have lots of spots in the GBA memory to store numeric values in. These are called “variables”

setvar 0x[varnumber] 0x[value] –That sets the [varnumber] to be [value]
subtractvar 0x[varnumber] 0x[value] – Subtracts [value] from [varnumber] variable
addvar 0x[varnumber] 0x[value] – Adds [value] to [varnumber] variable
compare 0x[varnumber] 0x[value] – Returns 1 if [varnumber] is set to [value] again, useage of the if statement is used
compare 0x8000 0x3
if 0x1 [jump/call] [label]
resetvars – Resets the variables 0x8000 through 0x8001
storevar 0x[buffernumber (\v\h02-\v\h05)] 0x[varnumber]
This can be used in loops as in this example
#dynamic 0x740000
#org @main
setvar 0x4000 0x20
setvar 0x4001 0x0
jump @loop

#org @loop
subtractvar 0x4000 0x4001
storevar 0x0 0x4000
message @reps
callstd MSG_NORMAL
addvar 0x4001 0x1
compare 0x4001 0x20
if 0x1 jump @end
jump @loop

#org @end

#org @reps
= Only \v\h02 loops to go!

There is a new command introduced here again
storevar 0x[buffernumber] 0x[varnumber]
If you use 0x0 for buffernumber the variable is stored in \v\h02, 0x1 means \v\h03, etc until you get to \v\h05 and 0x3

While the above method works, there is a new feature in PKSV that makes everything much more efficient.
#dynamic 0x740000

#org @main
setvar 0x8010 0x5
message @start
callstd MSG_NORMAL
fadesong 265
pause 0x50
compare 0x8010 0x1
if == jump @if1
storevar 0x1 0x8010
message @loopmsg
callstd MSG_NORMAL
subtractvar 0x8010 0x1
compare 0x8010 0x0
if == jump:-loop
jump :loop

message @done
callstd MSG_NORMAL

#org @if1
message @crud
callstd MSG_NORMAL
jump :skip

#org @start
= \v\h01 turned on the SNES

#org @loopmsg
= \v\h03 lives left

#org @crud
= Oh crud, I only have one live left!

#org @done
= \v\h01 got a gameover\ntime to quit!

There are now two types of labels for PKSV. There is one that works like we've discussed so far. These are the '@' labels we've been using.There is also another way.
A ' : ' label is used within an '@' label. It is simply a way to start a script from somewhere other than the beginning, and you can use them just like you would an '@' label.
#org @mainoffset
lock ' this is one byte
faceplayer ' this is another byte
:label ' this label is at the mainoffset+2 bytes, so if you jump to :label, then it will skip
' Lock and faceplayer commands, but doesn't take up space itself.

There were also two new commands from the above example
fadesong [song number] – fades the current song that's playing into the sappy song number
fadedefault – Fades the song back to the default song for the map


there are also more things to store in a buffer
they are always preceded with “storeZZZ” where ZZZ can be replaced with attack,boxname,comp,firstpokemon,furniture,item,it ems,pokemon,pokemonvar,or text
the arguments are the same for storevar and can be called just the same way, through messages.

Waitbutton – Continues the script after the user pushes a button

lasttrainerbattle – Initiates the last battle the player taken.

Getplayerpos 0x[varx] 0x[vary] – stores the players x position and y position in the corresponding variables

showpokepic POKEMONNAME xpos ypos– shows the pokemon sprite at x,y position

hidepokepic – The sprite displayed w/ above command will not hide until this command used

random ZZ – Generates a random number between 0 and ZZ then puts it in LASTRESULT or 0x800D

special XX – This is for a bunch of commands that must be used through this one
Here is a list of specials for you (they are different for each game)
FireRed / LeafGreen

special 0x0 'Heal Pokémon
special 0x29 'Choose three Pokemon for something
special 0x3C 'Access PC
special 0x8D 'Person says what said the last person you talked to
special 0x8E 'Reload Map
special 0x9D 'Old Man Catches Weedle
special 0x9F 'Choose Pokemon
special 0xAB 'FR/LG/R/S 'Tree' Data Called
special 0x108 'Kanto dex document
special 0x10F 'Game Restart
special 0x110 'Hall of Fame and Credits
special 0x111 'Elevator animation
special 0x113 'FR/LG/R/S screen scrolling
special 0x114 'FR/LG/R/S stop screen scrolling
special 0x132 'Shows floors
special 0x136 'Horizontal Earthquake
special 0x137 'Glitched Battle
special 0x138 'Battle
special 0x139 'Battle
special 0x13D 'Flash
special 0x13F 'Warp to first warp of the map
special 0x156 'Ghost
special 0x157 'Bike
special 0x161 'Surf
special 0x163 'Store Pokemon to Dex
special 0x166 'Nickname
special 0x16F 'Fire Red/Leaf Green National Dex
special 0x173 'Add to fame Checker?
special 0x17B 'Sea gallop Animation
special 0x18B 'Displays an image. Only known images are Kabuotps and Aerodactyl fossils.
special 0x18C 'Closes image shown with special 0x18B
special 0x191 'S.S. Anne animation

Ruby / Sapphire
0 = Heals Party Pokémon
2 = Warp sound + FadeBlack
3 = Hero Uses Last Used Warp
8 = Make new Secret Base/Enter Secret Base
9 = Come out of Coliseum
A = Come out of Coliseum
E = Hero Uses Secret Base PC
F = Something to do with registry in a secret base
11 = Something to do with Secret Base battling
18 = Move Player to X01 Y03
19 = Something to do with secret base battling
1A = Turning off PC
1B = Mixing Records
1F = checks whether game is linked
20 = Please wait followed by wild battle (Linkup) (VS in coliseum)
21 = "Please wait link stand by" (Link Feature)
22 = "Please wait link stand by" (Link Feature)
23 = Call Save Menu
29 = Select 3 Pokémon [maybe for Battle tower?]
2A = Black Screen
2B = Something to do with Berry Growth
2C = Opens up berry pocket (Used in berry blender script)
2D = Something to do with Planted berry (Used with CmdC3)
2E = Something to do with Berry Growth
2F = Something to do with Berry Growth
30 = Maybe activates the watered flag (used first, then special0x5E)
34 = Open Textbox (Stays Open)
35 = Open Textbox (Stays Open)
3B = Trainer battle
3C = Access Lanette's PC (BOX System)
5D = Call Save Menu which keeps looping.
5E = Watering of Berry (used first, then special0x5E)
5F = You fill your trainer's profile/interview
60 = Shows what you put for trainer's Profile/interview
67 = Strange Message with sound (could be Unown speech)
6C = Trainer Tales (Link Feature)
6D = Choose Tale
75 = Secret Base Decoration Item Menu
7C = Something to do with renaming
7D = Something to do with renaming
83 = Poké Slots In Use (Store Command)
8A = Crashes
8D = Displays the last message
8E = Used with Setmaptile to make it work
91 = setmaptile #206 at X8 YB
94 = Something to do with Timed events
98 = Cable Car Ride Cutscene
9A = Male Clock
9B = View Clock
9C = Choose Starters From Birch's Bag
9D = Wally Catching Ralts
9E = Nickname's first Pokémon in Party
9F = Choose a Pokémon in the party (For Nickname)
A0 = ?
A1 = Starts Berry Blender
A2 = Slot game.
AF = Gabby and TV's "In serach of Trainers"
BC = Store a Pokémon For Day Care
BD = Take back Pokémon From Day Care
BE = Get Breeding Growth (store)
BF = Get Price
C0 = Something to do with Day Cay pay (store)
C2 = Egg hatch (1st Pokémon in party)
C4 = Battle results For The Coliseum
C6 = Something to do with DayCare cost
C8 = Move to the last sethealingplace/flightspot after some time (faint!!) (Fainted Event)
D0 = Opens PokéBlock case
D1 = Stores a random value to LASTRESULT (If the value matches mirage Island will show)
D4 = Used Before Special 0xF9/FA
D5 = Catch Pokémon tip, boxset 4 (use closeonkeypress)
D6 = tile change (in the middle of screen?)(For PC)
D7 = tile change (flower, in the middle of screen?)
D9 = Sets some sort of tiles
DA = Sets some sort of tiles
DB = Choose Pokémon then Fadescreen
DC = Opens the First Pokémon's Moves
E0 = Move tutoring For 1st Pokémon in Party
E3 = CheckBike (store command) 00 = nobike
E4 = Set Cycling Road Results (time, collisions)
E6 = First Pokémon Happy (StoreResult, 4 = Happy),
EC = Verse a high level trainer, level 100/Random Battle?
F1 = Restarts Game
F5 = choose 3 Pokémon(Battle tower) F6 = ?
F9 = Item Storage Mailbox Decoration
FA = Item Storage - No Decoration
FB = World Map
FE = Used for In-Game Trades - Trades 1st trade Pokémon "Makit" to 1st Pokémon in Party
103 = Berry Blender results
106 = PC (menu opens and disappears real fast)
107 = Hall of Fame, through PC (Will be corrupt if there's no data) (reads)
108 = Hoenn Pokédex diploma
10E = Boat sailing for a long time, like Fire Red's speed boat (+Return)
10F = Restarts
110 = Hall of Fame "Credits" (Saves data)
111 = Elevator animation<
112 = Displays Flutes
113 = Freezes The Screen/Camera
114 = Releases The Screen/Camera
119 = Groudon's Orb followed by earthquake
11B = Battel Tower Results
12C = Player Goes to last warp/flightspot used
12D = Makes special 0x9d work properly
130 = Is PC Box Full (store command) (0 = full)
131 = Earthquake for few seconds "Earthquake (stops)"
132 = Show Floors & Which Floor you're on
134 = CheckPokerus [0001 = Pokerus]
136 = Weird Quake
137 = Lava Battle/with Groudon
138 = Land Battle/with legendary
139 = Land Battle2/different song/battle with ledgendary - used with wildbattle
13B = Small screen shake
13D = Light/Flash
13E = Player uses the warp last used (no sound)
13F = falls in first warp of the first map
140 = Pokémon Image (UnLZ 199/200)
142 = Ecard battle Initiate (used in Levelscript at mossdeep, Oldman's house)
143 = Battle ?(perhaps used for wildbattle)
147 = Check Pokemon
14C = Turns Off Background/Map music

special 0x0 ' Heal Pokémon
special 0x116' screen scrolling (control with 7F with move commands)
special 0x117' stop screen scrolling (return to original position before using this)
special 0x1F3' national dex

For Movements it's almost like movements
PKSV comes with a movement planner which makes everything much much easier
applymovement 0x[person event number] @label

Then add “#org @movement label”
Next make your movement script and copy it to your clipboard now just make a new line and paste the data.

Show me the Money!

These are a few commands used to give,take,check for money,and show money
Giveing Money
Command: givemoney ZZ 0
Where ZZ is the amount of money to give (must be less than one million)
givemoney 200 0 'Gives 200 pokedollars to the player

Takeing Money
command: paymoney ZZ 0
where ZZ is the amount of money to be taken from the player(must be less than or equal to the amount of money the player has)
paymoney 200 0 'Makes player loose 200 pokedollars

Checking money
command: checkmoney ZZ 0
where ZZ is the amount of money to be looked for, if the player has this much money, LASTRESULT is set to 1, otherwise it is 0
checkmoney 200 0 'Checks if the player has 200 pokedollars, sets LASTRESULT to 1 if he/she does
compare LASTRESULT 0x1 'Compares LASTRESULT to containing 1
if 0x1 jump @continue 'Jumps to #org @continue if LASTRESULT had one in it
jump @notenough 'Jumps to the script saying that the player did not have enough money

Showing Money
A little more complex than the other money commands
Showing Money
command: showmoney [ZZ] [YY] 0
Where ZZ is the x coordinates and YY is the y coordinates
showmoney 10 10 0 'Displays money at 10,10 on the screen
However if you take money, or give it, the money that the player sees needs to be updated to avoid confusion
command: updatemoney [ZZ] [YY] 0
Where [zz] and [yy] are the same as the coordinates used in your show money

Also, you will want to remove the money from the screen before your script ends.
command: hidemoney [zz] [yy] 0
Where [zz] and [yy] are the same as the coordinates used in your show money
showmoney 10 10 0
paymoney 200 0
updatemoney 10 10 0

You really shouldn't use any of these commands without using them all, with the exception of updatemoney maybe...
An example using them all
#org @main
checkmoney 0x96 0x0 0x0
compare LASTRESULT 0x1
if == jump @canhave ' Equal To
jump @canthave

#org @canhave
showmoney 0xA0A 0x0
msgbox @hy ' Hey \v\h01, do you w...
callstd MSG_YESNO ' Yes/No message
if == jump @want ' Equal To
jump @notwant

#org @want
paymoney 0x96 0x0 0x0
msgbox @ty ' Thank you for your b...
callstd MSG_LOCK ' Built-in lock command
hidemoney 0xA 0xA

#org @canthave
msgbox @he ' Hello \v\h01.
callstd MSG_LOCK ' Built-in lock command

#org @notwant
msgbox @mb ' My business is alway...
callstd MSG_LOCK ' Built-in lock command
hidemoney 0xA 0xA

#org @hy
= Hey \v\h01, do you want a\nA super potion for 150 ?

#org @ty
= Thank you for your business.

#org @he
= Hello \v\h01.

#org @mb
= My business is always open\nto those who can afford it.

These are simple commands to change the weather in outdoors maps.
SetWeather and doweather work together
setweather 0x3 'Sets the weather to do to 3 for rain
doweather 'Does the weather we set with setweather
resetweather 'Undoes the effects of setweather and doweather
You can find a list of weathers in a-map under the header tab
This should be enough to get you started, I might post more sooner, but not until I get suggestions to add, or PKSV has more features needing explanations.

Also, just so you know
“#dynamic 0x740000” can be “#dyn 0x740000” also, the offset does NOT have to be 0x740000 it can be any offset you want.

Level Scripts.

There are two types of level scripts....
.....Type 1
........The kind that is under the events tab (aka trap script)
.....Type 2
........The kind that is under the header tab (aka ...level scripts?)
How to use type 1
1) Create a script event in a-map events tab (the green s kind...)
2) Assign a variable into the correct box
3) Assign the value to be whatever that variable isn't (after the level script is used the variable is assigned this value...)
4) Assign the "unkown" to 3
5) Compile your script
6) Assign the script offset to the proper box
How to use type 2
These are a little bit more challenging and i'll update again when i can explain it

Sample Scripts.

Snes Script
Description: Displays "[player] turned on the snes!" then plays battle music, followed by a "player has X lives left" where x is a number which is automatically decremented. Then when the player has no more lives left "Game over time to go"
#dynamic 0x740000

#org @main
setvar 0x8010 0x5
message @start
callstd MSG_NORMAL
fadesong 265
pause 0x50
compare 0x8010 0x1
if == jump @if1
storevar 0x1 0x8010
message @loopmsg
callstd MSG_NORMAL
subtractvar 0x8010 0x1
compare 0x8010 0x0
if == jump:-loop
jump :loop

message @done
callstd MSG_NORMAL

#org @if1
message @crud
callstd MSG_NORMAL
jump :skip

#org @start
= \v\h01 turned on the SNES

#org @loopmsg
= \v\h03 lives left

#org @crud
= Oh crud, I only have one live left!

#org @done
= \v\h01 got a gameover\ntime to quit!

Credit: Full Metal

Description:This only happens once,player looks left and up pops an excite icon, OW person w/ event id of 4 looks down and right,then player talks about not being late to get their first pokemon,then the other guy will run down 3 steps and dissapear. Please note that if you don't have your map set up as mryvn's then the script will look a little weird. So i reccomend that you also set the person id no to 8C3 (which makes them dissapear forever,i'll explain more on the next update) as well as adjust the movement and sprite placement to fit to your map (eg add more downs/change direction the other person runs)
#dynamic 0x74000
#org @start
checkflag 0x8C3
if true jump :end
applymovement PLAYER @a1
applymovement 0x4 @a2' Where 0x4 is event # of whoever is talking to you
message @a3'
callstd MSG_NORMAL
applymovement 0x4 @a4' Where 0x4 is event # of whoever is talking to you
pauseevent 0x0
disappear 0x4' Where 0x4 is event # of whoever is talking to you
setflag 0x8C3

#org @a3
= \v\h06: Awesome weather right?\nLet's hurry up!\p Don't want to be late\n for out first Pokemon!

#org @a1
M look_left say_! end

#org @a2
M look_down look_right end

#org @a4
M run_down run_down run_down end

Credit: Mervyn

Eevee Script
Description: Give the player an Eevee!
#dyn 0x740000
#org @start
checkflag 0xABC
if 0x1 jump @geteevee
msgbox @eevee1
callstd MSG_NORMAL

#org @geteevee
checkflag 0xXYZ
if 0x1 jump @eevee2
msgbox @eevee3
callstd MSG_NORMAL
compare LASTRESULT 0x6
if == jump @toomany
addpokemon EEVEE 6 NONE 0x0 0x0 0x0
setflag 0xXYZ
storepokemon 0x0 EEVEE
message obtain
fanfare 0x101
msgbox @howseevee
callstd MSG_NORMAL

#org @eevee2
msgbox @howseevee
callstd MSG_NORMAL

#org @toomany
msgbox @toomuch

#org @eevee1

#org @howseevee

#org @eevee3

#org @toomany

Credit: Undocumented.


★ full metal.

I like to push it,
and push it,
until my luck is over.
Reply With Quote