Choose what is right, not what is easy
GameOptions are Engine Toggles that can be switched to instantly get an effect. They are also used inside the .ini files you find in the engine directory. After every major Patch, some of those get changed, removed or added. Not all of them have an noticeable effect or work at all. It's trial and error. 😉
I personally use the term PATH to a specific option, but ingame and inside an .ini File you have to split up the last part to make them work. I call those Parts GROUP and OPTION.
To use them ingame, you going to need Cyber Engine Tweaks. For each type, there are different commands. The common types are INT, BOOL and FLOAT. As Example, we are going to use the Path "RayTracing/Diffuse/UseScreenSpaceData". This is a "boolean" Option. You can only toggle it on (true) or off (false).
GameOptions.SetBool('RayTracing/Diffuse', 'UseScreenSpaceData', true)
To make your Options the default, you have to write them to an INI File. Cyberpunk does read them on start and apply your settings. The usual directory to place your INI file is "<INSTALL DIR>\engine\config\platform\pc". The syntax is fairly simple, so we use the example from above.
[RayTracing/Diffuse]
UseScreenSpaceData = true
The listing is fairly large with 1500+ Options, so i have moved it to /gameoptions (not mobile friendly). Supports search and multiple versions!
Sometimes i like to play an older Version of Cyberpunk because the Graphic Rendering changed alot between 1.2 and 1.5+, so sometimes i prefer to work on 1.31. I was not able to download older Versions than 1.31 with GOG, so i concentrated my efforts on Steam.
In order to download older Cyberpunk Versions i used the DepotDownloader GitHub, which uses DotNet Microsoft. You need only the AppID, the DepotID and the Manifest. Really helpful is the SteamDB. The Manifest selects the Version in the Depot of the App.
Open up a command prompt and enter the directory of the unpacked DepotDownloader.
DepotDownloader.exe -app 1091500 -depot 1091501 -manifest <Manifest> -username <Username> -password <Password>
If you have Steam Guard active, you prolly get an E-Mail with an Authentication Token. The DepotDownloader will ask for it.
I list only the Major Version with the last Patch for it.
Version | Manifest | Patch | Manifest | ||
1.0 | 7287387370544759862 | 7 December 2020 | 1.06 | 583937837845971710 | 23 December 2020 |
1.1 | 3852482208634779141 | 22 January 2021 | 1.12 | 6404500526474240765 | 5 February 2021 |
1.2 | 912635795014659773 | 29 March 2021 | 1.23 | 5662812629377532750 | 17 June 2021 |
1.3 | 4226367547239603660 | 18 August 2021 | 1.31 | 3225568184502668130 | 14 September 2021 |
1.5 | 4596392258055187917 | 15 February 2022 | 1.52 | 5869743417560122937 | 5 April 2022 |
1.6 | 9024153387735370035 | 6 September 2022 | 1.63 | 6594873489665865240 | 23 June 2023 |
2.0 | 1799993379545736809 | 21 September 2023 | 2.02 | 4882158097132343077 | 26 October 2023 |
2.1 | 2238892413801664242 | 5 December 2023 | 2.13 | 4350623720177810551 | 12 September 2024 |
Patch 1.31 / CET 1.16.4
The last patch with Static Resolution Scaling (SRS), which you could override up to 200% and beyond. At the doubled resolution the rendered image was pretty smooth and perfectly fine for high quality screenshots, as the AntiAliasing had alot more pixels to calculate with.
Patch 1.61 (DLSS) / CET 1.22.0
Introduced DLSS3 to Cyberpunk
CET 1.16.4
Updated ImGui to 1.84.2 which fixed BeginDisabled() and EndDisabled()
CET 1.18.0
First version that supports symbolic links in the filesystem, also added Lua function ModArchiveExists("example.archive")
CET 1.20.0
Changed to Openresty LuaJIT
CET 1.21.0
Switched to ImGui 1.88 (docking) and added Noto Sans as font. Made it possible to create a scaling UI. Removed the Window Arrow which was reintroduced with the following version.
CET 1.31.3
Disabled the console log for GameOption changes.
ImGui styling is some kind of Art in itself, but not that difficult. If you want a unique UI you have to deal with colors, padding and the line calculation. ImGui draws elements line by line with the padding from the element itself and padding from the window, so it's kinda limited in some ways and not comparable to HTML + CSS. My approach is a bit complicated but results in a precise positioning in any resolution the user can have. The builtin scaling of CET works pretty well and can be helpful if you don't want to do it the hard way.
The reference documentation is located at the CET Repository at GitHub, which lists all commands but not very extensive.
Examples are taken from my mod CharLi, which is my playground for advanced ImGui styling.
There are 4 commands that deal with the styles and colors of elements. They are 'stacking', so you need to remove them after applying or you overwrite all other mods and the CET windows too. Also if you don't remove them, CET or the Game may crash.
Colors are applied and removed with these two.
ImGui.PushStyleColor(<PART OF ELEMENT>, <COLOR>)
ImGui.PopStyleColor(<NUMBER OF COLOR DEFINITIONS>)
Styles (padding, alignment ..) are applied and removed with these two. Can have 1 or 2 values.
ImGui.PushStyleVar(<PART OF ELEMENT>, <VALUE>, <OPTIONAL>)
ImGui.PopStyleVar(<NUMBER OF STYLE DEFINITIONS>)
Each element in ImGui has it's own stylable parts, which is to much to list here. To get an idea, you always can refer to the ImGui source. See at Github at line ~1250. The colors are listed at line ~3357, see Github. Many element parts have multiple uses, like 'FramePadding' which can be applied to windows, the tabbar, tabs, collapsing headers and so on. To get an idea, here an simple example of a 'FramePadding' window. The values are horizontal and vertical pixels. I also show how to combine 'WindowFlags' which alter the behaviour of the generated window.
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, 5, 7)
ImGui.Begin("Name of the Window", ImGuiWindowFlags.NoTitleBar + ImGuiWindowFlags.NoScrollbar + ImGuiWindowFlags.NoScrollWithMouse)
ImGui.End()
ImGui.PopStyleVar(1)
Coloring our newly created window is the same deal as applying styles. Depending on the element you can colorize almost any part. In order to define a color, i prefer to use the command 'ImGui.GetColorU32(1, 0, 0, 0.5)', which has 4 values with Red, Green, Blue and the Alpha. The Range of those are 0.0 up to 1.0 which define the strength of the color. The Alpha defines the specific transparency of that color definition where 0.0 means complete transparency and 1.0 no transparency at all. If you create a transparent Button and the Window has it's own transparency, it will show the window color.
ImGui.PushStyleColor(ImGuiCol.WindowBg, ImGui.GetColorU32(1, 0, 0, 0.5))
ImGui.Begin("Name of the Window", ImGuiWindowFlags.NoTitleBar + ImGuiWindowFlags.NoScrollbar + ImGuiWindowFlags.NoScrollWithMouse)
ImGui.End()
ImGui.PopStyleColor(1)
We have now a half transparent red window without the title bar, awesome! :P
CET comes with an integrated list of icons called Glyphs. It's an large pool of fancy icons that can be used to enhance your UI. They can be used in any element that can have regular text, like a window title, a button or simple text field. If you look for an specific icon you can use this fancy listing Material Design Icons. In order to find the correct name you should look into the file '\cyber_engine_tweaks\scripts\IconGlyphs\icons.lua'. As example, on the website the 'clock' is called like 'clock-outline' while in CET it's 'ClockOutline'.
We take our red window and name it with the a glyph salad!
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, 5, 7)
ImGui.PushStyleColor(ImGuiCol.WindowBg, ImGui.GetColorU32(1, 0, 0, 0.5))
ImGui.Begin(IconGlyphs.ClockOutline..IconGlyphs.AlphaS..IconGlyphs.AlphaA..IconGlyphs.AlphaL..IconGlyphs.AlphaA..IconGlyphs.AlphaD)
ImGui.End()
ImGui.PopStyleColor(1)
ImGui.PopStyleVar(1)
This approach is kinda hacky, but works pretty well. ImGui allows negative values for the 'dummy' element which works like a manual padding. So if you know the exact width of an element, you can go back to the start of that element and 'overwrite' it with another element. This can be useful in terms of styling and usability. For CharLi i used a slider to draw an on/off switch like in Android or iOS, but you have to click on the right side to toggle it. To make it possible to click anywhere and toggle it, i first define the button and overwrite it with the slider of the same dimension. Usally it's the other way around.
First, the transparent button:
ImGui.PushStyleColor(ImGuiCol.Button, ImGui.GetColorU32(0, 0, 0, 0))
ImGui.PushStyleColor(ImGuiCol.ButtonActive, ImGui.GetColorU32(0, 0, 0, 0))
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, ImGui.GetColorU32(0, 0, 0, 0))
ImGui.PushID("Unique_Button_Name")
ImGui.Button("", 32, 18)
ImGui.PopID()
ImGui.PopStyleColor(3)
Now we can return to the starting point of the button:
ImGui.SameLine()
ImGui.Dummy(-32, 0)
ImGui.SameLine()
Finally paint the styled slider with transparent text:
ImGui.PushStyleVar(ImGuiStyleVar.GrabRounding, 10)
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 10)
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, 0, 0)
ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 2)
ImGui.PushStyleColor(ImGuiCol.Text, ImGui.GetColorU32(0, 0, 0, 0))
ImGui.PushStyleColor(ImGuiCol.Border, ImGui.GetColorU32(0.3, 0.3, 0.37, 0.7))
ImGui.PushStyleColor(ImGuiCol.FrameBg, ImGui.GetColorU32(0.2, 0.2, 0.27, 0.5))
ImGui.PushStyleColor(ImGuiCol.FrameBgActive, ImGui.GetColorU32(0.2, 0.2, 0.27, 0.5))
ImGui.PushStyleColor(ImGuiCol.FrameBgHovered, ImGui.GetColorU32(0.2, 0.2, 0.27, 0.5))
ImGui.PushStyleColor(ImGuiCol.SliderGrab, ImGui.GetColorU32(1, 0.56, 0.13, 0.85))
ImGui.PushStyleColor(ImGuiCol.SliderGrabActive, ImGui.GetColorU32(1, 0.56, 0.13, 0.7))
ImGui.SetNextItemWidth(32)
ImGui.PushID("Unique_Slider_Name")
ImGui.SliderInt("", value, 1, 0)
ImGui.PopID()
ImGui.PopStyleColor(7)
ImGui.PopStyleVar(4)
ImGui.SameLine()
ImGui.Text("The Real Title")
IMPORTEND: on elements with an empty title make sure you have an unique ID while using PushID and PopID, otherwise all elements will toggle at the same time.
Now we have a unique element with style und usability.
This technique works only if you know and define exact dimensions for the elements and only on the same line. You can't jump vertically in another line. That's a limitation of ImGui because it's line based.
to be continued...
Sadly there is no method in the GameOptions Family to determinate if an Option exist. Also the return values of Get* methods can be missleading. If GameOptions.GetBool returns a "false", you don't really know if it's the real value or the "false" for an not existing Option.
So i wrote a little workaround to get what i wanted and make autodetection possible. It doesn't avoid the "not found" message in the CET Console.
function GameOptions.Has(group, option)
if GameOptions.Get(group, option) ~= "" then
return true
end
return false
end
Sometimes there are Bugs you don't see while writing a CET Mod. You're asking yourself why the Game won't launch and try to locate the error. I document these findings, so other people may don't stumble over them.
If you define a local variable with an leading underscore in global space, any combination of the Game and CET won't start.
local _TRANSPARENCY = ImGui.GetColorU32(0, 0, 0, 0)