Normalize Cvar Values
If I'm I'm setting a boolean cvar and do:
]/set g_bot_level4 0
CVAR VALUE CHANGED: g_bot_level4 = 0 (1)
]/g_bot_level4
"g_bot_level4" - "0" - bool - whether bots use Tyrant - default: "on"
]/set g_bot_level4 off
CVAR VALUE CHANGED: g_bot_level4 = off (1)
]/g_bot_level4
"g_bot_level4" - "off" - bool - whether bots use Tyrant - default: "on"
0 and off are equivalent values yet a string compare won't catch them as such when doing Cvar::GetValue.
I'm sure similar problems exist for other cvar types too (maybe floating point?).
Currently, all of our normalization logic is only when you call the new C++ API in the engine.
We should normalize all cvars on set. I propose we do this by modifying the semantics of OnValueChanged to also return a normalized value and store that instead of the direct value the user passed in.
We should probably solve the float round trip problem first. You need a complicated algorithm to normalize a float without either losing precision or producing very ugly strings
std::string SerializeCvarValue(float value) {
// You'd need %.9g to guarantee a round trip but with 8 or 9 digits of precision you get
// stuff like 0.65f -> "0.649999976"
return Str::Format("%.7g", value);
}
For the case of reading cvar values in Lua, I would suggest adding more APIs like Cvar.getBool, Cvar.getNumber in addition to the current one which gets a string. We don't have to care about the type, if any, the cvar is registered as; just parse it as the requested type. Similar to RocketConditionalElement
Yes that's my workaround for now