Skip to content

Commit 95603af

Browse files
committed
Map Wuwa settings to verified values
1 parent 6129129 commit 95603af

2 files changed

Lines changed: 73 additions & 32 deletions

File tree

Hi3Helper.Plugin.Wuwa/Management/Settings/WuwaGameSettings.cs

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,23 @@ internal sealed class WuwaGameSettings
1414
private const string GameUserSettingsSection = "/Script/Engine.GameUserSettings";
1515
private const string LocalKeyPrefix = "local.";
1616

17+
// See docs/wuwa-settings-mappings.md for the versioned mapping sources and limitations.
1718
private static readonly LocalSettingSection[] LocalSettingSections =
1819
[
1920
new("Graphics", [
2021
Toggle("AutoAdjustImageQuality", "Automatically adjust image quality"),
21-
Level("ImageQuality", "Image quality preset", 4),
22-
Level("ImageDetail", "Image detail", 4),
23-
Level("ShadowQuality", "Shadow quality", 4),
24-
Level("AntiAliasing", "Anti-aliasing", 4),
25-
Level("AnisoLevel", "Anisotropic filtering", 4),
26-
Level("MotionBlur", "Motion blur", 3),
27-
Level("NiagaraQuality", "Effects quality", 4),
28-
Level("NpcDensity", "NPC density", 4),
29-
Level("VegetationDensity", "Vegetation density", 4),
30-
Level("LoadingRangeScaleLevel", "View distance", 4),
31-
Level("VolumeFog", "Volumetric fog", 4),
32-
Level("VolumeLight", "Volumetric lighting", 4),
22+
Choice("ImageQuality", "Graphics quality", [new("0", "Ultra Performance"), new("1", "Performance"), new("2", "Balanced"), new("3", "Quality"), new("4", "High Quality"), new("5", "Ultra Quality")]),
23+
Choice("ImageDetail", "LOD bias", [new("0", "Low"), new("1", "Medium"), new("2", "High"), new("3", "Ultra High")]),
24+
Choice("ShadowQuality", "Shadow quality", [new("0", "Low"), new("1", "Medium"), new("2", "High"), new("3", "Ultra High")]),
25+
Choice("AntiAliasing", "Anti-aliasing", [new("0", "Off"), new("1", "On")]),
26+
Choice("AnisoLevel", "Anisotropic filtering", [new("0", "1x"), new("1", "2x"), new("2", "4x"), new("3", "8x"), new("4", "16x")]),
27+
Choice("MotionBlur", "Motion blur", [new("0", "Off"), new("1", "Low"), new("2", "Medium"), new("3", "High")]),
28+
Choice("NiagaraQuality", "Special effects quality", [new("0", "Low"), new("1", "Medium"), new("2", "High")]),
29+
Choice("NpcDensity", "Crowd density", [new("0", "Low"), new("1", "Medium"), new("2", "High")]),
30+
Choice("VegetationDensity", "Foliage density", [new("0", "Low"), new("1", "Medium"), new("2", "High"), new("3", "Ultra High")]),
31+
Choice("LoadingRangeScaleLevel", "Render distance", [new("0", "Default"), new("1", "Far"), new("2", "Farthest")]),
32+
Choice("VolumeFog", "Volumetric fog", [new("0", "Off"), new("1", "Low"), new("2", "Medium"), new("3", "High")]),
33+
Choice("VolumeLight", "Volumetric lighting", [new("0", "Off"), new("1", "On")]),
3334
Toggle("SceneAo", "Ambient occlusion"),
3435
Toggle("BloomEnable", "Bloom"),
3536
Toggle("AutoExposure", "Automatic exposure"),
@@ -38,11 +39,11 @@ internal sealed class WuwaGameSettings
3839
Toggle("VegetationDither", "Vegetation dithering"),
3940
Toggle("WaterInteract", "Water interaction"),
4041
Toggle("FlowAdaptation", "Flow adaptation"),
41-
Toggle("RayTracing", "Ray tracing"),
42+
Choice("RayTracing", "Ray tracing", [new("0", "Off"), new("1", "Low"), new("2", "Medium"), new("3", "High")]),
4243
Toggle("NvidiaSuperSamplingEnable", "NVIDIA super sampling"),
4344
Choice("NvidiaSuperSamplingQuality", "NVIDIA super-sampling preset", [
44-
new("99", "Automatic"), new("0", "Preset 0"), new("1", "Preset 1"),
45-
new("2", "Preset 2"), new("3", "Preset 3"), new("4", "Preset 4")
45+
new("99", "Auto"), new("-2", "Ultimate Performance"), new("-1", "Performance"),
46+
new("0", "Balanced"), new("1", "Quality"), new("3", "DLAA")
4647
]),
4748
Slider("NvidiaSuperSamplingSharpness", "NVIDIA sharpening", 0, 100),
4849
Slider("Brightness", "Brightness", -100, 100),
@@ -74,33 +75,37 @@ internal sealed class WuwaGameSettings
7475
Slider("GamepadLeftStickDeadZone", "Left-stick dead zone", 0, 100),
7576
Slider("GamepadRightStickDeadZone", "Right-stick dead zone", 0, 100),
7677
Slider("JoystickShakeStrength", "Controller vibration strength", 0, 100),
77-
Level("JoystickShakeType", "Controller vibration mode", 3),
78-
Level("CameraShakeStrength", "Camera shake", 3),
79-
Level("CommonSpringArmLength", "Exploration camera distance", 3),
80-
Level("FightSpringArmLength", "Combat camera distance", 3),
81-
Level("KeyboardLockEnemyMode", "Keyboard enemy-lock mode", 3),
82-
Level("GamepadLockEnemyMode", "Controller enemy-lock mode", 3),
83-
Level("SkillLockEnemyMode", "Skill enemy-lock mode", 3)
78+
Choice("JoystickShakeType", "Controller vibration range", [new("0", "Full"), new("1", "Partial"), new("2", "Off")]),
79+
Choice("CameraShakeStrength", "Camera shake intensity", [new("0", "Low"), new("1", "Medium"), new("2", "High")]),
80+
Slider("CommonSpringArmLength", "Regular camera distance", 0, 100),
81+
Slider("FightSpringArmLength", "Combat camera distance", 0, 100),
82+
Choice("KeyboardLockEnemyMode", "Keyboard enemy-lock mode", [], "The in-game mapping for this internal setting is unverified. Its current value is preserved."),
83+
Choice("GamepadLockEnemyMode", "Controller enemy-lock mode", [], "The in-game mapping for this internal setting is unverified. Its current value is preserved."),
84+
Choice("SkillLockEnemyMode", "Skill enemy-lock mode", [], "The in-game mapping for this internal setting is unverified. Its current value is preserved.")
8485
]),
8586
new("Gameplay and accessibility", [
86-
Level("EnemyHitDisplayMode", "Enemy hit display", 3),
87-
Level("FlyControlMode", "Flight control mode", 3),
87+
Choice("EnemyHitDisplayMode", "Enemy hit flash", [new("0", "Off"), new("1", "On")]),
88+
Choice("FlyControlMode", "Flight control mode", [], "The in-game mapping for this internal setting is unverified. Its current value is preserved."),
8889
Toggle("ShowDamage", "Show damage numbers"),
8990
Toggle("ShowOtherName", "Show other player names"),
9091
Toggle("SubTitleOption", "Subtitles"),
9192
Toggle("PhotoAndShareShowPlayerName", "Show player name in photos"),
9293
Slider("WalkOrRunRate", "Walk/run transition", 0, 1, 0.05),
9394
Toggle("EyeProtection", "Eye-protection mode"),
94-
Level("EyeProtectionMode", "Eye-protection preset", 3),
95+
Choice("EyeProtectionMode", "Eye-protection preset", [], "The in-game mapping for this internal setting is unverified. Its current value is preserved."),
9596
Slider("EyeProtectionBrightness", "Eye-protection brightness", 0, 1, 0.05),
9697
Slider("EyeProtectionStrength", "Eye-protection strength", 0, 1, 0.05),
9798
Slider("EyeProtectionTexture", "Eye-protection texture", 0, 1, 0.05),
9899
Slider("EyeProtectionTemp", "Eye-protection color temperature", 1000, 10000, 100)
99100
]),
100101
new("Language", [
101-
Level("TextLanguage", "Text language", 20),
102-
Level("VoiceLanguage", "Voice-over language", 20)
103-
], "Language values are game-defined numeric identifiers. Change them only if you know the identifier used by your installed client.")
102+
Choice("TextLanguage", "Text language", [
103+
new("0", "Simplified Chinese"), new("5", "Traditional Chinese"), new("1", "English"),
104+
new("2", "Japanese"), new("3", "Korean"), new("6", "German"), new("7", "Spanish"),
105+
new("8", "Portuguese"), new("10", "French"), new("12", "Thai")
106+
]),
107+
Choice("VoiceLanguage", "Voice-over language", [new("0", "Mandarin"), new("1", "English"), new("2", "Japanese"), new("3", "Korean")])
108+
], "Voice-over languages require the corresponding voice pack to be installed.")
104109
];
105110

106111
private readonly string _gameUserSettingsPath;
@@ -287,7 +292,7 @@ private static GameSettingEntry CreateLocalEntry(LocalSetting setting, string va
287292
}
288293

289294
private static IReadOnlyList<GameSettingChoice> AddUnknownChoice(IReadOnlyList<GameSettingChoice> choices, string value) =>
290-
choices.Any(choice => choice.Value == value) ? choices : [.. choices, new(value, $"Unknown ({value})")];
295+
choices.Any(choice => choice.Value == value) ? choices : [.. choices, new(value, $"Unverified value ({value})")];
291296

292297
private static LocalSetting FindLocalSetting(string key) =>
293298
LocalSettingSections.SelectMany(section => section.Settings).FirstOrDefault(setting => setting.Key == key)
@@ -300,9 +305,6 @@ private static LocalSetting Slider(string key, string title, double minimum, dou
300305
string? description = null) =>
301306
new(key, title, LocalSettingKind.Number, minimum, maximum, step, null, description);
302307

303-
private static LocalSetting Level(string key, string title, int maximum, string? description = null) =>
304-
Choice(key, title, [.. Enumerable.Range(0, maximum + 1).Select(level => new GameSettingChoice(level.ToString(CultureInfo.InvariantCulture), $"Level {level}"))], description);
305-
306308
private static LocalSetting Choice(string key, string title, IReadOnlyList<GameSettingChoice> choices,
307309
string? description = null) =>
308310
new(key, title, LocalSettingKind.Choice, 0, 0, 1, choices, description);

docs/wuwa-settings-mappings.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Wuthering Waves settings mappings
2+
3+
Option values and English labels come from extracted **3.6** game tables, matching the inspected installation's version 3.6.0. These are community-hosted game-data extracts, not official API documentation.
4+
5+
Sources:
6+
- [menuconfig.json](https://github.com/Arikatsu/WutheringWaves_Data/blob/3.6/BinData/menu/menuconfig.json): pair OptionsValue with localized OptionsName; use SliderRange for slider bounds.
7+
- [English MultiText.json](https://github.com/Arikatsu/WutheringWaves_Data/blob/3.6/Textmaps/en/multi_text/MultiText.json): option text.
8+
- [languagedefine.json](https://github.com/Arikatsu/WutheringWaves_Data/blob/3.6/BinData/menu/languagedefine.json): LanguageType IDs; only IsShow languages are offered.
9+
- [rolevoicelanguage.json](https://github.com/Arikatsu/WutheringWaves_Data/blob/3.6/BinData/menu/rolevoicelanguage.json): voice language IDs and text.
10+
11+
| LocalStorage key | Menu FunctionId |
12+
| --- | --- |
13+
| ImageQuality | 10 |
14+
| ShadowQuality | 54 |
15+
| NiagaraQuality | 55 |
16+
| ImageDetail | 56 |
17+
| AntiAliasing | 57 |
18+
| VolumeFog | 63 |
19+
| VolumeLight | 64 |
20+
| MotionBlur | 65 |
21+
| NpcDensity | 79 |
22+
| NvidiaSuperSamplingQuality | 831 |
23+
| CameraShakeStrength | 93 |
24+
| CommonSpringArmLength | 99 |
25+
| FightSpringArmLength | 100 |
26+
| JoystickShakeType | 105 |
27+
| EnemyHitDisplayMode | 135 |
28+
| AnisoLevel | 20004 |
29+
| RayTracing | 20026 |
30+
| VegetationDensity | 20035 |
31+
| LoadingRangeScaleLevel | 20611 |
32+
33+
The LocalStorage-key associations are inferred from matching names and semantics; the menu table itself uses FunctionIds. A read-only database check corroborated ImageDetail=2, ShadowQuality=3, VolumeLight=1, ImageQuality=3 and NVIDIA quality=99. This is not an exhaustive in-game round-trip test.
34+
35+
Graphics presets merge device-dependent lists. Availability still depends on hardware and game version; the plugin does not evaluate the game's Device predicates. Existing values outside the lists remain visible as `Unverified value (n)` and are not changed merely by opening or applying the page.
36+
37+
Unresolved internal enums: KeyboardLockEnemyMode, GamepadLockEnemyMode, SkillLockEnemyMode, FlyControlMode and EyeProtectionMode. These offer only their existing value until their storage mapping is established. Do not infer their values from similarly named menu controls.
38+
39+
The generic Level lists are removed. Ray tracing becomes a quality selector, and regular/combat camera distance becomes a 0–100 slider. No installed game files are modified by this source change.

0 commit comments

Comments
 (0)