Menus and themes
Status: Implemented (API 1.13). A title screen background or panorama from a mod, and GUI sprite overrides per screen or for every screen, without a resource pack. Replacing whole vanilla screens and per-widget styles are Planned; mod screens can already look like anything (GUI with RmlUi, Immediate GUI).
A total-conversion mod usually wants its own first impression: its own title background and buttons that fit its look. Both are client-side and live while the mod is loaded; nothing changes for players without the mod.
Reference: gui, Client Integration.
1. The title screen
cl.on("lifecycle.client_setup", function()
cl.menu.set_title_background("horror:textures/gui/title.png") -- one picture over the whole screen
end)
The picture is stretched over the screen behind the logo and the buttons (use the screen’s aspect ratio, 16:9 for most players), and the vanilla panorama overlay stays on top. For a moving background use a panorama instead: six cube faces like vanilla’s, panorama_0.png to panorama_5.png:
cl.menu.set_panorama("horror:textures/gui/title/background/panorama")
It turns like the vanilla one and follows the Panorama Scroll Speed setting. "" brings back the vanilla background. If several mods set one, the last one wins. cl.menu.* is the same as cl.gui.* (cl_gui_set_title_background, cl_gui_set_panorama in C).
2. A theme for the vanilla GUI
Every vanilla widget is drawn from sprites of the GUI atlas (widget/button, widget/button_highlighted, widget/button_disabled, widget/slider, widget/slider_handle, widget/text_field, container/slot, hud/hotbar and so on: the files under assets/minecraft/textures/gui/sprites/ of the vanilla resources). Replace any of them:
cl.on("lifecycle.client_setup", function()
local T = "horror:textures/gui/theme/"
cl.menu.set_sprite("", "widget/button", T .. "button.png") -- every screen
cl.menu.set_sprite("", "widget/button_highlighted", T .. "button_hover.png")
cl.menu.set_sprite("options", "widget/slider", T .. "slider.png") -- only in Options
end)
- The first argument is the screen:
""for every screen, or a screen id asclient.screen_openreports it ("title","options","inventory","pause"). A per-screen override wins over a global one. - The texture keeps the sprite’s scaling: a nine-slice sprite (buttons) stays nine-slice with the same borders, measured in the vanilla sprite’s pixels, so a texture of twice the size gives crisper borders, not thicker ones. A tiled sprite tiles, a stretched one stretches.
- Resource packs still change the vanilla sprites; your overrides sit on top of them.
cl.menu.set_sprite(screen, sprite, "")removes one override,cl.menu.clear_sprites()all of yours.
In C:
cl_gui_set_sprite(CL_STR(""), CL_STR("widget/button"), CL_STR("horror:textures/gui/theme/button.png"));
The overrides cost nothing while there are none; with some, each sprite is looked up once per screen and cached.
Try it
Give only the pause menu purple buttons, and put the vanilla ones back when the player presses a key of your mod.
Show a solution
cl.on("lifecycle.client_setup", function()
cl.menu.set_sprite("pause", "widget/button", "horror:textures/gui/purple_button.png")
end)
local k = cl.keybind.register{ id = "horror:vanilla_buttons", default_key = "key.keyboard.f8" }
cl.on("tick.client_post", function()
if cl.keybind.consume_click(k) then cl.menu.clear_sprites() end
end)