foundryvtt / foundryvtt

Public issue tracking and documentation for Foundry Virtual Tabletop - software connecting RPG gamers in a shared multiplayer environment with an intuitive interface and powerful API.
https://foundryvtt.com/
202 stars 10 forks source link

Make the GM label a translatable string #8337

Closed kristianserrano closed 4 weeks ago

kristianserrano commented 1 year ago

User Experience

In the Players List and the AV panel, if a user is GM, the label GM is hardcoded and cannot be translated.

Some systems and settings alter the name of the GM to something appropriate such as Keeper, Dean, or Marshal. It'd be nice to be able to change "GM" to a custom label such as these.

kristianserrano commented 1 year ago

I tinkered with this some, and I think I've found a solution that allows the user (or a module) to set a custom GM title.

First, I added this setting. (Obviously, translation strings would be used for name and hint):

// Custom GM Title
game.settings.register("core", "gmTitle", {
    name: "GM Title",
    hint: "Customize the GM's title (e.g., \"DM\" or \"Keeper\")",
    scope: "world",
    config: true,
    default: game.i18n.localize("GM"), // Uses the localized string as the default.
    type: String,
    requiresReload: true
});

In PlayerList.getData(), I made the following modifications:

// Get the custom GM Title value.
const customGmTitle = game.settings.get("core", "gmTitle");
// Get the currently assigned localized string.
const localizedGmTitle = game.i18n.localize("GM");
// If the GM Title is an empty string, use the localized string as a fallback, otherwise use the custom title
const gmTitle = customGmTitle === "" ? localizedGmTitle : customGmTitle;
...
// If the user is a GM, use the gmTitle, otherwise use the character name (or none if there's no character chosen).
u.charname = u.isGM ? gmTitle : user.character?.name.split(" ")[0] || "";

In players.html, I changed lines 18-21 to the following:

{{user.name}}{{#if user.charname}} [{{user.charname}}]{{/if}}

In CameraViews._getDataForUser():

// Get the custom GM Title value.
const customGmTitle = game.settings.get("core", "gmTitle");
// Get the currently assigned localized string.
const localizedGmTitle = game.i18n.localize("GM");
// If the GM Title is an empty string, use the localized string as a fallback, otherwise use the custom title
const gmTitle = customGmTitle === "" ? localizedGmTitle : customGmTitle;

// Return structured User data
return {
    ...
    charname: user.isGM ? gmTitle : charname, // Use the GM Title if the user is a GM.
    ...
};

And finally, for whispers to the GM, in ChatMessage.getWhisperRecipients():

// Get the custom GM Title value converted to uppercase
const gmTitle = game.settings.get("core", "gmTitle").toUpperCase();
// Whisper to groups
// Include the GM Title in the list of possible GM names.
if (["GM", "DM", gmTitle].includes(name.toUpperCase())) {
  return game.users.filter(u => u.isGM);
}
aaclayton commented 1 year ago

Your original suggestion of making sure that "GM" is a localization string that can be "translated" differently is the correct solution to this problem, we just need to prioritize doing it.

kristianserrano commented 1 year ago

Out of curiosity, if/when this gets thrown into a release, will the approach allow the user to set the string via a setting, or will it require a configuration via a module or system?

mclemente commented 5 months ago

I think this issue was already completed sometime on V11.

kristianserrano commented 5 months ago

Yes, but it's not an editable field per se, and it seems the string used for the title in the GM's video window uses a different key (USER.GM vs. GM). I made a module to handle it though. https://github.com/kristianserrano/gamemaster-title-editor

aaclayton commented 4 weeks ago

This was already completed. the GM string is already localizable so a module can easily override the translation for GM, for example:

"GM": "Keeper"
kristianserrano commented 4 weeks ago

Does it also apply to the name in the GM's AV window?

mclemente commented 4 weeks ago

This was already completed. the GM string is already localizable so a module can easily override the translation for GM, for example:

"GM": "Keeper"

Could you add the "GM": "GM" string to Core's en.json? I know it is redundant in English, but it makes localization easier when using localization tools. If I were to do it right now with V12 Testing 3, I'd have to add a "GM" string to the en.json every time en.json were updated.

aaclayton commented 4 weeks ago

Could you add the "GM": "GM" string to Core's en.json? I know it is redundant in English, but it makes localization easier when using localization tools.

That is already the case, and what I meant when saying that the GM string is already localizable.

kristianserrano commented 4 weeks ago

I'm an idiot. I'm already modifying that string with my module. 🤣

It does seem that I have to modify two strings (unless I'm doing it wrong).

game.i18n.translations.USER.GM = title;
game.i18n.translations.GM = title;