How to use addOptionsMenuItem to put a multiple-choice option set in the System Menu

This is a simple one-off example. A more robust system could be created to generate multiple menu items, with the displayed option text and associated internal values all stored in tables! But FWIW I thought I'd just share this simple, minimal Lua example for addOptionsMenuItem, from retreiving the value that sets which option should be shown as selected, through to processing the user's choice.

Corrections/improvements/alternatives welcomed!

--First determine which option should already be selected when the menu opens ("storedValue" is assumed to be some variable--which need not be an integer--that exists in your game already):

local preSelectedMenuOption
if storedValue == 1 then --Whatever value was set previously by your game (maybe an initial default, maybe a prior hoice saved in playdate.datastore)
	preSelectedMenuOption = "option A"
elseif storedValue == 2 then
	preSelectedMenuOption = "option B"
else
	preSelectedMenuOption = "option C"
end

--Then create the menu item (its title will be forced to lowercase by the system, but capitalization of its options is in your control):

local sysMenu = playdate.getSystemMenu()
local menuItem, error = sysMenu:addOptionsMenuItem("title", {"option A", "option B", "option C"}, preSelectedMenuOption, function(value)
	setstoredValue(value)
end)

--This function runs when the system menu closes, if the user changed the option:

function setstoredValue(value)
	if value == "option A" then
		storedValue = 1
	elseif value == "option B" then
		storedValue = 2
	else
		storedValue = 3
	end
	
	--Take actions here to make use of the new "storedValue" (and save it to playdate.datastore for future sessions if desired)
end
4 Likes

Thanks for this example. I'm coming from JavaScript where I'm used to making huge config files in JSON and I'm having a hard time getting Lua to handle similar functionality. I am thinking of making three menu items and saving them to playdate.datastore. Here's my config, any suggestions?


local sysMenuItems = {
	{["id"]="toughness",["label"]="difficulty", ["default"]=2},
	{["id"]="altness",	["label"]="sampletest", ["default"]=1},
	{["id"]="crankness",["label"]="use crank",  ["default"]=false},
}

local sysMenuOpts = {}
sysOpts.toughness = {["hard"]=3, ["normal"]=2, ["easy"]=1}
sysOpts.altness = {["five"]=5, ["four"]=4, ["three"]=3, ["two"]=2, ["one"]=1}
sysOpts.crankness = {["on"]=true, ["off"]=false}

sysMenuVals = {}
sysOpts.toughness = 2
sysOpts.altness = 3
sysOpts.crankness = false

@Curbstone.Glyph you won't be able to avoid a bit of busy work setting up such a menu and making use of the result.

Also, I had to correct some of your definitions to get the code to work.

eg.

local sysMenuOpts = {}
sysMenuOpts.toughness = {["hard"]=3, ["normal"]=2, ["easy"]=1}

local sysMenuVals = {}
sysMenuVals.toughness = 2

function getTableKeys(tab)
	local keyset = {}
	for k,v in pairs(tab) do
		keyset[#keyset + 1] = k
	end
	return keyset
end

local menu = playdate.getSystemMenu()
local optionMenuItem, error = menu:addOptionsMenuItem("Tough", getTableKeys(sysMenuOpts.toughness), "easy", function(value)
	print("Checkmark menu item value changed to: ", value)
	-- code to transform value back into your numeric id
	sysMenuVals.toughness = sysMenuOpts.toughness[value]
	print(sysMenuVals.toughness)
end)

function playdate.update()
end
2 Likes

Thank you, that worked for me. I also made it more complicated, naturally.