Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
69aa9f0
Feat: Added a language option in setting menu. Added a little test tr…
CaesinEachonson Aug 9, 2026
1eb8568
Fix: Gobo format check
CaesinEachonson Aug 9, 2026
ed38ba3
Feature: extract hardcoded strings in chapter creation session to en.…
CaesinEachonson Aug 10, 2026
b90fbdb
fix(localization): address review comments (lookups, fonts, CM_get_fo…
CaesinEachonson Aug 10, 2026
fadab29
Fix: address review comments
CaesinEachonson Aug 10, 2026
ca0a8d5
Fix: crash on switching language
CaesinEachonson Aug 10, 2026
9af5a62
Merge feat/localization-base into feat/zh-chapter-creation
CaesinEachonson Aug 10, 2026
3489afd
chore(l10n): refine translation strings
CaesinEachonson Aug 10, 2026
501a658
chore(l10n): refine translation strings
CaesinEachonson Aug 10, 2026
72c45be
fix: potential crash on opening squad view
CaesinEachonson Aug 11, 2026
d453c7b
merge: solve conflicts with main branch
CaesinEachonson Aug 11, 2026
1b87c88
fix: address review comments
CaesinEachonson Aug 11, 2026
8b11e6d
fix: address review comment
CaesinEachonson Aug 11, 2026
b93317a
fix: address review comment
CaesinEachonson Aug 11, 2026
4d0f5a3
fix: address review comment
CaesinEachonson Aug 11, 2026
df7585a
fix: address review comment
CaesinEachonson Aug 11, 2026
3fb4445
fix: address review comment
CaesinEachonson Aug 11, 2026
0899bec
address review comment
CaesinEachonson Aug 11, 2026
4d4d5ae
fix: address review comment
CaesinEachonson Aug 11, 2026
96a3eb1
fix: address review comment
CaesinEachonson Aug 12, 2026
7afe752
fix: address review comment
CaesinEachonson Aug 12, 2026
86d79a2
feat(l10n): translate module A1 - star/planet interface
CaesinEachonson Aug 16, 2026
5e76fc9
feat(l10n): translate module A2 - fleet, combat & unit management
CaesinEachonson Aug 16, 2026
408edd7
fix(l10n): align zh.json with glossary terms
CaesinEachonson Aug 16, 2026
1ae9a0c
feat(l10n): translate module A3 - recruitment & promotion
CaesinEachonson Aug 16, 2026
e633c22
fix(l10n): add ~28-char line breaks to aspirant trial descriptions
CaesinEachonson Aug 16, 2026
c87260c
feat(l10n): translate module A4 - trade, diplomacy, advisors, secret …
CaesinEachonson Aug 16, 2026
c0cc8d1
fix(l10n): align zh.json with updated glossary
CaesinEachonson Aug 16, 2026
ee51be5
Merge 7a58c5a1a (upstream zh-cn-localization #1431)
CaesinEachonson Aug 16, 2026
5e5a9d2
fix(l10n): wrap all A1-A4 draw fonts with cjk_font for CJK rendering
CaesinEachonson Aug 16, 2026
c467cf8
chore(l10n): refine translation string
CaesinEachonson Aug 16, 2026
4fdb3b1
refactor(l10n): drop redundant string() wrappers in recruit advisor r…
CaesinEachonson Aug 16, 2026
a47fc15
fix: address review comments
CaesinEachonson Aug 16, 2026
8d76965
fix: address review comments
CaesinEachonson Aug 16, 2026
f6f4bf2
fix: crash due to calling wrong function
CaesinEachonson Aug 16, 2026
afb21d7
Fix: address review comment; sync with Nyx's change on LocalizationMa…
CaesinEachonson Aug 16, 2026
9d3c1c1
fix: remove duplicated safeguard
CaesinEachonson Aug 16, 2026
515a881
Merge branch 'main' into feat/zh-cn-localization
OH296 Aug 16, 2026
a67a1c1
Apply suggestion from @OH296
OH296 Aug 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
821 changes: 777 additions & 44 deletions datafiles/lang/en.json

Large diffs are not rendered by default.

770 changes: 766 additions & 4 deletions datafiles/lang/zh.json

Large diffs are not rendered by default.

55 changes: 29 additions & 26 deletions objects/obj_controller/Draw_64.gml
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,19 @@ if (!zoomed && !zui) {
draw_set_color(c_white);

if (!instance_exists(obj_popup)) {
menu_buttons.chapter_manage.draw(34, 838 + y_slide, "Chapter Management", 1, 1, 145);
menu_buttons.chapter_settings.draw(179, 838 + y_slide, "Chapter Settings", 1, 1, 145);
menu_buttons.apoth.draw(357, 838 + y_slide, "Apothecarium");
menu_buttons.reclu.draw(473, 838 + y_slide, "Reclusium");
menu_buttons.lib.draw(590, 838 + y_slide, "Librarium");
menu_buttons.arm.draw(706, 838 + y_slide, "Armamentarium");
menu_buttons.recruit.draw(822, 838 + y_slide, "Recruitment");
menu_buttons.fleet.draw(938, 838 + y_slide, "Fleet");
menu_buttons.diplo.draw(1130, 838 + y_slide, "Diplomacy", 1, 1, 145);
menu_buttons.event.draw(1275, 838 + y_slide, "Event Log", 1, 1, 145);
menu_buttons.end_turn.draw(1420, 838 + y_slide, "End Turn", 1, 1, 145);
menu_buttons.help.draw(1374, 8 + y_slide, "Help");
menu_buttons.menu.draw(1484, 8 + y_slide, "Menu");
menu_buttons.chapter_manage.draw(34, 838 + y_slide, localize("Chapter Management"), 1, 1, 145);
menu_buttons.chapter_settings.draw(179, 838 + y_slide, localize("Chapter Settings"), 1, 1, 145);
menu_buttons.apoth.draw(357, 838 + y_slide, localize("Apothecarium"));
menu_buttons.reclu.draw(473, 838 + y_slide, localize("Reclusium"));
menu_buttons.lib.draw(590, 838 + y_slide, localize("Librarium"));
menu_buttons.arm.draw(706, 838 + y_slide, localize("Armamentarium"));
menu_buttons.recruit.draw(822, 838 + y_slide, localize("Recruitment"));
menu_buttons.fleet.draw(938, 838 + y_slide, localize("Fleet"));
menu_buttons.diplo.draw(1130, 838 + y_slide, localize("Diplomacy"), 1, 1, 145);
menu_buttons.event.draw(1275, 838 + y_slide, localize("Event Log"), 1, 1, 145);
menu_buttons.end_turn.draw(1420, 838 + y_slide, localize("End Turn"), 1, 1, 145);
menu_buttons.help.draw(1374, 8 + y_slide, localize("Help"));
menu_buttons.menu.draw(1484, 8 + y_slide, localize("Menu"));
}

if (y_slide > 0) {
Expand All @@ -113,19 +113,20 @@ if (!zoomed && !zui) {
}

draw_set_color(CM_GREEN_COLOR);
draw_set_font(fnt_menu);
draw_set_font(cjk_font(fnt_menu));
draw_set_halign(fa_center);
draw_set_valign(fa_top);
// Draws the sector name
var _sector_string = $"Sector {obj_ini.sector_name ?? "Terra Nova"}";
var _sector_string = localize("Sector {0}", [obj_ini.sector_name ?? "Terra Nova"]);
draw_text(775, 17, _sector_string);
draw_text(775.5, 17.5, _sector_string);

// Checks if you are penitent
if (faction_status[eFACTION.IMPERIUM] != "War") {
if (penitent_max == 0) {
draw_text(998, 17, "Loyal");
draw_text(998, 17.5, "Loyal");
var _loyal_text = localize("Loyal");
draw_text(998, 17, _loyal_text);
draw_text(998, 17.5, _loyal_text);
}
if (penitent_max > 0) {
var endb2 = "";
Expand All @@ -134,26 +135,28 @@ if (!zoomed && !zui) {
endb2 = " " + string(endb);
}
draw_set_color(c_red);
draw_text(998, 17, string(min(100, floor((penitent_current / penitent_max) * 100))) + "% Penitent");
draw_text(998, 17.5, string(min(100, floor((penitent_current / penitent_max) * 100))) + "% Penitent");
var _penitent_text = localize("{0}% Penitent", [string(min(100, floor((penitent_current / penitent_max) * 100)))]);
draw_text(998, 17, _penitent_text);
draw_text(998, 17.5, _penitent_text);
draw_set_color(CM_GREEN_COLOR);
// TODO Need a tooltip for here to display the actual amounts
}
}
// Sets you to renegade
if (faction_status[eFACTION.IMPERIUM] == "War") {
draw_set_color(255);
draw_text(998, 17, "Renegade");
draw_text(998, 17.5, "Renegade");
var _renegade_text = localize("Renegade");
draw_text(998, 17, _renegade_text);
draw_text(998, 17.5, _renegade_text);
draw_set_color(CM_GREEN_COLOR);
}
if (menu == eMENU.DEFAULT || menu == eMENU.TURN_END) {
if (imp_ships == 0 && turn < 2) {
sector_imperial_fleet_strength();
}
draw_text(850, 60, $"Sector Fleet Strength {imp_ships}/{max_fleet_strength}");
draw_text(850, 60, localize("Sector Fleet Strength {0}/{1}", [imp_ships, max_fleet_strength]));
if (scr_hit([700, 60, 1000, 80])) {
tooltip_draw("The relative strength of the imperial navy and defence fleet forces and their max supported strength. Increase The number of imperial aligned planets and active forge worlds to increase the limit");
tooltip_draw(localize("The relative strength of the imperial navy and defence fleet forces and their max supported strength. Increase The number of imperial aligned planets and active forge worlds to increase the limit"));
}
} // Checks if the chapter name is less than 140 chars, adjusts chapter_master_name_width accordingly
var chapter_master_name_width = 1;
Expand All @@ -175,7 +178,7 @@ if (!zoomed && !zui) {
if (income_last < 0) {
inc = string(round(income_last));
}
draw_set_font(fnt_40k_14);
draw_set_font(cjk_font(fnt_40k_14));
draw_set_halign(fa_left);
// Draws the requisition amount
draw_sprite(spr_new_resource, 0, 14, 16);
Expand Down Expand Up @@ -208,13 +211,13 @@ if (!zoomed && !zui) {
draw_text(485.5, 16.5, string(marines) + "/" + string(command));
pop_draw_return_values();
}
draw_set_font(fnt_40k_14b);
draw_set_font(cjk_font(fnt_40k_14b));
draw_set_color(c_red);
draw_set_halign(fa_left);
draw_set_alpha(1);
// Sets up debut mode
if (global.cheat_debug) {
draw_text(1124, 7, "DEBUG MODE");
draw_text(1124, 7, localize("DEBUG MODE"));
}

function draw_line(x1, y1, y_slide, variable) {
Expand Down
4 changes: 2 additions & 2 deletions objects/obj_controller/Step_0.gml
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,8 @@ try {
repair_ships = 0;

var pip = instance_create(0, 0, obj_popup);
pip.title = "Ships Repaired";
pip.text = "In accordance with the Imperial Repair License, all " + string(obj_ini.chapter_name) + " ships orbiting friendly planets have been repaired. Note that repaired ships, and their fleets, are unable to act further this turn.";
pip.title = localize("Ships Repaired");
pip.text = localize("In accordance with the Imperial Repair License, all {0} ships orbiting friendly planets have been repaired. Note that repaired ships, and their fleets, are unable to act further this turn.", [obj_ini.chapter_name]);
pip.image = "shipyard";
pip.cooldown = 15;

Expand Down
10 changes: 5 additions & 5 deletions objects/obj_popup/Draw_64.gml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ try {
}

if (type == ePOPUP_TYPE.FLEET_MOVE) {
draw_set_font(fnt_large);
draw_set_font(cjk_font(fnt_large));
draw_set_halign(fa_center);
draw_set_color(CM_GREEN_COLOR);
draw_text_transformed(320, 60, "SELECT DESTINATION", 0.5, 0.5, 0);
draw_text_transformed(320, 60, localize("SELECT DESTINATION"), 0.5, 0.5, 0);
draw_set_halign(fa_left);
} else if (type == 10) {
target_comp += 1;
Expand All @@ -52,20 +52,20 @@ try {
x1 = (1600 - sprite_width) / 2;
y1 = (900 - sprite_height * y_scale_mod) / 2;

draw_set_font(fnt_40k_14b);
draw_set_font(cjk_font(fnt_40k_14b));
draw_set_halign(fa_center);
draw_set_color(CM_GREEN_COLOR);

if (fancy_title == 1) {
draw_set_font(fnt_fancy);
draw_set_font(cjk_font(fnt_fancy));
if (type == 1) {
draw_set_color(255);
}
}
draw_text_transformed(x1 + (sprite_width / 2), y1 + (sprite_height * 0.07), string_hash_to_newline(string(title)), 1.1, 1.1, 0);
// draw_text(xx+320.5,yy+123.5,string(title));

draw_set_font(fnt_40k_14);
draw_set_font(cjk_font(fnt_40k_14));
draw_set_halign(fa_left);
draw_set_color(CM_GREEN_COLOR);

Expand Down
4 changes: 2 additions & 2 deletions objects/obj_star/Draw_0.gml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ if (storm > 0) {
//ad hoc way of determining whether stuff is in view or not...needs work

draw_set_halign(fa_center);
draw_set_font(fnt_cul_14);
draw_set_font(cjk_font(fnt_cul_14));
draw_set_alpha(1);

if (global.load == -1 && (obj_controller.zoomed || in_camera_view(star_box_shape()))) {
if (garrison) {
draw_sprite(spr_new_resource, 3, x - 30, y + 15);
if (scr_hit(x - 40, y + 10, x - 10, y + 35)) {
tooltip_draw("Marine Garrison in system");
tooltip_draw(localize("Marine Garrison in system"));
}
}
if (point_in_rectangle(mouse_x, mouse_y, x - 128, y, x + 128, y + 80) && obj_controller.zoomed) {
Expand Down
4 changes: 2 additions & 2 deletions objects/obj_star_select/Create_0.gml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ debug_options = new RadioSet([
{
str1: "Add Feature",
},
], "Debug options", {
], localize("Debug options"), {
x1: 36,
y1: 129,
max_width: 300,
Expand All @@ -61,7 +61,7 @@ garrison = "";
population = false;

garrison_data_slate = new DataSlate();
garrison_data_slate.title = "Garrison Report";
garrison_data_slate.title = localize("Garrison Report");
main_data_slate = new DataSlate();

potential_donors = [];
Expand Down
38 changes: 19 additions & 19 deletions objects/obj_star_select/Draw_64.gml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if (obj_controller.menu == 60) {
}

add_draw_return_values();
draw_set_font(fnt_40k_14b);
draw_set_font(cjk_font(fnt_40k_14b));
draw_set_halign(fa_center);
draw_set_valign(fa_top);
draw_set_color(0);
Expand Down Expand Up @@ -95,7 +95,7 @@ try {
draw_sprite_ext(spr_servo_right_arm, 0, 27, 165 + _screen_height / 3, 2, 2, 0, c_white, 1);
draw_sprite_ext(spr_servo_skull_head, 0, 27 + _screen_width / 2, 165, 2, 2, 0, c_white, 1);

var system_string = $"{target.name} System";
var system_string = target.name + " " + localize("System");

draw_set_color(target.owner == eFACTION.PLAYER ? c_blue : 0);

Expand All @@ -116,7 +116,7 @@ try {
var _unit_dispersement = _viewer.garrison_log;
var _sys_name = target.name;
if (struct_exists(_unit_dispersement, target.name)) {
group_selection(_unit_dispersement[$ _sys_name].units, {purpose: $"{target.name} Management", purpose_code: "manage", number: 0, system: target.id, feature: "none", planet: 0, selections: []});
group_selection(_unit_dispersement[$ _sys_name].units, {purpose: localize("{0} Management", [target.name]), purpose_code: "manage", number: 0, system: target.id, feature: "none", planet: 0, selections: []});
instance_destroy();
pop_draw_return_values();
exit;
Expand All @@ -125,17 +125,17 @@ try {
}

if (loading != 0) {
draw_set_font(fnt_40k_14);
draw_set_font(cjk_font(fnt_40k_14));
draw_set_color(CM_GREEN_COLOR);
draw_text(184, 202, "Select Destination");
draw_text(184, 202, localize("Select Destination"));
}

//the draw and click on planets logic
if (!debug) {
planet_selection_action();
}

draw_set_font(fnt_40k_14b);
draw_set_font(cjk_font(fnt_40k_14b));

var _planet = obj_controller.selecting_planet;
if (_planet != 0) {
Expand Down Expand Up @@ -236,13 +236,13 @@ try {
}
} else if (garrison != "" && !population && garrison.planet == obj_controller.selecting_planet) {
if (garrison.garrison_force) {
draw_set_font(fnt_40k_14);
draw_set_font(cjk_font(fnt_40k_14));

garrison_data_slate.sub_title = $"Garrison Leader {garrison.garrison_leader.name_role()}";
garrison_data_slate.sub_title = localize("Garrison Leader {0}", [garrison.garrison_leader.name_role()]);
garrison_data_slate.body_text = garrison.garrison_report();

garrison_data_slate.inside_method = function() {
garrison_data_slate.title = "Garrison Report";
garrison_data_slate.title = localize("Garrison Report");
draw_set_color(c_gray);
var xx = garrison_data_slate.XX;
var yy = garrison_data_slate.YY;
Expand All @@ -251,25 +251,25 @@ try {
draw_set_halign(fa_left);
draw_line(xx + 10, half_way, garrison_data_slate.width - 10, half_way);
var defence_data = determine_pdf_defence(target.p_pdf[cur_planet], garrison, target.p_fortified[cur_planet]);
var defence_string = $"Planetary Defence : {defence_data[0]}";
var defence_string = localize("Planetary Defence : {0}", [defence_data[0]]);
draw_text(xx + 20, half_way, defence_string);
if (scr_hit(xx + 20, half_way + 10, xx + 20 + string_width(defence_string), half_way + 10 + 20)) {
tooltip_draw(defence_data[1], 400);
}

var _dispo_change = garrison.dispo_change;
if (_dispo_change > 55) {
draw_text(xx + 20, half_way + 30, $"Garrison Disposition Effect : Positive");
draw_text(xx + 20, half_way + 30, localize("Garrison Disposition Effect : Positive"));
} else if (_dispo_change > 44 || _dispo_change == 0) {
draw_text(xx + 20, half_way + 30, $"Garrison Disposition Effect : Neutral");
draw_text(xx + 20, half_way + 30, localize("Garrison Disposition Effect : Neutral"));
} else {
draw_text(xx + 20, half_way + 30, $"Garrison Disposition Effect : Negative");
draw_text(xx + 20, half_way + 30, localize("Garrison Disposition Effect : Negative"));
}
};
garrison_data_slate.draw(340 + main_data_slate.width, 160, 0.6, 0.6);
}
} else if (population) {
garrison_data_slate.title = "Population Report";
garrison_data_slate.title = localize("Population Report");
garrison_data_slate.inside_method = function() {
p_data.draw_planet_population_controls();
};
Expand All @@ -283,7 +283,7 @@ try {
var shutter_y = 296 + 165;
if (!debug) {
for (var i = 0; i < array_length(buttons); i++) {
if (shutters[i].draw_shutter(shutter_x, shutter_y + (47 * i), buttons[i], 0.5, true)) {
if (shutters[i].draw_shutter(shutter_x, shutter_y + (47 * i), localize(buttons[i]), 0.5, true)) {
current_button = buttons[i];
}
}
Expand Down Expand Up @@ -382,12 +382,12 @@ try {
draw_set_halign(fa_left);

draw_set_color(0);
draw_set_font(fnt_40k_14b);
draw_text(37, 413, "Select Fleet Combat");
draw_set_font(cjk_font(fnt_40k_14b));
draw_text(37, 413, localize("Select Fleet Combat"));

draw_set_color(CM_GREEN_COLOR);
draw_set_font(fnt_40k_14b);
draw_text(37.5, 413.5, "Select Fleet Combat");
draw_set_font(cjk_font(fnt_40k_14b));
draw_text(37.5, 413.5, localize("Select Fleet Combat"));

var x3 = 49, y3 = 441;

Expand Down
26 changes: 9 additions & 17 deletions scripts/LocalizationManager/LocalizationManager.gml
Original file line number Diff line number Diff line change
Expand Up @@ -165,23 +165,14 @@ function LocalizationManager() constructor {
/// English always restores the original English names. Call from
/// SettingsManager.apply_language().
static refresh_locale_globals = function() {
for (var i = 0; i < array_length(global.faction_names_en); i++) {
global.faction_names[i] = self.translate(global.faction_names_en[i]);
}

// Rebuild each live rating array from its pristine English source, exactly like
// faction_names above. Writes go directly through each global accessor so the live
// array CoW-copies away from the shared _en source; translating from English each time
// keeps the call idempotent and round-trip safe.
for (var i = 0; i < array_length(global.chapter_strength_ratings_en); i++) {
global.chapter_strength_ratings[i] = self.translate(global.chapter_strength_ratings_en[i]);
}
for (var i = 0; i < array_length(global.chapter_cooperation_ratings_en); i++) {
global.chapter_cooperation_ratings[i] = self.translate(global.chapter_cooperation_ratings_en[i]);
}
for (var i = 0; i < array_length(global.chapter_geneseed_ratings_en); i++) {
global.chapter_geneseed_ratings[i] = self.translate(global.chapter_geneseed_ratings_en[i]);
}
global.faction_names = self.localize_array(global.faction_names_en);
global.chapter_strength_ratings = self.localize_array(global.chapter_strength_ratings_en);
global.chapter_cooperation_ratings = self.localize_array(global.chapter_cooperation_ratings_en);
global.chapter_geneseed_ratings = self.localize_array(global.chapter_geneseed_ratings_en);
global.planet_forti = self.localize_array(global.planet_forti_en);
global.presence_factions = self.localize_array(global.presence_factions_en);
global.presence_blurbs = self.localize_array(global.presence_blurbs_en);
global.planet_size = self.localize_array(global.planet_size_en);
};

/// @param {Real} _base_font The font asset intended for this text.
Expand Down Expand Up @@ -314,6 +305,7 @@ function localize_array(_keys) {
/// @returns {Real}
function cjk_font(_base_font) {
if (!variable_global_exists("localization_manager") || !global.localization_manager.needs_cjk) {

return _base_font;
}

Expand Down
Loading
Loading