GUI modding

From Imperator Wiki
Revision as of 16:43, 23 October 2019 by Long Game Short (talk | contribs) (Added pictures for the other examples)
Jump to navigation Jump to search

Imperator's user interface (UI) is highly moddable, but for this reason UI mods disable achievements, since a player could cheat with them.

The game also includes a powerful GUI editor, making UI modding easier to learn.

Example from Compact Events mod

Modders can:

  • change the visual style of the interface
  • make windows movable and resizable
  • change and remove elements
  • add new buttons
  • show more information from the code

Modders can’t:

  • add new hotkeys (only reuse the existing ones)
  • make multiple windows visible (like Treasury and Trade views at the same time)
  • display information from one window in another, unless it was pre-configured by the developers


Basics

Code from select_office.gui, opened in Visual Studio with the CWTools extension

The interface in Imperator is created through .gui files in the game/gui folder, which are somewhat similar to html files.

As such, you can edit them with a notepad, but a proper text editor is recommended.


Imperator uses .dds files for textures, which are saved inside the game/gfx/ folder.

To edit or save .dds files use either Photoshop with Intel plugin or GIMP with this plugin.

Export with settings set to Alpha with no compression for better results.


There are two important console commands available for UI modding: “reload gui” and “reload texture”, for updating changes to .gui files and .dds files respectively, without restarting the game.

To use the console and the GUI editor, right-click the game on Steam, choose Properties, Set Launch Options, add "-debug_mode -develop" (without quotes).

Use this mod to hide the purple debug tooltip if it gets in the way.


Note, that using the debug mode changes the checksum, so you won’t be able to get achievements. Also, do not load any ironman saves with it, as this will corrupt them.

Creating a GUI mod

Creating gui mod.png

1. Start the game launcher, go to Mods, Mod Tools and fill in all the fields, including tags.

Clicking Create will create a new folder and a .mod file in Documents/Paradox Interactive/Imperator/mod.

2. Next, create a “gui” folder inside this new mod folder and copy the files you want to mod there, from game/gui.

So, to mod the topbar, we will end up with the following: best_topbar_mod/gui/ingame_topbar.gui.

  • If you don’t know which file is needed, enable the mod in the launcher anyway, start the game and use the GUI editor to help locate it.

GUI Editor

GUI editor: Outliner and Properties

GUI Editor is a developer tool for editing the UI right in the game. It is very convenient, but has its limitations and is prone to crashing.

To use it you need to launch the game with -developer and -debug_mode options.

Right-click the game on Steam, choose Properties, Set Launch Options, add "-debug_mode -develop" (without quotes).


To open the editor, either:

  • press Ctrtl+F8
  • open the console with the ` key (below Esc), click 2D Tools at the bottom and choose GUI Editor
  • open the console, type “gui_editor” (without quotes) and press Enter.

The game will freeze when loading it for the first time, don’t be alarmed.

Features

By default the editor starts with the Edit mode enabled. You can disable it in the top window, called Outliner. Hotkey “E”.

  • The edit mode is similar to the Inspect mode in browsers. While it’s enabled you can’t interact with the game, but it allows you to select elements of the UI and change them in the Properties window below.
  • Drag any dev windows to move it. Drag any edge to resize the window.
  • Yellow border indicated the selected element. You can use the scroll wheel to switch between other elements on the screen. Uncheck “Show Hierarchy” in the Outliner to hide other borders (Hotkey “L”).
  • Holding the right mouse button allows you to move the selected element. You can right-click anywhere on the screen, not necessarily on the element.
  • You can drag the elements inside the Outliner to reorder them. Right-click to open the .gui file in notepad or to delete them.
  • You can change or add new properties (by clicking the plus symbol) in the Properties window.
  • To undo anything you can press Ctrl+Z or the undo button in the Outliner. Redo is next to it, Ctrl+Y.
  • Ctrl+S saves changes to the .gui file.
GUI editor: UI Components


By clicking "Window" in the Outliner, you can open two more windows: UI components and Registered Data Types.

  • UI Components is like a palette from which you can drag new elements to the UI. gui/shared/standard.gui and gui/defaults.gui contain the most common things, like buttons, icons and text.
  • Registered Data Types may be used to look up what functions are available to display dynamic data from the game (like country stability or ruler popularity) or to duplicate some of the existing buttons.
  • Clicking the top right button in the Data Types will dump this data to your log folder (Documents/Paradox Interactive/Imperator/logs). You can also use “DumpDataTypes” console command.

Important: pay attention to which .gui file is selected. It is displayed in yellow at the top of the Outliner. If you don’t have a copy of it in your mod, the editor will save changes to the game files!

If your mod is enabled, you can copy the needed files to the mod folder without restarting the game, and continue editing.

If you do accidentally change the game files, you can reset them by validating: right-click the game on Steam, go to Properties, Local Files, Verify Integrity of Game Files.

Also, it is often easy to select a template by mistake, changing which will affect all instances of it in the UI. A blue header in the Properties that starts with “Type:” indicates a template, so be careful not to edit this part, unless you intend to.

Enabled timelapse button

Examples

Adding the Timelapse button

Imperator has an unfinished timelapse feature that can be enabled by using the “replay” console command.

There is also a hidden button for it, which we can easily reveal.

  1. Select the topbar and search for “replay” in the Outliner’s “filter” field. Press Enter to apply the filter.
  2. You should see three elements with “replay” in their names, inside a container. Select this container in the Outliner and in the Properties check the box next to “visible”.
  3. If you move the Outliner away from the top right corner, you should see a new button. Disable the Edit mode and click on it. The date will change to 450 and it will open the replay controls. The second button from the right will fast-forward the timelapse, so you can see how the world in your game evolved over the years.

Now, you will probably notice that you can only click on the right half of the timelapse button.

This is because the Date window is too small.

  1. Use the “Outside parent” option in the Outliner to highlight any elements that don’t fit inside their parents.
  2. Select the Date window and change its width in the Properties from 210 to 235. Now the button should be fully clickable.

Leaving it hanging in the air isn’t very pretty, however, so let’s move it to be between the date and the score.

  1. Select the replay container and hold the right mouse button to drag it.
  2. Then, let’s also remove the top half-circle, since we don’t need it here. Select the replay_frame icon. You can either:
    1. right-click it in the outliner and choose Delete.
    2. click the plus icon in the Properties and type “visible” to add a “visible” property. Unchecking that box will hide the frame but keep it in the code if we ever want to use it again.

Adding text

Adding text to the topbar

Let’s learn how to add new elements from the UI Components.

  1. If you don’t have this window open, click “Window” in the Outliner and select “Types” (select it again to close it). Resize the new window by dragging its bottom edge to make it easier to navigate.
  2. Look for gui/defaults.gui. It is the shortest line somewhere in the middle of the whole list. Expand it to reveal available components.
  3. Select the empty area on the topbar, between the stats and the score, topbar_bg_right. (If you still have “replay” in the filter field, delete it and press Enter to reset it)
  4. Drag and drop a textbox from the UI Components to the topbar. The new component is placed inside whatever element is currently selected.
  5. Expand the topbar_bg_right in the Outliner and select your new textbox.
    1. Uncheck “Show only active file” in the Outliner to see the other elements or save and then reload the UI with the “reload_gui” command.
  6. Go to the Properties and add a “text” property by clicking the plus sign on the white “Properties” header. Then type “text” in the search. If you don’t see this header, check “Show all” in the top right. (Do not add it to “type: textbox”, as this section is for the template, located in gui/defaults.gui)
  7. You should see your text appear in pink letters on the topbar. To make it look better, we will need to add a few more properties: “font” (choose BaseFont), “fontcolor” and “fontsize”. Add “autoresize” and enable it by checking the box so you can select the textbox from the UI. Otherwise, it won’t actually have any size.
  • if you need to add a lot of text, you could edit the blue template section, but then you’ll need to include the defaults.gui file in your mod and this may cause incompatibility issues with other mods. The better way to do it is by manually copying textboxes in the .gui file.

Adding more stats

Adding stats to the topbar

Let’s say we want to show more information on the topbar, like the ruler’s wealth and popularity.

The topbar stats are placed inside a flowcontainer which automatically orders them in a row, so we don't need to set position for each one.

  1. Select one of the stats on the topbar and find its parent flowcontainer in the Outliner.
    1. You can see there are two flowcontainers: one for all the stats and one inside it for legitimacy and centralization. You can select either one, our stats will be added at the very end.
  2. With the flowcontainer selected, drag an icon from the UI Components. You can drop it anywhere, as the flowcontainer ignores position. The template for the icon is in gui/defaults.gui, like for the textbox. (To open the UI Components, click Window>Types in the Outliner)
    1. Expand the flowcontainer in the Outliner and select your new icon. Add a “texture” property in the Properties. (Enable “Show all” if you don’t see the white Properties header. Do not add it to “type: icon”.)
    2. For now we will not add a frame like the other stats have, as it’s somewhat tedious. Instead, search for “treasury” in the “texture” field and select the first result.
    3. Add the “size” property and set it to 35x35 or the “scale” property set to 0.75.
  3. Next, select the flowcontainer again and add drag a textbox.
    1. Select the textbox in the Outliner and add a “text” property.
    2. Click on the plus sign next to the text property and select the following cascading menus: Player > Get Ruler > GetWealth. GetWealth will be in white and you need to scroll down for it.
    3. This will display the ruler’s current wealth in pink numbers on the topbar. To remove the fractional numbers, add “|0” the text field like this: [Player.GetRuler.GetWealth|0]. This doesn’t round the numbers, just cuts it off, but it will be enough for us. “|1” will display 1 digit after the decimal, “|2” will two and so on.
    4. Add the “font”, “fontsize”, “fontcolor” and “size” properties. Set the font to BaseFont, the fontsize to 18 and the size to 30x30, as this will line it up properly with the other numbers.
  4. To add some spacing between our icon and text, select the flowcontainer and add a widget to it from the UI Components. Then reorder it in the Outliner to be between the icon and text.
    1. Add a “size” property to the widget and set its width to 10. If you want to add more space before the icon too, add another widget there.
  5. To add the ruler’s popularity we can try to recreate how vanilla stats look. You can select one of them and try to do it yourself.
    1. Select the flowcontainer and add a widget to it, add a “size” property set to 116x40. We won’t be using a button as we can’t add the “onclick” property in the editor and, as such, tell it what to open.
    2. Select the widget and add an icon. Search for the “icon_value_tiles” texture.
      1. Set the icon’s position to 0x-2 and size to 110x40.
      2. The texture will look slightly different, so add a “spriteType” property set to corneredtiled and a “spriteborder” set to 48x48. This allows the texture to be stretched, while preserving its edges (spriteborder determines how much to preserve). Experiment by changing the icon’s size.
    3. Add another icon to this widget, search for a “popularity” texture and set its position to 2x0.
    4. Select the widget and add a textbox to it, set “text” to [Player.GetRuler.GetPopularity|0]. You can copy and paste this instead of searching, as GetPopularity is buried deep in the list.
      1. You can also use InGameTopbar.GetPlayer.GetRuler… like other stats do. Each window has its own set of promotes available to it, which you can see in DataTypes. However, there is a set of global promotes that can be used anywhere, like Player.
      2. Set the textbox’s position to 73x3, add “autoresize” and enable it and add a “widgetanchor” property set to top|hcenter. Widgetanchor determines where the object’s anchor point is (displayed by a yellow dot), which is what we move around when changing position. By default it’s always set to top|left.

The advantage of the second method is we can drag our widget in the Outliner and place it between other stats.

However, this is where you see the limitations of the editor, as we cannot copy elements and their properties or add functioning buttons.

Manual editing

Examples

Adding toggles with PdxGuiWidget

Scripted GUIs

Adding toggles

Adding a cheat button

Displaying a variable or script value

To show a variable on the UI is quite simple by using the Var function.

A tooltip made from custom_tooltips sometimes inside if blocks. Examples from the Bronze Age mod.
Showing names of provinces stored in global variables (among other things).

Example:

text = "[ProvinceWindow.GetProvince.MakeScope.Var('religious_prestige').GetValue|0]"

Where religious_prestige is a variable stored on the province currently selected. Any other appropriate scope can be used such as a country variable with:

text = "[Player.MakeScope.Var('religious_centralization').GetValue|0]"

This function can also be utilized in a localization entry. Example:

REL_PRESTIGE_CITIZEN_TT:0 "Citizen: #G +[SCOPE.GetRootScope.GetProvince.MakeScope.Var('citizen_num').GetValue|2]#!"
Where the scope comes from the top scope in the gui file. (i.e. scope = country, scope = province etc)

You can also use a saved scope as the target. You save a scope with "save_scope_as = target_religion". Example:

TOTAL_PRESTIGE_DISPLAY:0 "[SCOPE.sP('target_religion').MakeScope.Var('total_prestige').GetValue|0]"

But this localization string has to be called from the scripted GUI file with:

custom_tooltip = "TOTAL_PRESTIGE_DISPLAY"

And then using the BuildTooltip function:

text = "1. [ScriptedGui.BuildTooltip(GuiScope.SetRoot(Player.MakeScope).End)]"

In a localization file you can also show script values. Example:
[SCOPE.ScriptValue('final_cen_change_svalue_UI')|+=2]

This system is very flexible and the strings created can be displayed in texts right on the screen or as a tooltip where you just write "tooltip" instead of "text". Can also have great control over what appears in a tooltip by simply using a if and a limit with a custom_tooltip inside it.
Some more examples that might be helpful:
[SCOPE.sP('targetprov').GetName]
[SCOPE.sChar('prevruler').GetName|Y]

Displaying data lists

Hiding an object

UI components

Containers

Data lists

Objects

Textures

Resources