Editing Menus
As of 0.8.3, a new service callback has been added to the game, called AddMenu. This callback can be used by modders to edit menus on the fly right before they appear on screen. This guide exists as a way to explain how this callback works and how to use it.
Prerequisites
This guide assumes that the user is capable of writing Services and Creating Menus. Please refer to these pages if anything is unclear. The user is also expected to be able to navigate the RogueEssence repository, specifically looking into its Menu folder and its subfolders.
Preparations
With the advent of 0.8.3, the callback AddMenu has been added to the game. This message is sent to services just before a menu is displayed so that modders can add, remove or modify its content at their heart's content. What can be edited depends on the menu itself.
There are three broader types of Menus. Each of them has one Scriptable counterpart and they are InteractableMenu, ChoiceMenu and MultiPageMenu. Being able to differentiate between them is the key to know how to interact with the menu you're looking to edit. Luckily, all it takes is a look in the repository's Menu folder. What you want to do is find the menu you ant to edit. Let's follow the base game's menu_tools service as an example and look for the Others menu.
Open the RogueEssence/Menu/Others folder and find the OthersMenu.cs file. Look for the "class" keyword. You should find the line public class OthersMenu : TitledStripMenu
near the top.
TitledStripMenu does not correspond to any of the three types we discussed, so we will have to follow the chain down until we find one. Click on TitledStripMenu
and use GitHub's Symbol window to follow the hierarchy up until you reach ChoiceMenu. Good job, we now know what type of menu we're dealing with!
To edit the menu, however, we still need its Label. A Label is a little string property that serves to identify a menu. If a menu has a label, it will be displayed in the dev mode's output console every time you open it. So... let's do that! Here's what happens when we open the OthersMenu:
Great! Now we have all the pieces necessary to start working on our changes.
Now that we have our menu type and our label, we need to write our AddMenu callback.
Since the AddMenu event message contains an argument, you will need to pass that argument on to your callback like this:
med:Subscribe("MenuTools", EngineServiceEvents.AddMenu, function(_, args) self:OnAddMenu(args[0]) end )
Now we write the function. Here's what menu_tools does:
function MenuTools:OnAddMenu(menu) if RogueEssence.GameManager.Instance.CurrentScene == RogueEssence.Dungeon.DungeonScene.Instance and menu:HasLabel() and menu.Label == "OTHERS_MENU" then local index = menu:GetChoiceIndexByLabel("OTH_SETTINGS") if index <0 then index = math.min(1, menu.Choices.Count) end menu.Choices:Insert(index, RogueEssence.Menu.MenuTextChoice("OTH_RECRUIT", RogueEssence.StringKey("MENU_RECRUITMENT"):ToLocal(), function () _MENU:AddMenu(RecruitmentListMenu:new().menu, false) end)) menu:InitMenu() end end
Now, what does this all mean? Let's analyze it one step at a time. First thinkgs first, this new option must only appear while inside a dungeon, so that's what the first part of the if statement does. We must then check if the menu that has been opened has a label, and, if it does, check if it's the label we're looking for.
Now that we know this is the right menu, we want to add our new option just above Settings. Since menu elements also have labels, we ask the menu for the index of its OTH_SETTINGS option and save that value. The fubnction then checks if the number is valid, and defaults to either slot 1 or 0 if it isn't. Finally, we add our new MenuTextChoice in that spot and reload the Choice list by calling InitMenu.
Functions
Now that we know how editing a menu works in practice, it's time to explore all of the tools offered by the engine to help modders.
This article is currently still work in progress