Problem Description
The current SwiftlyS2 menu API provides a complete menu construction and lifecycle model through IMenuManagerAPI / IMenuAPI, but the actual rendering layer appears to be tied to the default CenterHTML implementation.
This makes the menu system difficult to extend when a plugin wants to keep using the framework-managed menu behavior, but render the menu through a different UI surface.
For example, I may want to implement a custom menu renderer using world text instead of CenterHTML. In that case, I still want SwiftlyS2 to manage the core menu responsibilities:
- Opening and closing menus for players.
- Tracking the current active menu.
- Handling menu key input.
- Managing selection movement and option activation.
- Handling menu lifecycle callbacks.
- Supporting parent / child menu navigation.
- Reusing existing
IMenuAPI and IMenuOption data.
However, without a renderer abstraction or takeover point, the only practical option is to reimplement the whole menu system outside the framework. That means duplicating keybind handling, menu state management, lifecycle behavior, and option interaction logic, even though those are already framework-level responsibilities.
A menu system built into the main framework should ideally separate these concerns:
- Menu state and lifecycle management.
- Player input handling.
- Option selection and activation.
- Default UI rendering.
CenterHTML can remain the default built-in renderer, but plugin authors should be able to replace or extend the rendering layer when they need a different presentation model.
Proposed Solution
public interface IMenuRenderer
{
void Open(IPlayer player, IMenuAPI menu);
void Render(IPlayer player, IMenuAPI menu);
void Close(IPlayer player, IMenuAPI menu);
}
Or alternatively, expose renderer registration through the menu manager:
Core.Menus.RegisterRenderer("worldtext", new WorldTextMenuRenderer());
Then menus could opt into a renderer:
var menu = Core.Menus.CreateBuilder()
.Design.SetMenuTitle("Custom Menu")
.SetRenderer("worldtext")
.Build();
Alternative Solutions
1
Use Case
1
Implementation Ideas
- The existing CenterHTML menu rendering remains the default behavior.
- Existing plugins keep working without changes.
- Custom renderers can take over only the drawing/output layer.
- The framework still owns menu input, current menu tracking, selection state, close behavior, and callbacks.
- Renderers can be implemented by plugins using world text, HUD text, entities, or other display mechanisms.
This would make the menu system more extensible without forcing plugin authors to rebuild the entire menu lifecycle from scratch.
Priority
Low
Contribution
Additional Context
No response
Problem Description
The current SwiftlyS2 menu API provides a complete menu construction and lifecycle model through
IMenuManagerAPI/IMenuAPI, but the actual rendering layer appears to be tied to the default CenterHTML implementation.This makes the menu system difficult to extend when a plugin wants to keep using the framework-managed menu behavior, but render the menu through a different UI surface.
For example, I may want to implement a custom menu renderer using world text instead of CenterHTML. In that case, I still want SwiftlyS2 to manage the core menu responsibilities:
IMenuAPIandIMenuOptiondata.However, without a renderer abstraction or takeover point, the only practical option is to reimplement the whole menu system outside the framework. That means duplicating keybind handling, menu state management, lifecycle behavior, and option interaction logic, even though those are already framework-level responsibilities.
A menu system built into the main framework should ideally separate these concerns:
CenterHTML can remain the default built-in renderer, but plugin authors should be able to replace or extend the rendering layer when they need a different presentation model.
Proposed Solution
Or alternatively, expose renderer registration through the menu manager:
Then menus could opt into a renderer:
Alternative Solutions
1
Use Case
1
Implementation Ideas
This would make the menu system more extensible without forcing plugin authors to rebuild the entire menu lifecycle from scratch.
Priority
Low
Contribution
Additional Context
No response