Overworld Scripting ‐ A Complete Example - haven1433/HexManiacAdvance GitHub Wiki
Click to return to the main scripting page
In this tutorial, we'll be making a not-too-simple, but not-too-complex script, from the ground up. By the end of it, we'll have used flags, specials, sections, autos, and message boxes, as well as learned a few debugging techniques.
The goal is to make a character that asks to see a pokemon, and then gives you an item if you show it to them. An outline for the script would look like this:
Ask to see a Rattata? Yes/No
No -> ok, nevermind
Pick a pokemon from the team.
Not a Ratata? -> ok, nevermind
Thanks for showing me a Rattata!
Give Rare Candy
Explain what Rare Candies do.
And then if you talk to the character again, they'll just tell you what Rare Candies do.
Since you're talking to a character, there's a few things we'll want in almost every script. Here's some boilerplate code:
section0:
lock # prevent normal NPC movement during the script
faceplayer # turn towards the player
# your stuff goes here
release # allow normal NPC movement now that the script is over
end # end the script
section0
is called a "section header", and you can call it just about whatever you want, as long as you don't have spaces and end with :
.
The bits you care about go in the middle. Let's add a bit of code for asking the user if they have a pokemon:
section0:
lock
faceplayer
msgbox.yesno <auto> # ask the player a yes/no question
{
Have you caught a RATTATA yet?
}
if.no.goto <notyet> # jump to another section if the player said no
release
end
notyet:
msgbox.default <auto> # show a message
{
If you catch one, let me know!
}
release
end
We ask the player a yes-or-no question, and then we jump to another section if the user says no.
We'll worry about how the "show a pokemon" part works a little later: right now, let's just pretend that the player is telling the truth, and go ahead and give them the item.
section0:
lock
faceplayer
msgbox.yesno <auto>
{
Have you caught a RATTATA yet?
}
if.no.goto <notyet>
msgbox.item <auto> "RARE CANDY" 1 mus_level_up # give item/jingle/message
{
Oh, cool! Take this RARE CANDY for
showing that to me.
}
msgbox.default <auto> # show a message
{
You can use a RARE CANDY to make
your pokemon stronger!
}
release
end
notyet:
msgbox.default <auto>
{
If you catch one, let me know!
}
release
end
Now we have a pretty good 'first draft' of our script. Let's start adding some details.
There are hundreds of commands available for event scripting, but there are still some special-case things that are used only rarely that don't get their own command. Instead, all of these 'special case' things are put together into one command, the special
command. It comes in 2 forms: special
and special2
. They both do the same thing, except that you use special2
when you want the special to set the value of a variable. See Specials for more information.
There's also documentation available within the application:
Within here, you can find a list of every available scripting command / special, which links to a detailed reference document with examples of using each command and special. Using this reference, we can discover 2 specials that help with our specific task: ChoosePartyMon and GetPartyMonSpecies. Lets add those to our script to check if the player has a Rattata (species 19) in their team:
special ChoosePartyMon # show party menu, store chosen party index in var4
waitstate # included because the documentation says to
if.compare.goto var4 = 7 <notyet> # branch if the player chose 'cancel'
special2 varResult GetPartyMonSpecies # get the species
if.compare.goto varResult != 19 <notyet> # branch if the player didn't choose Rattata
We've written most of our script, but if we test it, we'll notice that the player can get unlimited rare candies by talking to the NPC. We want the NPC to remember if it's already given an item to the player, so let's use a Flag to track this bit of information. Our general goal is something like:
top:
if the flag is set, jump to bottom
do the script
set the flag
bottom:
basic text explaining what rare candies do
Here's what that looks like in an actual script:
section0:
lock
faceplayer
if.flag.set.goto 0x0021 <finish> # you can name the 'finish' section whatever you want
... # stuff we've already written goes here
setflag 0x0021 # set the flag once we've given the item
finish:
msgbox.default <auto>
{
You can use a RARE CANDY to make
your pokemon stronger!
}
release
end
Always test your scripts! There may be some detail you messed up or didn't understand correctly. For example, when we test this script, we'll notice that after special ChoosePartyMon
, the NPC starts walking around again. We can correct this by adding lock
/faceplayer
again after that special.
Other common things to watch for:
- When you edit a script, any existing save file (or save state) may not load it correctly at first. Always leave and re-enter the map that contains the script to make sure that everything gets loaded correctly.
- NPCs are only visible if their assigned Flag is clear.
- Script events will only activate if their variable matches the trigger.
- Script events will always activate if their variable matches the trigger. So make sure the script either moves the character or changes the value in their assigned variable.
Here's the full script that we've written, all together:
section0:
lock
faceplayer
if.flag.set.goto 0x0021 <finish>
msgbox.yesno <auto>
{
Have you caught a RATTATA yet?
}
if.no.goto <notyet>
msgbox.default <auto>
{
Great! Please show it to me.
}
special ChoosePartyMon
waitstate
lock
faceplayer
if.compare.goto var4 = 7 <notyet>
special2 varResult GetPartyMonSpecies
if.compare.goto varResult != 19 <notyet>
msgbox.item <auto> "RARE CANDY" 1 mus_level_up
{
Oh, cool! Take this RARE CANDY for
showing that to me.
}
setflag 0x0021
finish:
msgbox.default <auto>
{
You can use a RARE CANDY to make
your pokemon stronger!
}
release
end
notyet:
msgbox.default <auto>
{
If you catch one, let me know!
}
release
end