• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

UI Template

This bundle is marked as pending. It has not been reviewed by a staff member yet.
Here's my take on an ultra-minimalist user interface.

Notes:
If your map uses a multiboard, you can prevent covering it up with the quest menu exit button by modifying line 131 to -
JASS:
    call BlzFrameSetPoint(BlzGetFrameByName("QuestAcceptButton",0), FRAMEPOINT_TOPRIGHT, BlzGetFrameByName("QuestBackdrop", 0), FRAMEPOINT_TOPRIGHT, -0.055, -0.016)

What it includes:

A Reworked Top Interface - Menu buttons have been relocated to be more compact on the right side of the screen. Standard game clock removed, and upkeep replaced with a real-time elapsed clock.

A Reworked Bottom Interface - All excess textures have been cut out, and selection dead space has been removed. The minimap and command card have both been resized, as well as the command buttons that go inside it. Both of the Toggle Minimap Creep Display, and the Toggle Formation Movement buttons have been removed, as they didn't fit my needs for this UI, but are still able to be activated by using their hotkeys, Alt+R & Alt+F, respectively.

Game Timer - This UI contains an integrated clock that updates each second, in favor of the original "game time" clock used. The script for this is included with the interface, and works with any map.

Camera Slider - This UI, next to the portrait, also contains a camera slider, with the script included, that allows the user to zoom in and out while locking their camera to that newly adjusted height.

Expanded Quest Box - The in-game quest box description has been expanded to fit more text, and an example is shown in the demo map.

Jass & Lua - The demo contains both, just swap the language mode and disable the one you want.

HD & SD Compatibility - This UI works great in both game modes. Requires patch 1.32+


Importing:

In order to make this UI work, you'll need to import all the assets located in the asset manager, as well as import over the scripts (camera slider and game timer are optionally split from the rest of the the interface).


Demo Map:

I highly suggest using the Demo map to pull resources from, check paths, and view the interface for yourself.


What's to come?

The Lua version is not complete, and may take a few days to add. The Jass version is 100% ready to go.


Credits:

Thanks to SonGuhun, Macadamia & Tasyen


Code Snippets:
Required - PlayerUI
vJASS:
function UISetup takes nothing returns nothing
    //Local Variables
    local framehandle fh = null
    local framehandle chatButton = null
    local framehandle questButton = null
    local framehandle allyButton = null
    local framehandle MiniMap = null
    local framehandle gridButtons = null
    local framehandle imageTest = BlzCreateFrameByType("BACKDROP", "image", BlzGetFrameByName("ConsoleUIBackdrop", 0), "ButtonBackdropTemplate", 0)

    //Top UI & System Buttons
    set fh = BlzGetFrameByName("UpperButtonBarFrame", 0)
    call BlzFrameSetVisible(fh, true)
    set allyButton = BlzGetFrameByName("UpperButtonBarAlliesButton", 0)
    set fh = BlzGetFrameByName("UpperButtonBarMenuButton", 0)
    set chatButton = BlzGetFrameByName("UpperButtonBarChatButton", 0)
    set questButton = BlzGetFrameByName("UpperButtonBarQuestsButton", 0)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameClearAllPoints(allyButton)
    call BlzFrameClearAllPoints(chatButton)
    call BlzFrameClearAllPoints(questButton)
    call BlzFrameSetAbsPoint(questButton, FRAMEPOINT_TOPLEFT, 0.77, 0.6)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.85, 0.6)
    call BlzFrameSetAbsPoint(allyButton, FRAMEPOINT_TOPLEFT, 0.77, 0.583)
    call BlzFrameSetAbsPoint(chatButton, FRAMEPOINT_TOPLEFT, 0.85, 0.583)

    //Hiding clock UI and creating new frame bar
    call BlzFrameSetTexture(imageTest, "UI\\ResourceBar.tga", 0, true)
    call BlzFrameSetPoint(imageTest, FRAMEPOINT_TOP, BlzGetOriginFrame(ORIGIN_FRAME_WORLD_FRAME, 0), FRAMEPOINT_TOP, 0, 0)
    call BlzFrameSetSize(imageTest, 0.4, 0.025)
    call BlzFrameSetVisible(BlzFrameGetChild(BlzFrameGetChild(BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 5), 0), false)
    call BlzFrameSetLevel(imageTest, 1)

    //Food
    set fh = BlzGetFrameByName("ResourceBarSupplyText", 0)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.58, 0.5965)

    //Upkeep
    set fh = BlzGetFrameByName("ResourceBarUpkeepText", 0)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.295, 0.5965)

    //Gold
    set fh = BlzGetFrameByName("ResourceBarGoldText", 0)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.389, 0.5965)

    //Lumber
    set fh = BlzGetFrameByName("ResourceBarLumberText", 0)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.485, 0.5965)

    //Bottom UI & Idle Worker Icon
    set fh = BlzGetFrameByName("ConsoleUI", 0)
    set fh = BlzFrameGetChild(fh, 7)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.09, 0.179)

    //Remove Deadspace
    set fh = BlzGetFrameByName("ConsoleUI", 0)
    call BlzFrameSetVisible(BlzFrameGetChild(fh, 5), false)

    //Minimap
    set MiniMap = BlzGetFrameByName("MiniMapFrame", 0)
    call BlzFrameSetVisible(MiniMap, true)
    call BlzFrameClearAllPoints(MiniMap)
    call BlzFrameSetAbsPoint(MiniMap, FRAMEPOINT_BOTTOMLEFT, 0.0525, 0.0)
    call BlzFrameSetAbsPoint(MiniMap, FRAMEPOINT_TOPRIGHT, 0.2125, 0.141)

    //Minimap Buttons
    set fh = BlzGetFrameByName("MinimapSignalButton", 0)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_BOTTOMLEFT, 0.222, 0.116)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.242, 0.136)
    call BlzFrameSetTexture(fh, "UI\\ButtonBorder.dds", 0, true)
    set fh = BlzGetFrameByName("MiniMapAllyButton", 0)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_BOTTOMLEFT, 0.242, 0.116)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.262, 0.136)
    call BlzFrameSetTexture(fh, "UI\\ButtonBorder.dds", 0, true)
    set fh = BlzGetFrameByName("MiniMapTerrainButton", 0)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_BOTTOMLEFT, 0.262, 0.116)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.282, 0.136)
    call BlzFrameSetTexture(fh, "UI\\ButtonBorder.dds", 0, true)
    set fh = BlzGetFrameByName("MiniMapCreepButton", 0)
    call BlzFrameSetVisible(fh, false)
    set fh = BlzGetFrameByName("FormationButton", 0)
    call BlzFrameSetVisible(fh, false)

    //Minimap Border
    set fh = BlzCreateFrameByType("BACKDROP", "MinimapBorder", MiniMap, "", 0)
    call BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, MiniMap, FRAMEPOINT_TOPLEFT, 0, 0)
    call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOMRIGHT, MiniMap, FRAMEPOINT_BOTTOMRIGHT, 0, 0)
    call BlzFrameSetTexture(fh, "UI\\MiniMapBorder.dds", 0, true)

    //Tooltips
    set fh = BlzGetOriginFrame(ORIGIN_FRAME_TOOLTIP, 0)
    call BlzFrameSetVisible(fh, true)
    set fh = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP, 0)
    call BlzFrameSetVisible(fh, true)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_BOTTOMRIGHT, 0.7725, 0.141)

    //Command Buttons
    set gridButtons = BlzGetFrameByName("CommandBarFrame", 0)
    call BlzFrameSetVisible(gridButtons, true)
    call BlzFrameClearAllPoints(gridButtons)
    call BlzFrameSetAbsPoint(gridButtons, FRAMEPOINT_BOTTOMLEFT, 0.5950, 0.005)

    //Backdrop
    set fh = BlzGetFrameByName("ConsoleUIBackdrop", 0)
    call BlzFrameClearAllPoints(fh)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_BOTTOMLEFT, 0.052, 0)
    call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPRIGHT, 0.770, 0.141)

    //Command buttons border
    set fh = BlzCreateFrameByType("BACKDROP", "CommandBorder", MiniMap, "", 0)
    call BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, gridButtons, FRAMEPOINT_TOPLEFT, -0.007, 0.007)
    call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOMRIGHT, gridButtons, FRAMEPOINT_BOTTOMRIGHT, 0.0025, -0.005)
    call BlzFrameSetTexture(fh, "UI\\CommandCard.dds", 0, true)

    // Prevent multiplayer desyncs by forcing the creation of the QuestDialog frame
    call BlzFrameClick(BlzGetFrameByName("UpperButtonBarQuestsButton", 0))
    call ForceUICancel()

    // Expand TextArea
    call BlzFrameSetPoint(BlzGetFrameByName("QuestDisplay", 0), FRAMEPOINT_TOPLEFT, BlzGetFrameByName("QuestDetailsTitle", 0), FRAMEPOINT_BOTTOMLEFT, 0.003, -0.003)
    call BlzFrameSetPoint(BlzGetFrameByName("QuestDisplay", 0), FRAMEPOINT_BOTTOMRIGHT, BlzGetFrameByName("QuestDisplayBackdrop", 0), FRAMEPOINT_BOTTOMRIGHT, -0.003, 0.)

    // Relocate button
    call BlzFrameSetPoint(BlzGetFrameByName("QuestDisplayBackdrop", 0), FRAMEPOINT_BOTTOM, BlzGetFrameByName("QuestBackdrop", 0), FRAMEPOINT_BOTTOM, 0., 0.017)
    call BlzFrameClearAllPoints(BlzGetFrameByName("QuestAcceptButton", 0))
    call BlzFrameSetPoint(BlzGetFrameByName("QuestAcceptButton", 0), FRAMEPOINT_TOPRIGHT, BlzGetFrameByName("QuestBackdrop", 0), FRAMEPOINT_TOPRIGHT, -0.016, -0.016)
    call BlzFrameSetText(BlzGetFrameByName("QuestAcceptButton", 0), "×")
    call BlzFrameSetSize(BlzGetFrameByName("QuestAcceptButton", 0), 0.03, 0.03)

    // Add back ally resource icons
    call BlzFrameSetTexture(BlzGetFrameByName("InfoPanelIconAllyGoldIcon", 7), "UI\\RGReplacement.dds", 0, false)
    call BlzFrameSetTexture(BlzGetFrameByName("InfoPanelIconAllyWoodIcon", 7), "UI\\RLReplacement.dds", 0, false)
    call BlzFrameSetTexture(BlzGetFrameByName("InfoPanelIconAllyFoodIcon", 7), "UI\\RSReplacement.dds", 0, false)

endfunction

scope init initializer Init
private function Init takes nothing returns nothing
    call UISetup()
endfunction
endscope
Optional - Camera Slider
vJASS:
library CameraSlider initializer init

    globals
        private real max_dist = 5000
        private real min_dist = 500
        private real array current_dist
    endglobals

    private function periodic takes nothing returns nothing
        local integer i = 0
        loop
        exitwhen i > bj_MAX_PLAYERS
            if Player(i) == GetLocalPlayer() then
                call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, current_dist[i], 0)
                call SetCameraField(CAMERA_FIELD_FARZ, 1.5 * current_dist[i], 0)
            endif
            set i = i + 1
        endloop
    endfunction

    private function chatCam takes nothing returns nothing
        local real zoom = S2R(SubString(GetEventPlayerChatString(), 5, StringLength(GetEventPlayerChatString())))
        local integer pid = GetPlayerId(GetTriggerPlayer())
        if zoom < min_dist then
            set zoom = min_dist
        elseif zoom > max_dist then
            set zoom = max_dist
        endif

        set current_dist[pid] = zoom
    endfunction

    private function sliderCam takes nothing returns nothing
        local real zoom = BlzGetTriggerFrameValue()
        local integer pid = GetPlayerId(GetTriggerPlayer())
        set current_dist[pid] = zoom
    endfunction

    private function init takes nothing returns nothing
        local integer i = 0
        local trigger chatTrigger = CreateTrigger()
        local trigger CameraControl = CreateTrigger()
        local framehandle VSlider = BlzCreateFrameByType("SLIDER", "Distance", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "QuestMainListScrollBar", 0)
        local framehandle SliderToolTip = BlzCreateFrameByType("TEXT", "SliderTitle", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
        local integer Color = BlzConvertColor(255, 80, 80, 0) // Change values of alpha, red, green and blue for another custom color
        call TimerStart(CreateTimer(), 0.1, true, function periodic) // change loop speed as desired.
        call TriggerAddAction(chatTrigger, function chatCam)
        loop
        exitwhen i > bj_MAX_PLAYERS
            call TriggerRegisterPlayerChatEvent(chatTrigger, Player(i), "-cam ", false)
            set current_dist[i] = 1650 //default zoom
            set i = i + 1
        endloop

        // Set parameter for the Slider
        call BlzFrameSetSize(VSlider, 0.015, 0.085)
        call BlzFrameSetAbsPoint(VSlider, FRAMEPOINT_BOTTOMLEFT, 0.2920, 0.022)
        call BlzFrameSetMinMaxValue(VSlider, min_dist, max_dist)
        call BlzFrameSetValue(VSlider, current_dist[0])
        call BlzFrameSetStepSize(VSlider, 50)

        // ... and for the SliderToolTip
        call BlzFrameSetText(SliderToolTip, "") // Sets display text when hovered over the frame
        call BlzFrameSetScale(SliderToolTip, 1.60)
        call BlzFrameSetTextColor(SliderToolTip, Color)
        call BlzFrameSetAbsPoint(SliderToolTip, FRAMEPOINT_BOTTOMLEFT, 0.22, 0.16)
        call BlzFrameSetTooltip(VSlider, SliderToolTip)

        // Add event and callback to trigger for the Slider
        call BlzTriggerRegisterFrameEvent(CameraControl, VSlider, FRAMEEVENT_SLIDER_VALUE_CHANGED)
        call TriggerAddAction(CameraControl, function sliderCam)

        set VSlider = null
        set CameraControl = null
    endfunction

endlibrary
Optional - Game Timer
vJASS:
library TimerUpdate initializer init

    globals
        integer GameTimeSec = 1
    endglobals

    function Sec2Timer takes integer i returns string
        local integer timeSec = i
        local integer timeMin = 0
        local string timeString = ""

        set timeMin = timeSec / 60
        set timeSec = timeSec - (timeMin * 60)
        if timeMin < 10 then
            set timeString = "0" + I2S(timeMin) + ":"
        else
            set timeString = I2S(timeMin) + ":"
        endif

        if timeSec < 10 then
            set timeString = timeString + "0" + I2S(timeSec)
        else
            set timeString = timeString + I2S(timeSec)
        endif

        return timeString
    endfunction

    private function periodic takes nothing returns nothing
        local framehandle timerTextFrame = BlzGetFrameByName("ResourceBarUpkeepText", 0)
        set GameTimeSec = (GameTimeSec + 1)
        call BlzFrameSetText(timerTextFrame, Sec2Timer(GameTimeSec))
    endfunction


    private function init takes nothing returns nothing
        call TimerStart(CreateTimer(), 1, true, function periodic)
    endfunction

endlibrary
Required - PlayerUI
Lua:
//Coming soon!
Optional - Camera Slider
Lua:
//Coming soon!
Optional - Game Timer
Lua:
//Coming soon!
Contents

UI Template (Map)

Gold Icon (Texture)

Lumber Icon (Texture)

SupplyIcon (Texture)

ResourceBar (Texture)

Backdrop (Texture)

ButtonBorder (Texture)

CommandCard (Texture)

HumanUITileInventoryCover (Texture)

HumanUITile01 (Texture)

HumanUITile02 (Texture)

HumanUITile03 (Texture)

HumanUITile04 (Texture)

HumanUITile05 (Texture)

HumanUITile06 (Texture)

ResourceGold (Texture)

ResourceLumber (Texture)

ResourceSupply (Texture)

MiniMapBorder (Texture)

Level 7
Joined
Dec 9, 2014
Messages
89
The template is great and very useful. I did find that the exit button for the Quests can overlap with multiboards making it impossible to close, and that the menu buttons are placed off the screen for users on lower resolutions.

Will be testing it out in my map, thanks!
 
Looks pretty nice, however the transition from minimap to portrait looks a bit hard. Putting a border there would make it look better.
The goal of this UI was to show where to cut away from the default UI, since it is a "template" I hoped a few people would customize it further for their own project. It has almost all parts of the visible UI modified, so you can easily swap out numbers to your liking. The texture was also left as a slightly modified Reforged Human UI, but should be easy enough for anyone to "reskin" the visuals.

I made this during a time where we did not have a mega tutorial from Tasyen, or any UI-creation tools to work with. Lots could be improved, but I think it still serves as a good base for those who want something a little more unique.


The template is great and very useful. I did find that the exit button for the Quests can overlap with multiboards making it impossible to close, and that the menu buttons are placed off the screen for users on lower resolutions.

Will be testing it out in my map, thanks!
hi, I have actually made a fix for that, I will include it here (it's now included @ the top of the post under "notes"); thanks for the reminder. The menu buttons are not anchored properly, they're using fixed placement. I originally did not mind it, because I was going to include an update for it where the buttons were re-designed into small circles that fall under the resource panel. We'll see which one, if any, of these fixes I do :grin:


Overall, this concept is not continually being updated because it is off-centered & I didn't feel like getting back to working on it. I think I will, however, make a new bundle with different types of resource bars, and fixed menu buttons. I'll leave this here for those who want to dabble with it.

========
Also, as a update note for the Lua version, there is one, but it has issues with the camera slider. So, if anyone wants it, feel free to comment and I will include it, but it may require tweaking.
 
Last edited:
Level 7
Joined
Dec 9, 2014
Messages
89
I think I will, however, make a new bundle with different types of resource bars, and fixed menu button
Having different types of resource bars would be great. Personally I'd love one with the current style but without time/food/gold/lumber icons so that I can add my own icons.

The goal of this UI was to show where to cut away from the default UI, since it is a "template" I hoped a few people would customize it further for their own project.

Yes it was very useful for this purpose. Experimenting with the assets helped me understand how the default UI works and I'll be customizing it further from this template. Thanks for the hard work, hive could use more UI templates in general. This section of the forum is fairly hidden away for the average user.
 
Level 1
Joined
Oct 26, 2020
Messages
2
Hi, I'm new to making maps. I noticed this code in your template:

JASS:
// Prevent multiplayer desyncs by forcing the creation of the QuestDialog frame
call BlzFrameClick(BlzGetFrameByName("UpperButtonBarQuestsButton", 0))
call ForceUICancel()

Should I be doing this in every map in general? Or just in maps that modify the QuestDialog?
 
Hi, I'm new to making maps. I noticed this code in your template:

JASS:
// Prevent multiplayer desyncs by forcing the creation of the QuestDialog frame
call BlzFrameClick(BlzGetFrameByName("UpperButtonBarQuestsButton", 0))
call ForceUICancel()

Should I be doing this in every map in general? Or just in maps that modify the QuestDialog?
great question, I was told to add that by someone more knowledgeable than me :grin: I think you open/close whatever UI menu so the changes take effect immediately for all players. I'll see if I get can get some more info on it.
 
Level 8
Joined
May 19, 2016
Messages
145
cool template. but LUA: coming soon ?
i hope it will release for LUA too :) bump

I tried using this with JASS but even the Test Map seems to be broken. maybe because of the newest Patch?
 
Last edited:
Level 12
Joined
Jun 17, 2023
Messages
36
Remove these 3 lines from PlayerUI and the example map will no longer crash on load:
JASS:
// Prevent multiplayer desyncs by forcing the creation of the QuestDialog frame
call BlzFrameClick(BlzGetFrameByName("UpperButtonBarQuestsButton", 0))
call ForceUICancel()
 
Remove these 3 lines from PlayerUI and the example map will no longer crash on load:
JASS:
// Prevent multiplayer desyncs by forcing the creation of the QuestDialog frame
call BlzFrameClick(BlzGetFrameByName("UpperButtonBarQuestsButton", 0))
call ForceUICancel()
Well, I am not sure what changed since this was uploaded to break it; but I will update the template. Thank you.

Also, I do not plan to update this template anymore; instead I have been working on a new template that will be available in Lua to start, and a Jass version will be added later. Here's a sneak peek of the 2.0 template.

1697002944206.png


This version will offer optional additional resource boxes, a better way to show menu buttons (drop down menu), health/mana/xp bars, optional additional stats, and a move-able minimap. This one was also designed with an RPG style in mind.
 
Level 1
Joined
Dec 14, 2023
Messages
1
Hello, can you create a tutorial video on how to install this UI? I've tried searching for tools and methods to install this UI, but with no success. I'm using versions 1.24 and 1.26. Thank you!
 
Top