halflife-unified-sdk icon indicating copy to clipboard operation
halflife-unified-sdk copied to clipboard

Implement new UI

Open SamVanheer opened this issue 1 year ago • 0 comments

Implement a new UI using RmlUi or another UI library.

The game uses sprites + text for the HUD and VGUI1 for menus like the MOTD, Map Briefing, Team and Class menus.

RmlUi is based on HTML and has features like a layout engine, styling, colors, fonts and coordinate and size scaling using CSS properties. It does all the heavy lifting which makes it easier to improve the UI.

To implement this a few things need to be verified first:

  • Is it possible to render the current UI (HUD + VGUI1 menus) using HTML and CSS? This can be tested in any browser and should be done first to determine whether it's possible at all. The solution should also be tested when rendered at 60 FPS or more since some UI elements are animated (e.g. health changes color when it changes)
  • Can it render text the same way the engine does? The engine uses a couple fonts defined in Half-Life/platform/resource/TrackerScheme.res (mods can override this by putting the file in their resource directory) and Half-Life/valve/resource/ClientScheme.res (also override-able). game_text and related use Legacy_CreditsFont which is Trebuchet MS.
  • Can it render images the same way the engine does? The HUD renders images using a few render modes like additive and alpha test rendering which means the specific behavior has to be emulated somehow. Alpha test is fairly simple to do using an alpha channel, but additive rendering is harder. RmlUi may not support the CSS properties used in web development yet, but it might be a good idea to request they be added. It should be possible to draw grayscale images with a color to use the HUD color, and the alpha value should act as a fade value (0 == transparent, 255 == fully visible)
  • Does it allow resolving file paths using the engine's filesystem? Since files can be loaded from multiple locations (e.g. the game loads HUD sprites from the mod directory as well as addon, HD, low violence, fallback and base game directories). Some way to resolve paths embedded in HTML and CSS is needed.

This should be tested with various resolutions and aspect ratios, on Windows and Linux.

If a UI library can handle all of this the integration of the library needs to be investigated.

Can the library render to a texture? This would allow a frame to be drawn and subsequently drawn using the VGUI1 Bitmap class. A custom subclass could re-upload the texture using Image::drawSetTextureRGBA. This should allow the new UI to be used with the Software renderer as well as OpenGL.

If it can't render to texture but it can render directly using OpenGL it should be possible to render a frame directly when the engine asks for the HUD to be drawn. This does mean dropping support for the Software renderer. Note that the engine uses OpenGL 1.x commands to draw everything, so the OpenGL commands used by the library must be compatible with these to work. This also means checking to make sure the player's computer supports the OpenGL version required by the library, otherwise it could crash or not draw anything.

A window-sized VGUI1 panel can be used to forward player inputs like mouse and keyboard to the library, but should only do so if there is an active menu to receive it (like VGUI1 currently behaves).

The UI should be built with scaling in mind from the start. That means for the HUD scaling should not move elements too far away like the armor HUD does in vanilla Half-Life. Testing for overlapping elements is a must.

The HUD only accepts user input through key bindings (weapon selection slots in particular) so integrating the UI should consist of 2 stages: replacing the HUD and replacing the VGUI1 menus.

RmlUi doesn't use JavaScript for logic. Instead it uses C++ or optionally Lua (it is possible to add bindings for other languages). Care must be taken when using scripting languages to prevent servers from being able to execute arbitrary code. Restrict loading to the GAMECONFIG path to prevent downloaded files from being loaded.

Use vcpkg to add the library as a dependency.

There may be other issues to deal with that will be uncovered during the development process.

SamVanheer avatar Jun 17 '23 16:06 SamVanheer