diff --git a/crates/workshop-rs/src/bin/workshop-catalog-gen.rs b/crates/workshop-rs/src/bin/workshop-catalog-gen.rs index a95cbdb..f6d4ae1 100644 --- a/crates/workshop-rs/src/bin/workshop-catalog-gen.rs +++ b/crates/workshop-rs/src/bin/workshop-catalog-gen.rs @@ -1123,7 +1123,12 @@ mod corpus { ); index }; - let gamemodes = localized_index(export, &["gamemodes.", "customGameSettings.gamemodes."]); + let gamemodes = { + let mut index = + localized_index(export, &["gamemodes.", "customGameSettings.gamemodes."]); + merge_index(&mut index, data_index(export, "gamemodes")); + index + }; let maps = localized_index(export, &["maps."]); let heroes = localized_index(export, &["heroes."]); let teams = localized_index( @@ -1232,7 +1237,7 @@ mod corpus { "commit": meta.get("commit").and_then(Value::as_str).unwrap_or(""), "commitDate": meta.get("commitDate").and_then(Value::as_str).unwrap_or(""), "fetchedAt": meta.get("fetchedAt").and_then(Value::as_str).unwrap_or(""), - "method": "exact en-US spelling match between the declared settings surface (settings::table) and every locale translation carried by the export's customGameSettings/gamemodes/maps/heroes labels and other.customGameSettings tokens; the two hero Ultimate Generation labels are composed per reviewed locale from exact export templates and hero identities; entries without an accepted match keep fail-explicit behavior (ADR-0001 Decision 7)", + "method": "exact en-US spelling match between the declared settings surface (settings::table) and every locale translation carried by the export's customGameSettings/gamemodes/maps/heroes labels, direct data.gamemodes entries, and other.customGameSettings tokens; the two hero Ultimate Generation labels are composed per reviewed locale from exact export templates and hero identities; entries without an accepted match keep fail-explicit behavior (ADR-0001 Decision 7)", "sourceReview": "reviewed: workshop-rs commits its own settings mapping data; the user-provided JSON is build input only and is not redistributed", }, "labels": labels, @@ -1430,7 +1435,7 @@ mod corpus { #[cfg(test)] mod tests { - use super::{Index, en_aliases, match_en_aliases, set_zh_alias}; + use super::{Index, en_aliases, match_en_aliases, set_zh_alias, settings_corpus}; use serde_json::json; #[test] @@ -1490,5 +1495,26 @@ mod corpus { assert_eq!(entry["aliases"]["zh-CN"], json!(["中止", "中断"])); } + + #[test] + fn settings_corpus_includes_direct_gamemode_data() { + let export = json!({ + "data": { + "gamemodes": { + "ctf": { + "en-US": "Capture The Flag", + "zh-CN": "勇夺锦旗" + } + } + } + }); + + let settings = settings_corpus(&export).expect("settings corpus builds"); + assert_eq!(settings["modes"]["Capture The Flag"]["zh-CN"], "勇夺锦旗"); + assert_eq!( + settings["modes"]["Capture The Flag"]["sources"], + json!(["data.gamemodes.ctf"]) + ); + } } } diff --git a/crates/workshop-rs/src/settings/data/locales.json b/crates/workshop-rs/src/settings/data/locales.json index a5fdfbb..396bb92 100644 --- a/crates/workshop-rs/src/settings/data/locales.json +++ b/crates/workshop-rs/src/settings/data/locales.json @@ -17,8 +17,8 @@ "total": 2 }, "modes": { - "matched": 7, - "total": 7 + "matched": 8, + "total": 8 }, "teams": { "matched": 3, @@ -3472,6 +3472,13 @@ ], "zh-CN": "占领要点" }, + "Capture The Flag": { + "en-US": "Capture The Flag", + "sources": [ + "data.gamemodes.ctf" + ], + "zh-CN": "勇夺锦旗" + }, "Deathmatch": { "en-US": "Deathmatch", "sources": [ @@ -3512,7 +3519,7 @@ "provenance": { "source": "user-provided workshop-data export (workshop-data.json)", "sourceCommit": "d854bf01fc7bbf3b2169f67408c07a8da8989ad6", - "method": "generated current customGameSettings labels, value kinds, enum members, and paths; dynamic hero templates remain resolved through gameplay catalog identities" + "method": "generated current customGameSettings labels, value kinds, enum members, and paths; game mode headers use reviewed localized and direct data.gamemodes identities; dynamic hero templates remain resolved through gameplay catalog identities" }, "schemaVersion": 2, "teams": { diff --git a/crates/workshop-rs/tests/settings_pipeline.rs b/crates/workshop-rs/tests/settings_pipeline.rs index 6a017d3..5d10c32 100644 --- a/crates/workshop-rs/tests/settings_pipeline.rs +++ b/crates/workshop-rs/tests/settings_pipeline.rs @@ -67,6 +67,21 @@ fn reviewed_settings_conversion_round_trips_en_us_and_zh_cn() { assert_eq!(collapse(&back_to_en.text), collapse(&source)); } +#[test] +fn capture_the_flag_settings_emit_and_reparse_in_zh_cn() { + let catalog = catalog(); + let source = "settings { modes { Capture The Flag {} } }"; + let en = Locale::new("en-US"); + let zh = Locale::new("zh-CN"); + let program = parser::parse(source, &catalog, &en).expect("CTF settings parse"); + + let emitted = emitter::emit(&program, &catalog, &zh).expect("CTF settings emit"); + assert!(emitted.contains("勇夺锦旗"), "{emitted}"); + + let reparsed = parser::parse(&emitted, &catalog, &zh).expect("CTF settings reparse"); + assert!(roundtrip::equivalent(&program, &reparsed)); +} + #[test] fn composed_blizzard_settings_labels_convert_in_both_directions() { let source = "settings {