Seen 21 Hours Ago
Posted 2 Weeks Ago
91 posts
13.5 Years
Dynamic Multichoice

Hey there. Over the last couple days I've been working on a take on the multichoice script command that allows you to create arbitrary menus from the scripting system. I was mostly not fully satisfied with the implementations of list menus / other forms of dynamic multichoice versions, so I decided to overengineer one. The idea is to have a "satisfies all needs" solution that can do all of these things:
  • Implement simple menus in one line without needing to adjust a global list.
  • Implement "conditions" (see below) to create menus based on certain game states.
  • Make drawing the list customizable, if you are willing to put in a little more coding effort.


How to implement

All the code for this system is available on my pokeemerald fork:
If you want to use it you can choose to implement it however you want. (Yes, you can also use git to merge it.)
I would really recommend looking at the changes I made and try to follow along by implementing them yourself on your fork.

Basic Usage

The most simple menus you can build as seen in the examples above just consist of a list of elements, you can use the following syntax in poryscript:
dynmultichoice(left, top, ignoreBPress, maxBeforeScroll, initialSelected, callbacks, "Option 1", "Option 2", "Option 3", ...)
with the following arguments:
  • left: The x offset of the menu (in tiles / units of 8 pixels)
  • top (the y offset of the menu, in tiles / units of 8 pixels)
  • ignoreBPress: Whether the menu should stay open if the user presses the B Button
  • maxBeforeScroll: The maximum amount of items shown before the menu scrolls
  • initialSelected: Variable or static value that determines the initially selected item
  • callbacks: The event callbacks of the menu. For a simple menu supply DYN_MULTICHOICE_CB_NONE
  • ...: Any number of menu options can follow after these arguments

The menu will automatically convert to a scrolling list (and indicate that with UI Arrows) if the amount of elements is larger than maxBeforeScroll.

When the menu is closed by player interaction, it will return the selected option index in VAR_RESULT. If the user aborted the menu by pressing the B Button, it will return 127.

Conditional Menus

Ever thought you only wanted to enable certain options if the player aquired a specific item, or progressed the game to a certain point? You can use this pattern to fully customize the options of your menu:
dynmultipush("First option", 0)
if (flag(FLAG_SYS_GAME_CLEAR)) {
   dynmultipush("Secret option", 1)
dynmultistack(left, top, ignoreBPress, maxBeforeScroll, shouldSort, initialSelected, callbacks)
dynmultistack behaves just like dynmultichoice with the addition of a shouldSort argument, that determines whether the list should be sorted according to the IDs you pass to dynmultipush. The latter also accepts variables as its second argument.


The callbacks argument chooses from a set of event listeners. If that does not make any sense to you, you may notice in the example I already use one such set of events, which will display an icon corresponding to the item id which the menu is built from. But you do not need to use the callbacks, you can always pass DYN_MULTICHOICE_CB_NONE. Those callbacks are written in C and allow you to have a very powerful extensions for those menus that really need it. You might also want to look at examples over at

Script Example

The example images from above where created by using the following script in poryscript syntax:
script EventScript_MultichoiceTests {
    msgbox (LittlerootTown_Text_CanUsePCToStoreItems, MSGBOX_DEFAULT)

    // random items with visualization example

    bufferitemname(STR_VAR_1, VAR_RESULT)
    dynmultipush("{STR_VAR_1}", VAR_RESULT)
    bufferitemname(STR_VAR_2, VAR_RESULT)
    dynmultipush("{STR_VAR_2}", VAR_RESULT)
    bufferitemname(STR_VAR_3, VAR_RESULT)
    dynmultipush("{STR_VAR_3}", VAR_RESULT)
    dynmultistack(0, 0, TRUE, 6, FALSE, VAR_0x800A, DYN_MULTICHOICE_CB_SHOW_ITEM)

    // inline example without scrolling

    dynmultichoice(0,0, TRUE, 6, 0, DYN_MULTICHOICE_CB_NONE, "Option 1", "Option 2", "Option 3")

    // inline example with scrolling

    dynmultichoice(0,0, TRUE, 3, 0, DYN_MULTICHOICE_CB_NONE, "Option 1", "Option 2", "Option 3", "Option 4")

    buffernumberstring(STR_VAR_1, VAR_RESULT)
    msgbox("{STR_VAR_1}", MSGBOX_DEFAULT)
For an example of how this would translate to regular scripting visit

I hope this is helpful to some people, at least I had a blast coding it. If you have questions about it, feel free to contact me on the usual suspects of discord servers, or leave a comment (Though bear in mind I'm not very active on this forum, and I might take a while to respond)

If you want to credit me for this (Which you should not feel obligated to do) I would appreciate if you used the name SBird instead of any other aliases you might know me under.

Good luck on your scripting adventures!

Seen 1 Week Ago
Posted 2 Weeks Ago
177 posts
5.4 Years
This not only is really easy to use, customise and display, but it's also really professional-looking and flexible! I look foward to see what I can create thanks to this!


Random Uruguayan User

Montevideo (Uruguay)
Seen 11 Hours Ago
Posted 4 Days Ago
2,998 posts
14.3 Years
Dynamic Multichoice
I think you know what I think of this beautiful piece of work, but I'll say it again; it's absolutely phenomenal and it was sorely needed too.
It's super flexible and allows the user to do so. many. things with the multichoices system it's ridiculous.
Completely foolproof and futureproof, surely something that would have made the lives of the workers at Game Freak much, much easier imo.
One could easily go as far as to replace every multichoice in the code with one of these and get rid of all the multichoice arrays.

When you first linked the branch before it was ready for public use, I decided to use it to remake the start menu of the game on a whim, thinking back about MapleFang's flawed implementation.
Since I just finished getting it to a point in which I think it's good enough to distribute, I think that I may as well link it here to display one of the many possibilities this system opens

It's functionally equivalent to the original start menu as far as I tested, but naturally, it has the advantages that this system brings, like faster transition from one option to the next, being able to hold the arrow keys to move between options constantly, being easier to read and easier to expand too!
EDIT: And scrolling options, of course.

Note: I didn't bother trying to keep absolute accuracy on the visuals department; that's a fool's errand imo. I just left it in a state that I personally like.
Note2: I intended to delete the code that composes the original and now unused start menu too, but it's too ingrained in the codebase which makes the task a big pita. I'll leave that up to the user.