Project: Gorgon 3rd-Party Tools Data

Welcome!

You've found the CDN repository for Project: Gorgon's client data! This data is made available for third-party reference websites and apps. In general, you can use the contents of these data files in whatever tools you want to create, with the following caveats:

Click here to jump to translation documentation.

Available JSON Files:

File-Specific Notes

This document (and the game!) are a work in progress. You will need to look at each file to get an idea of how it works. Most of the files reference content from other files when needed. Here's some file-specific tips that may not be obvious from looking at them:

abilities.json

Each ability in this file has an ID number which is encoded into the key for the ability. (Ability_1 has the ID of 1, etc.) The "PvE" section of each ability describes how the ability is used in player-versus-monster combat. Abilities can also have a "PvP" section, which will list specific fields that are different from the PvE version. The PvP block lists only the "differences": fields not listed in the PvP section are assumed to be the same as the ones in the PvE section.

Also, note that some abilities are only used by monsters. These abilities have the "Lint_MonsterAbility" keyword.

abilitykeywords.json

Lists commonly-occurring ability keywords, and Attributes that apply to all abilities that have that keyword. These attributes are combined with the attributes that are explicitly listed in abilities.json for that ability.

advancementtables.json

These are mostly internal lists of attribute power-ups. There's not too much that's useful to tools here, but one important use is when looking at skills.json. Each skill can reference an advancement table, and if it does, the player gets the benefits of that advancement table as they level up in the skill.

ai.json

This is configuration info for monster/pet AIs. There isn't much here that's useful to tools, but one bit of info you can glean from it is whether an ability is for monsters/pets or for players. If an ability name is referenced by an AI entry, it's for monsters or pets. Otherwise it's for players.

directedgoals.json

This describes all the entries in the "stuff to do" pane of the Quest window. The file contains both the categories of entries AND the actual entries for each category, lumped together for your inconvenience. If an entry has IsCategoryGate set to true, then it's used as a category header; actual entries will have a CategoryGateId that maps to one of the categories.

effects.json

This file contains client data for every buff, debuff, or other weird special effect that can happen to a player, IF the effect is visible in the client: an icon in the "effects" pane, a particle, a tooltip entry, etc. Some effects have no status indicator in the client, so they are not included here.

Each effect has an ID which is encoded into the key for the entry. The "DisplayMode" field indicates how it's used:

The "Desc" field is normally shown to the player directly, but there is a special case to be aware of: if "DisplayMode" is "AbilityModifier", the Desc field can optionally take the format "DamageType:<Type>" where <Type> is replaced with a damage type such as Cold or Fire. The client interprets this to mean that the Effect changes affected abilities' damage type to the specified type. If the string continues with a semicolon, the rest of the string after the semicolon is displayed to the user as normal. Examples: "DamageType:Cold", "DamageType:Darkness;Deals up to 50 extra random damage"

items.json

The items have IDs, which are encoded into the key for each item object. (Item_1 has the ID of 1, etc.) The "EffectDescs" array describes the item's effects when equipped. These can be in plain-English or attribute-description formats -- see the comments on tsysclientinfo.json below for more info.

items_raw.json

This is the "raw" version of items.json with embedded variables. See Variable Replacement for more info. The following fields can have <<<TripleStab>>> variables in them:

This file, items_raw.json, is what the game uses for its item data. items.json is auto-generated for your convenience, replacing all the embedded variables with their English language strings. In most cases you can just reference items.json and ignore this file.

We included this file to give volunteer translators as much context as possible about where a string is referenced. It could also have interesting tool uses.

itemuses.json

This info is used by the game to create the "More Info" window for items. Note that the information in this file is 100% redundant right now: the client could figure out which recipes involve the item just by examining all recipes. So the file may go away at some point -- but more info may get added to it, making it important. We'll have to see how things go.

lorebookinfo.json

Currently, this just contains the categories that lore books can be in.

lorebooks.json

This contains information about each lore book that can be found in-game. The text of some lore books is not included here (or in the game client). For books that we want to keep "secret", the book entry will have "IsClientLocal" set to false. In those cases, the server sends the client the book text when the player actually obtains the book.

Secrets don't last in an MMO because information spreads. So this just prevents books from being "scraped" moments after a game update. We will periodically "de-secretize" lore books when we feel they no longer need to be hidden.

npcs.json

Each entry in this file describes an NPC in the game. The key value is the internal name of the NPC, and this is what is used elsewhere to refer to the NPC (such as in storagevaults.json). You can use npcs.json to find the "friendly name" of these NPCs.

The file also contains information about what each NPC likes and dislikes. The "Pref" field gives a general idea of how much they like/dislike it (with negative numbers indicating dislike), but this information is not sufficient to exactly calculate favor earned from a gift.

playertitles.json

Describes all the titles a player can earn.

quests.json

Describes each quest. Note that as of this writing, much of the information in this file is server info not used by the client, and will be removed from this file eventually. Fields such as "Requirements" and "InteractionFlags" are not used by the client.

recipes.json

Each recipe has an Ingredients array, and each ingredient can have either an "ItemCode" or an "ItemKeys" field. The "ItemCode" field is the type ID of an item from items.json. The name of this field will change to "ItemTypeID" in a future version of this data.

Alternatively, some recipes don't have fixed ingredients; they let the user drag and drop in items. In that case, they have an "ItemKeys" field. This is an array of item keywords which the dropped-in item must have.

New addition: some recipes have a ProtoResultItems array which is exactly like the ResultItems array, except that these "proto-items" are enchanted before being given to the player. (So the proto-items are the unenchanted base items.) Recipes can have ProtoResultItems, ResultItems, both, or neither.

storagevaults.json

Describes each 'storage vault' in the game, where players can store items.

skills.json

Describes each skill. (Note that not all skills are accessible in-game yet.)

One thing to watch for is the Rewards array. The keys in the array are usually levels, such as "7"; players get that reward when they reach level 7. But sometimes entries in the array also indicate races, such as "7_Dwarf_Elf". In that case, only dwarves and elves would get this reward when they reach level 7; other races would not.

Also note that skills can reference an Advancement Table, which will provide additional level-up rewards (such as more Max Health). If a skill is a combat skill, the skill's Advancement Table is only applied when the player is using that skill. If the skill is non-combat, the advancement table is always applied.

sources_abilities.json and sources_recipes.json

These have entries for the ability/recipe IDs described in abilities.json/recipes.json, and describe how each ability or recipe can be obtained by players. (This data is not actually used in the game client as of this writing, but will be used in the future to assist players in finding stuff.)

strings_all.json

Contains all the named localizable strings, with their English-language values. These same strings can be found in the Translations folder broken up into multiple files. This file combines all those strings into one for tool convenience.

The game doesn't actually read this file; it's synthesized for your convenience. The intended use is to provide replacement values for embedded in strings in items_raw.json and other "raw" JSON files.

tsysclientinfo.json

"TSys" stands for "Treasure System". This is the internal name for the random-loot-generation system. Each entry is a possible treasure effect that can be found on loot (or via crafting). Each treasure effect has one or more tiers of potency, described in the "Tiers" array for the entry.

The "SkillLevelPrereq" indicates the minimum skill-level needed to wield equipment with that tier of power. (If the Skill for the power is "Unknown" or "AnySkill", there is not actually any level requirement; the value is still provided because it often (90% of the time) corresponds to the intended power-level of the tier, so it may be useful to tools.)

The "EffectDescs" sections describe what each tier does. These are strings in two possible formats: plain English and attribute-describing:

tsysprofiles.json

("TSys" stands for "Treasure System".) A "tsys profile" is just a list of treasure effects, as found in tsysclientinfo.json. When an item in items.json has a "TSysProfile" field, that item will be randomly generated with effects contained in that profile.

Each profile in this file lists its eligible effects; those effect names correspond to the "InternalName" fields in tsysclientinfo.json.

xptables.json

Each skill can reference an XP table from this file. The XP table indicates how much XP needs to be earned to level-up a skill. For some reason the keys are named "Level_1" etc. when a more intuitive name would have been "XPTable_1" or something like that. So just imagine that's how they're named.

Variable Replacement

Note: this system helps us localize strings that originate from spreadsheets and scripts. It's pretty niche. If you don't care about localization you can ignore this section, along with the file that uses it (items_raw.json).

To facilitate localization, we've added a way to embed variables in JSON string fields. These embeds can thenselves have simple numeric variables. Examples are probably the fastest explanation. This is a snippet from items_raw.json:


        "DynamicCraftingSummary": "<<<Food_CheapMeatCraftingSummary>>>",
        
Text contained in <<<TripleStabs>>> is a variable that needs replacing. You can find the replacements in the file strings_all.json, where it's defined as:

        "Food_CheapMeatCraftingSummary": "This can be used in Cooking recipes that call for 'Cheap Meat.' In those recipes, all Cheap Meat behaves the same way, so use whatever you have handy.",
        
So all we need do is replace <<<Food_CheapMeatCraftingSummary>>> with that string. Easy! But the real point of this system is that the replacement itself can contain variables. Here's another snippet from strings_all.json:

        "Food_RestorePower" : "Restores {0} Power",
        
The {0} in the string is a variable, and it needs to be replaced with a value. The replacement values are specified sort of like a function call:

        "<<<Food_RestorePower(0=28)>>>"
        
The parameters are declared within parentheses (). Each variable is a number starting at 0, then an equals sign =, then the value for that variable, which is always a number (a decimal number, possibly negative). If there's more than one variable to replace, they are separated by a semicolon:

        "<<<SomeMadeUpString(0=200;1=-13.4)>>>"
        

As of this writing, no variable takes more than one parameter, and that parameter is always named 0. But we'll eventually have need of a 1 variable, and if we get crazy with it, maybe even 2.

Lint Keywords

Most types of things (items, recipes, quests, etc.) have a Keywords array. Keywords that start with "Lint_" are used by our data validation process. For instance, if an item has the "Lint_NotObtainable" keyword, that means the item cannot be obtained via any regular in-game process such as quest rewards or loot. (These items can still be created manually by admins, so they might be used as rewards in live events. The items may also have been accessible in the past, so players might still have them, but they're retired now. Or the items may just be new stuff that's not quite ready to be in the game yet.)

"Lint" is the name of an old programming tool that detects problems by analyzing source files. We have a similar tool that analyzes the game's data. It would normally complain about an item that can't be obtained, but if it sees that the item has the Lint_NotObtainable keyword, it knows it's on purpose. "Lint_" keywords are used to tell the tool that something is behaving weirdly, but on purpose.

The client doesn't actually use these Lint keywords, but they are included here because they're probably useful for 3rd-party tools.

Versioning Info

Each version of the game's data has a number or name. This is stored at http://client.projectgorgon.com/fileversion.txt. (Note that's client.projectgorgon.com, NOT cdn.projectgorgon.com!) The contents of this file will be an integer or a word -- that is, a consecutive sequence of ascii letters and numbers. (If there is whitespace at the end of the file, remove it.) The data for that version is found at http://cdn.projectgorgon.com/v{fileversion}/data and the icons for that version are at http://cdn.projectgorgon.com/v{fileversion}/icons. The icon filenames are based on the icons' IDs. They are "icon_###.png", where ### is the icon ID number, as referenced in a JSON file.

Localization

The game's text is also stored as JSON and is provided here to serve as a basis for player-written translations.

(IMPORTANT NOTE: only part of the game is localizable at this time. Making the game fully translatable is a work in progress with many more steps to go.)

How to Start Translating

The game has a way to let volunteer players create translations of the game. Right now, there isn't a formal repository of these translations (but there will be eventually). So for other people to use your translation, you need to give them your translation manually and they have to store it on their hard drive at a certain place.

The rest of these instructions are for volunteer translators.

The easiest way to start is by downloading this zip. It contains the English version of all the localizable strings. Extract the zip to Project Gorgon's app data folder. In Windows, the easiest way to find this is to paste this into Windows Explorer -- it should open the correct folder:

%localappdata%low\Elder Game\Project Gorgon

Extract all the files in that zip into a new sub-folder here. Name the sub-folder "Translation".

Before starting the game, go ahead and change one of the strings so you can tell if it's working. Open strings_skills.json in a text editor and change the value for "skill_Unarmed_Name" from "Unarmed" to something else. (I picked Unarmed because all players have this skill from character-creation. But you can change any string you want.)

Now when you start the game, it will detect your translation. You should see a big message on startup asking if you want to use the "Language Pack". If you click Yes and log into the game, you should be able to open the Skill window and see that the Unarmed skill has been renamed.

While the game is running you can use the chat-command /reloadstrings to reload all the JSON files from the folder. This lets you edit the various strings_whatever.json files, and test without having to restart the game. If you have a GUI window open when you use this command, you may need to change the selection before the new strings are displayed. For instance, if viewing a quest, click on a different quest and then back to the original.

What's Going On Under the Hood

When the game starts it checks to see if there is a folder named "Translation" in the game's app-data folder. If there's a Translation folder here and it contains at least a file named version.json, we assume there's a translation available.

The game then prompts the user to see if they actually want to use this translation.

Note: Advanced users can change where the game looks for the translation directory is by adding command-line parameters to the game in the Steam initialization. If you add -translationdir C:\MyTranslation to the parameters, it will look in the C:\MyTranslation folder for version.json and other files.

The game next looks in that folder for a file named checksums.json. This file is included in the zip, and you don't need to change it for anything. This file acts as a sort of versioning system. The checksums in this file are for the English-language strings that you translated. If the game notices that the English-language string has changed since it was translated, that string gets turned back into English. (Edit: this feature is not yet implemented; it runs too slowly on game startup right now.)

This feature is optional. The goal is to make sure outdated translations don't keep getting used when they're out of date. (The idea is that someone will update the translation and replace checksums.json with the latest version.) If you don't want to provide this feature to your users, just delete checksums.json.

Next the game searches that directory for any file that starts with "strings_" and ends with ".json" (or ".jsonc", see below). It loads all the strings from these files and applies them to the game data. Any strings that aren't found in the directory remain English strings.

Note: we generally recommend you use the same setup of JSON files that are provided in the English version here. That will probably make it easier to manage changes in the future. But if you need to break up the strings into more files while developing, you can create any file named string_whatever.json. The only caveat is that no two files can contain the same string ID. If that happens, one is chosen at random! (If you are worried about this use the /reloadstrings command in-game. It will print an error if the same string is found more than once.)

JSON with Comments

The format used by these files is JSON, which is a simple text format that you can learn very quickly with a google search. If you're a coder by nature you may end up wanting to create custom tools that use these JSON files, and that's great. But if you're edit the files directly via a text editor like VS Code, it may be useful to have comments. Comments are notes left to yourself or other readers which aren't processed by the game. The JSON format doesn't have built in support for comments, but it's a common extension to the format. The game understands single-line comments that start with double slashes, like this:

// from here until the end of the line is a comment -- the game will ignore it, so you can use it to leave yourself notes
    
Or you can have multi-line comments by starting and ending with /* and */:
/* everything from here is a comment


even on multiple lines

until we see this marker: */
    

There is one annoying problem here, which is that text-editors which enforce the JSON format will mark these comments as errors. But if you rename the file's extension from .json to .jsonc editors like VS Code will recognize this as "JSON with Comments" and parse it correctly. The game checks for files with both the .json and .jsonc extension.

The version.json File

Before giving your translation to others, edit this file to name your translation and add any notes you want them to see. This is shown to the user when they pick your translation, and again each time the game starts.

Updating Your Translation

Each version of the game has a separate set of strings. If you have partially-translated strings from the previous version, here is a script that will update your strings. It will add new strings to the bottom of each JSON file, and mark each changed string with a marker that you can search for in your text editor. Istructions:

1. BACK UP YOUR STRINGS:

2. Download script: https://cdn.projectgorgon.com/v466/data/UpdateTranslationFiles.ps1

3. Run script. You may need to right-click and do whatever stupid voodoo Windows requires to let you run the script. It can take several minutes to run.

4. Update your translations. Now, each JSON file has new English strings added to the bottom of the file. Search each file for $CHECKME$. This is added to any string who's English version has changed. The English version is added to the string, then your translated string is at the end. (Or the old English string if you haven't translated it yet.) Make sure the translation matches the English. Then remove all the $CHECKME$ and the English translation text.

Other Localization Tips