@VictorPhilipp If you can dump some basic info in here - even just links to existing C# or xml files or whatever, if it's obvious from looking at them what to do - I'll add a wiki page to document it.
I've made quick test.
It's quite easy and seems to be working (at least in the mod options):
Build Action to Embedded Resource in file Properties (Visual Studio),AVAILABLE_LANGUAGE_CODES.Add("suffix_of_new_language");LANGUAGE_LABELS["suffix_of_new_language"] = "lang name in native language"; - label displayed as language option the mod options"suffix_of_new_language has to be the same as suffix of language file in Resources
e.g. lang_en.txt, so suffix en obviously 馃槈
There isn't a lang_en.txt in the resources folder though?
I'm not sure what this step means:
- set Build Action to Embedded Resource in file Properties (Visual Studio),
I would assume one just goes to the Resources folder, right-click to add new item, and then select the lang file?

And then edit the Translation.cs in the usual manner?
Ah, after adding file to Resources folder in VS, right-click file > properties, then set Embedded Resource:

Also, what are we doing about lang_template.txt?
Currently our updated localisation guide states to use lang.txt as that contains the actual text of the locale keys.
Here's initial draft in the wiki: https://github.com/krzychu124/Cities-Skylines-Traffic-Manager-President-Edition/wiki/Adding-a-new-language
Oh, you're too quick for me :)
lang_template.txt is there to help translators such that they don't have to remove every English translation from the lang.txt when they introduce a new language.
(off topic) What do you think about moving to XML-based localization files? For example:

I like idea of moving to XML. Then we could automate the process of registering new language.
We could include a section in the xml for the locales and their captions too:
...
<Languages>
<Language lang="en">English</Language>
<Language lang="fr">Fran莽ais</Language>
...
</Languages>
<Translations>
<Translation key="Road_type">
<Value lang="en">Road type</Value>
<Value lang="fr">Type de route</Value>
...
</Translation>
...
</Translations>
...
Would we still use \n for newlines, or would we start using <![CDATA[ ... ]]> stuff?
Also, I think we have to factor in translators too - is using XML making their job more complex or easier? If the current format is easier for them, maybe we could have some sort of build process that converts the lang_*.txt in to centralised lang.xml file?
What happens if two users submit translations at the same time (which happened recently - French and Japanese if memory serves)? I assume github will be able to merge easily, but will any merge-related stuff on-screen deter translators?
Another consideration is RAM consumption - would we be loading and retain whole XML, or would we just parse it to get the relevant strings for the active language?
Regarding missing translations, we could spit those out to the log file in DEBUG builds.
<Translation><Language><Value> not found for the language, trace details to log fileBetter still, if we could dump the info in to a markdown file we could then add that to the repo or wiki so translators know what needs translating in their language. We could also state what percentage each language is at.
If a specific <Translation> isn't yet localised to a specific language, the <Value> for that language would be omitted from the file. In RELEASE builds, when loading the local file, we'd just default to the <Value lang="en"> for the given <Translation> if the desired language is not found.
I'm making a simple html file to parse the lang_*.txt files in order to compile an xml file. If there's anything you want to know about the translations, which can be determined when I parse the files, let me know. :)
I filtered out any translations that were exact match of the English value, so these stats aren't 100% accurate.
Start, min/max, Segment, TMPE_Title, Name, Imperial, Gameplay, Overlays, Simulation, Strict, TMPE_TUTORIAL_HEAD_MainMenu, Turn_on_red, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods,
TMPE_Title, Imperial, General, Individual_driving_styles, Simulation, On_roads, Ban_private_cars_and_trucks_on_bus_lanes, default, flow_ratio, wait_ratio, After_min._time_has_elapsed_switch_to_next_step_if, Adaptive_step_switching, Dynamic_lane_section, Percentage_of_vehicles_performing_dynamic_lane_section, Vehicle_restrictions_aggression, Strict, Show_path-find_stats, Remove_this_vehicle, Vehicles_follow_priority_rules_at_junctions_with_timed_traffic_lights, Enable_tutorial_messages, TMPE_TUTORIAL_HEAD_MainMenu, TMPE_TUTORIAL_BODY_MainMenu, TMPE_TUTORIAL_HEAD_JunctionRestrictionsTool, TMPE_TUTORIAL_BODY_JunctionRestrictionsTool, TMPE_TUTORIAL_HEAD_LaneArrowTool, TMPE_TUTORIAL_BODY_LaneArrowTool, TMPE_TUTORIAL_HEAD_LaneConnectorTool, TMPE_TUTORIAL_BODY_LaneConnectorTool, TMPE_TUTORIAL_HEAD_ManualTrafficLightsTool, TMPE_TUTORIAL_BODY_ManualTrafficLightsTool, TMPE_TUTORIAL_HEAD_ParkingRestrictionsTool, TMPE_TUTORIAL_BODY_ParkingRestrictionsTool, TMPE_TUTORIAL_HEAD_PrioritySignsTool, TMPE_TUTORIAL_BODY_PrioritySignsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool, TMPE_TUTORIAL_BODY_SpeedLimitsTool, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool, TMPE_TUTORIAL_HEAD_ToggleTrafficLightsTool, TMPE_TUTORIAL_BODY_ToggleTrafficLightsTool, TMPE_TUTORIAL_HEAD_VehicleRestrictionsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_BODY_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_RemoveJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_RemoveJunction, Public_transport, Prevent_excessive_transfers_at_public_transport_stations, Compact_main_menu, Window_transparency, Overlay_transparency, Remove_this_citizen, Remove_parked_vehicles, Node_is_level_crossing, Experimental_features, Turn_on_red, Also_apply_to_left/right_turns_between_one-way_streets, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods, Notify_me_if_there_is_an_unexpected_mod_conflict,
Stop, min/max, Segment, Maintenance, Gameplay, Individual_driving_styles, Options, Simulation,
Stop, min/max, TMPE_Title, Outgoing_demand, Incoming_demand, Parking_AI, Gameplay, Overlays, Individual_driving_styles, Enable_tutorial_messages, TMPE_TUTORIAL_HEAD_MainMenu, TMPE_TUTORIAL_BODY_MainMenu, TMPE_TUTORIAL_HEAD_JunctionRestrictionsTool, TMPE_TUTORIAL_BODY_JunctionRestrictionsTool, TMPE_TUTORIAL_HEAD_LaneArrowTool, TMPE_TUTORIAL_BODY_LaneArrowTool, TMPE_TUTORIAL_HEAD_LaneConnectorTool, TMPE_TUTORIAL_BODY_LaneConnectorTool, TMPE_TUTORIAL_HEAD_ManualTrafficLightsTool, TMPE_TUTORIAL_BODY_ManualTrafficLightsTool, TMPE_TUTORIAL_HEAD_ParkingRestrictionsTool, TMPE_TUTORIAL_BODY_ParkingRestrictionsTool, TMPE_TUTORIAL_HEAD_PrioritySignsTool, TMPE_TUTORIAL_BODY_PrioritySignsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool, TMPE_TUTORIAL_BODY_SpeedLimitsTool, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool, TMPE_TUTORIAL_HEAD_ToggleTrafficLightsTool, TMPE_TUTORIAL_BODY_ToggleTrafficLightsTool, TMPE_TUTORIAL_HEAD_VehicleRestrictionsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_BODY_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_RemoveJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_RemoveJunction, Public_transport, Prevent_excessive_transfers_at_public_transport_stations, Compact_main_menu, Window_transparency, Overlay_transparency, Remove_this_citizen, Remove_parked_vehicles, Node_is_level_crossing, Experimental_features, Also_apply_to_left/right_turns_between_one-way_streets, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods, Notify_me_if_there_is_an_unexpected_mod_conflict,
TMPE_Title, Individual_driving_styles, TMPE_TUTORIAL_HEAD_MainMenu, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods,
Individual_driving_styles, TMPE_TUTORIAL_HEAD_MainMenu,
Start, Stop, min/max, Segment, Individual_driving_styles, Simulation, On_roads, Ban_private_cars_and_trucks_on_bus_lanes, default, flow_ratio, wait_ratio, After_min._time_has_elapsed_switch_to_next_step_if, Adaptive_step_switching, Dynamic_lane_section, Percentage_of_vehicles_performing_dynamic_lane_section, Vehicle_restrictions_aggression, Strict, Show_path-find_stats, Remove_this_vehicle, Vehicles_follow_priority_rules_at_junctions_with_timed_traffic_lights, Enable_tutorial_messages, TMPE_TUTORIAL_HEAD_MainMenu, TMPE_TUTORIAL_BODY_MainMenu, TMPE_TUTORIAL_HEAD_JunctionRestrictionsTool, TMPE_TUTORIAL_BODY_JunctionRestrictionsTool, TMPE_TUTORIAL_HEAD_LaneArrowTool, TMPE_TUTORIAL_BODY_LaneArrowTool, TMPE_TUTORIAL_HEAD_LaneConnectorTool, TMPE_TUTORIAL_BODY_LaneConnectorTool, TMPE_TUTORIAL_HEAD_ManualTrafficLightsTool, TMPE_TUTORIAL_BODY_ManualTrafficLightsTool, TMPE_TUTORIAL_HEAD_ParkingRestrictionsTool, TMPE_TUTORIAL_BODY_ParkingRestrictionsTool, TMPE_TUTORIAL_HEAD_PrioritySignsTool, TMPE_TUTORIAL_BODY_PrioritySignsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool, TMPE_TUTORIAL_BODY_SpeedLimitsTool, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool, TMPE_TUTORIAL_HEAD_ToggleTrafficLightsTool, TMPE_TUTORIAL_BODY_ToggleTrafficLightsTool, TMPE_TUTORIAL_HEAD_VehicleRestrictionsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_BODY_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_RemoveJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_RemoveJunction, Public_transport, Prevent_excessive_transfers_at_public_transport_stations, Compact_main_menu, Window_transparency, Overlay_transparency, Remove_this_citizen, Remove_parked_vehicles, Node_is_level_crossing, Experimental_features, Turn_on_red, Also_apply_to_left/right_turns_between_one-way_streets, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods, Notify_me_if_there_is_an_unexpected_mod_conflict,
Start, Stop, min/max, Segment, Individual_driving_styles, TMPE_TUTORIAL_HEAD_MainMenu,
min/max, TMPE_Title, Imperial, Gameplay, Individual_driving_styles, Simulation, On_roads, Ban_private_cars_and_trucks_on_bus_lanes, default, flow_ratio, wait_ratio, After_min._time_has_elapsed_switch_to_next_step_if, Adaptive_step_switching, Dynamic_lane_section, Percentage_of_vehicles_performing_dynamic_lane_section, Vehicle_restrictions_aggression, Strict, Show_path-find_stats, Remove_this_vehicle, Vehicles_follow_priority_rules_at_junctions_with_timed_traffic_lights, Enable_tutorial_messages, TMPE_TUTORIAL_HEAD_MainMenu, TMPE_TUTORIAL_BODY_MainMenu, TMPE_TUTORIAL_HEAD_JunctionRestrictionsTool, TMPE_TUTORIAL_BODY_JunctionRestrictionsTool, TMPE_TUTORIAL_HEAD_LaneArrowTool, TMPE_TUTORIAL_BODY_LaneArrowTool, TMPE_TUTORIAL_HEAD_LaneConnectorTool, TMPE_TUTORIAL_BODY_LaneConnectorTool, TMPE_TUTORIAL_HEAD_ManualTrafficLightsTool, TMPE_TUTORIAL_BODY_ManualTrafficLightsTool, TMPE_TUTORIAL_HEAD_ParkingRestrictionsTool, TMPE_TUTORIAL_BODY_ParkingRestrictionsTool, TMPE_TUTORIAL_HEAD_PrioritySignsTool, TMPE_TUTORIAL_BODY_PrioritySignsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool, TMPE_TUTORIAL_BODY_SpeedLimitsTool, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool, TMPE_TUTORIAL_HEAD_ToggleTrafficLightsTool, TMPE_TUTORIAL_BODY_ToggleTrafficLightsTool, TMPE_TUTORIAL_HEAD_VehicleRestrictionsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_BODY_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_RemoveJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_RemoveJunction, Public_transport, Prevent_excessive_transfers_at_public_transport_stations, Compact_main_menu, Window_transparency, Overlay_transparency, Remove_this_citizen, Remove_parked_vehicles, Node_is_level_crossing, Experimental_features, Also_apply_to_left/right_turns_between_one-way_streets, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods, Notify_me_if_there_is_an_unexpected_mod_conflict,
TMPE_Title, Individual_driving_styles, TMPE_TUTORIAL_HEAD_MainMenu, TMPE_TUTORIAL_BODY_MainMenu,
Individual_driving_styles,
Individual_driving_styles, Simulation, On_roads, Ban_private_cars_and_trucks_on_bus_lanes, default, flow_ratio, wait_ratio, After_min._time_has_elapsed_switch_to_next_step_if, Adaptive_step_switching, Dynamic_lane_section, Percentage_of_vehicles_performing_dynamic_lane_section, Vehicle_restrictions_aggression, Strict, Show_path-find_stats, Remove_this_vehicle, Vehicles_follow_priority_rules_at_junctions_with_timed_traffic_lights, Enable_tutorial_messages, TMPE_TUTORIAL_HEAD_MainMenu, TMPE_TUTORIAL_BODY_MainMenu, TMPE_TUTORIAL_HEAD_JunctionRestrictionsTool, TMPE_TUTORIAL_BODY_JunctionRestrictionsTool, TMPE_TUTORIAL_HEAD_LaneArrowTool, TMPE_TUTORIAL_BODY_LaneArrowTool, TMPE_TUTORIAL_HEAD_LaneConnectorTool, TMPE_TUTORIAL_BODY_LaneConnectorTool, TMPE_TUTORIAL_HEAD_ManualTrafficLightsTool, TMPE_TUTORIAL_BODY_ManualTrafficLightsTool, TMPE_TUTORIAL_HEAD_ParkingRestrictionsTool, TMPE_TUTORIAL_BODY_ParkingRestrictionsTool, TMPE_TUTORIAL_HEAD_PrioritySignsTool, TMPE_TUTORIAL_BODY_PrioritySignsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool, TMPE_TUTORIAL_BODY_SpeedLimitsTool, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool, TMPE_TUTORIAL_HEAD_ToggleTrafficLightsTool, TMPE_TUTORIAL_BODY_ToggleTrafficLightsTool, TMPE_TUTORIAL_HEAD_VehicleRestrictionsTool, TMPE_TUTORIAL_HEAD_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_BODY_SpeedLimitsTool_Defaults, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddStep, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_Copy, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_AddJunction, TMPE_TUTORIAL_HEAD_TimedTrafficLightsTool_RemoveJunction, TMPE_TUTORIAL_BODY_TimedTrafficLightsTool_RemoveJunction, Public_transport, Prevent_excessive_transfers_at_public_transport_stations, Compact_main_menu, Window_transparency, Overlay_transparency, Remove_this_citizen, Remove_parked_vehicles, Node_is_level_crossing, Experimental_features, Turn_on_red, Also_apply_to_left/right_turns_between_one-way_streets, Scan_for_known_incompatible_mods_on_startup, Ignore_disabled_mods, Traffic_Manager_detected_incompatible_mods, Notify_me_if_there_is_an_unexpected_mod_conflict,
Here's the xml file, and the (hastily bodged together) html file I used to create the <Translations> section:
Now we have an xml file, I'm pretty sure I can make a web page for editing that file = translators won't need to worry about the XML file, they'll just see a form with the keys vs. values.
Great but not 100% accurate 馃槈 Some translations doesn't have to be translated because they are the same meaning e.g. in Polish Start, Stop or Segment
To take that case into account we should differentiate translation keys a little bit (e.g. use capital letters).
Great but not 100% accurate 馃槈 Some translations doesn't have to be translated because they are the same meaning e.g. in Polish Start, Stop or Segment
I already filtered out all translations that were exact match of English. :) I realise that makes the stats I posted earlier somewhat inaccurate.
zh is 99% complete. Missing 1 keys:
Individual_driving_styles,
the missing 1 key of zh:
Individual_driving_styles 涓汉椹鹃┒椋庢牸
@aubergine10
Busy writing web interface for maintaining the xml file, and found a few useful resources while searching for infos:
Specifically, on the "Add language" screen, I'm hoping to provide a list of existing languages so translators don't need to go hunting for the ISO codes. The second link above looks like it will do.
Just some to-do's for the webapp so I don't forget:
<Where> tags in <Translation> tags; briefly describe where a translation is used (e.g. "Mod options screen")<Notes> tags at top of <Localization> with some pointers to the web appoutdated="true" attribute to <Value> tags to indicate which translations need updating due to alterations to the English translation (e.g. we refine an existing value, the other languages need to be updated)multiline="n" attribute to <Translation> tags, if defined, n = number of lines available (e.g. multiline="5") and UI provides multi-line text area for easier editing.What is this format?
What is the tool to edit it?
If the format is custom or there are no good tools, then this "new" format is just as bad as the old one.
I would suggest looking at Transifex, they offer free access for opensource projects and it is a well known tool for translating apps.
So, I just created an account (using GitHub to login) and doing the usual check, "can I delete my account?", fails at first hurdle (yes, even after doing the 'forgot password via sign-in page' thing as described in their FAQ). So Transifex is already smelling of nope to me.
How is this check relevant to translating an open-source project?
If you use GDPR (the right to be forgotten) I am sure they will be able to help you. But this is not relevant to i18n/l10n.
There was one more similar tool for this, crowdin. For example Reddit hosts their translations there.
How is this check relevant to translating an open-source project?
If you don't get why stuff like that is so important, there's no way I could ever explain it to you until it affects you personally.
There was one more similar tool for this, crowdin
Looks better, will give it a try.
If you don't get why stuff like that is so important, there's no way I could ever explain it to you until it affects you personally.
I live in Sweden, all my personal data (not private data) is publicly available online, including home address, employer, phone number, owned vehicles i think income bracket might also be known. In any case GDPR should be protecting me in such cases when I want stuff deleted from some website.
I repeat:
there's no way I could ever explain it to you until it affects you personally.
Implemented in PR #509