Authoring Reputations
Standing with a faction or one character, kept by the game and named by the library
A reputation is how a faction, or one character, thinks of a player. The number is Hytale's own: the game keeps one per player for each reputation, saves it with the character, and keeps it through death and across worlds. ZiggfreedCommon adds what the game leaves out: a name and a picture, a cap, its own word for each rank, standing for kills, gear that makes every gain bigger while it is worn, rewards past the top rank, the Reputation tab on the shared menu, a bar that moves with standing, and a notice when a rank goes up.
Seasons of Orbis ships the first two, and both are quoted on this page: Old Jack's Favor, standing with one character, and the Hallowed (id Hallows_Eve_Hallowed), a reputation with no characters in it.
Where the files go
One reputation is up to four files under Server/, and only the reputation group is required.
MyFactionPack/
├── manifest.json # "IncludesAssetPack": true
└── Server/
├── NPC/Reputation/Groups/Your_Traders.json # the reputation itself
├── NPC/Groups/Your_Traders.json # the characters whose attitude follows it
├── Entity/Stats/ReputationGain_Your_Traders.json # the stat gear speeds gains on
└── ZiggfreedCommon/Reputations/MyStudio/Your_Traders.jsonA reputation group with no companion file still works: it reads by its id, with no cap and no kills, and the page names it by its id. The game reads reputation groups and ranks once at start, so a change to either needs a restart.
The reputation group
Server/NPC/Reputation/Groups/<Id>.jsonA native Hytale asset. Its filename is the reputation's id everywhere else: the companion file, a reward, a factor and an objective step all name it.
{
"NPCGroups": [ "Hallows_Eve_Old_Jack" ],
"InitialReputationValue": 0
}| Field | Type | Default | Description |
|---|---|---|---|
NPCGroups* | string[] (NPC group ids) | - | The native NPC groups (Server/NPC/Groups/, each listing roles under IncludeRoles) whose characters treat a player by the rank that player holds here. A reputation nobody stands behind writes an empty list. |
InitialReputationValue | int | 0 | Where every player starts. A player who has never touched the reputation reads this value. |
Keep the NPCGroups key, even when it is empty
NPCGroups key, or one naming an NPC group that is not loaded, makes the game throw on every NPC that spawns, in every world. The Hallowed's reputation group writes "NPCGroups": [] for exactly this reason.The rank ladder
Every reputation on a server climbs one ladder of seven ranks, which the library ships in Server/NPC/Reputation/Ranks/. A rank runs from its floor up to the next rank's floor, and its attitude is how the characters in a reputation's NPC groups treat a player who holds it.
| Rank | From | Attitude |
|---|---|---|
Hated | -30,000, the bottom | Hostile |
Unfriendly | -3,000 | Neutral |
Neutral | 0 | Neutral |
Friendly | 1,000 | Friendly |
Honored | 3,000 | Friendly |
Revered | 9,000 | Revered |
Exalted | 21,000, open-ended | Revered |
To retune a rank, ship a file of the same name (MinValue, MaxValue, Attitude) in your own pack. The ladder is server-wide, so a mod that ships ranks of its own changes every reputation, and the game logs a warning at start when two ranks overlap or leave a gap. A rank holds its MinValue and stops short of its MaxValue, so give each rank the next one's floor as its MaxValue. Each reputation can still call a rank by a name of its own: see Ranks below.
The companion file
Server/ZiggfreedCommon/Reputations/<Namespace>/<Id>.jsonReputations/The filename is the id of the reputation group it describes, matched without regard to case; the folders are your own grouping. Every leaf is inherited through Parent. The owner layer is mods/ziggfreedcommon/reputation.json.
| Field | Type | Default | Description |
|---|---|---|---|
Text | {TitleKey, FlavorKey} | the id | What the reputation is called and its description, as keys in your own lang file. |
Icon | string (item id) | none | The item whose picture stands for the reputation on its page row, its bar and its rank notice. |
Order | int | 0 | Where it sorts on the page and among the bars: lower first, then by id. |
Cap | int | the whole ladder | The most standing a player can earn here through rewards and kills. A gain past it is cut to it, after any boost from gear, and a loss is never cut. |
Ranks | {<Rank>: {Name, From}} | the library's words | What this reputation calls each rank, keyed by rank id (Neutral, Friendly, ...), each Name a key in your own lang file. A rank left out reads with the library's own word. An id that is not one of the server's ranks, written with a From, is a rank of this reputation's own above the top one (Exalted): it starts at that much standing, above the top rank's floor, and lasts until the next one's From. Seasons of Orbis's Festival Favor climbs on to Exalted II, III and IV this way. A From on one of the server's own ranks is reported and ignored, since their floors are the same for every reputation. Under Parent the map merges by rank id. |
Kills | [{NPCGroups, Amount, Season}] | none | Standing for each kill of an NPC whose role is in one of the listed NPC groups. A negative Amount costs standing. A row with a Season, a calendar event's id such as Hallows_Eve, counts kills only while that event runs: the rest of the time it counts nothing, as if it were not written, and the reputation's other rows still count. Leave it out for a row that counts all year. Under Parent this list replaces the parent's whole. |
Beyond | {Every, Rewards, Collect} | pays nothing | Rewards for standing earned past the top rank's floor (its own highest rank, when Ranks adds some): each time earned standing crosses another multiple of Every above it, the player earns Rewards once, in the same entries a quest pays. With Collect true (the default) each one waits on the reputation's page until the player presses Collect, which pays up to 20 at a press and leaves the rest waiting; a press whose item rewards would not fit pays nothing and keeps them all waiting (a Lootable or Currency reward is never held back for room); with Collect false it pays on the crossing. Each step is earned once: falling below it and earning it back pays nothing again. An Every of zero or less pays nothing. |
Earn | {Lines} | what the library can see | How a player earns it, in your own words, for the How to earn block on the Reputation page: Lines is a list of keys in your own lang file, one line each, in the order the page lists them ("Take contracts from his board."). Left out, the page says only what the library can see (kills that count right now, so a row out of its Season says nothing), or a plain "their quests and requests raise it" when it sees none. Either way, while the player's gear changes what they earn, a last line says by how much. Under Parent the list replaces the parent's whole. |
Enabled | bool | true | False takes the reputation off this server: its readings answer nothing, so a gate on it stays shut, rewards naming it refuse to pay, and the page leaves it out. The standing players hold is kept. |
{
"Text": {
"TitleKey": "reputation.hallows_eve_old_jack.name",
"FlavorKey": "reputation.hallows_eve_old_jack.flavor"
},
"Icon": "Hallows_Eve_Jack_Helm",
"Order": 10,
"Cap": 21000,
"Ranks": {
"Neutral": { "Name": "reputation.hallows_eve_old_jack.rank.neutral" },
"Friendly": { "Name": "reputation.hallows_eve_old_jack.rank.friendly" },
"Honored": { "Name": "reputation.hallows_eve_old_jack.rank.honored" },
"Revered": { "Name": "reputation.hallows_eve_old_jack.rank.revered" },
"Exalted": { "Name": "reputation.hallows_eve_old_jack.rank.exalted" }
},
"Earn": {
"Lines": [
"reputation.hallows_eve_old_jack.earn.quests",
"reputation.hallows_eve_old_jack.earn.board",
"reputation.hallows_eve_old_jack.earn.talk",
"reputation.hallows_eve_old_jack.earn.gear"
]
}
}Old Jack's favor stops at Exalted's floor, and his ranks read Stranger, Regular, Trusted, Confidant and Jack's Own. His four earn lines read "Do his errands and his daily jobs.", "Take contracts from his board.", "Stop by for a word once a day." and "Wear a Jack Helm, and everything you do for him earns more favor while you have it on." The Hallowed has no cap. It counts kills of the season's creatures and pays a loot table every 5,000 past Exalted:
{
"Text": {
"TitleKey": "reputation.hallows_eve_hallowed.name",
"FlavorKey": "reputation.hallows_eve_hallowed.flavor"
},
"Icon": "Hallows_Eve_Hollow_Lantern",
"Order": 20,
"Kills": [
{ "NPCGroups": [ "Hallows_Eve_Event_Mobs" ], "Amount": 2 }
],
"Beyond": {
"Every": 5000,
"Rewards": [ { "Kind": "Lootable", "Params": { "Lootable": "Hallows_Eve_Hallowed_Cache" } } ]
},
"Earn": {
"Lines": [
"reputation.hallows_eve_hallowed.earn.kills",
"reputation.hallows_eve_hallowed.earn.jack",
"reputation.hallows_eve_hallowed.earn.treats",
"reputation.hallows_eve_hallowed.earn.gear"
]
}
}Gear that speeds gains
Gear never adds standing. It makes each gain bigger, by a percent, through two stats: the library's ReputationGain, which counts for every reputation, and ReputationGain_<Id>, which counts for one. The library ships the first. For gear that favors one reputation, ship the second yourself, with <Id> spelled as the reputation group's file name, a base Max of 0 and a Min of -100. The companion file needs no leaf for it: the library finds the stat by its name.
{
"InitialValue": 0.0,
"Min": -100.0,
"Max": 0.0,
"Shared": false,
"HideFromTooltip": false
}Give each item a modifier on the stat's Max, in whole percent points: 10 is +10%. The game applies and clears it as the item goes on and off. Armor names the stat in Armor.StatModifiers, a shield in Utility.StatModifiers, and a gear set's tier in its own.
"StatModifiers": {
"ReputationGain_Hallows_Eve_Old_Jack": [ { "Amount": 10, "CalculationType": "Additive", "Target": "Max" } ]
}The library adds the two stats together and multiplies every gain by that much, rounded, never to less than 1: with the Jack Helm on, a 250 reward pays 275. A kill, a quest, a contract, a daily line and a reward collected from a boss's chest or a dungeon's clear all count, and so does standing past the top rank. A loss is never changed, and the Cap cuts the gain after the boost. The total counts from -100% to +1,000%. The item's tooltip line reads the client.lang key itemTooltip.stats.<Stat> ("Old Jack's Favor Gain: 10%"), and the reputation's page ends How to earn on "Your gear raises what you earn here by 10%." while it is worn.
Standing is what was earned
Beyond payouts read the standing the player has earned. Putting gear on never opens a lock or reaches a rank by itself, and taking it off never lowers standing.Earning standing
- Rewards. The
Reputationreward kind moves standing by a wholeAmount, negative to cost standing, anywhere a reward pays: a quest, a contract, a shop offer, an achievement, a loot table, a conversation line'sGrant. In a reward list it reads "+250 Old Jack's Favor". See Rewards. - Kills, through the companion's
Killstable. The standing lands a moment after the kill. A row with aSeasoncounts only while that calendar event runs, the sameSeasonleaf shops, boards, quests and dungeons use, so a reputation can pay a little more during an event and go back to its usual rows when the event ends. - A word each day. A
Startbeat with a dailyOncecan pay a little standing the first time each day a player stops to talk: see Beats that pay.
{ "Kind": "Reputation", "Params": { "Reputation": "Hallows_Eve_Old_Jack", "Amount": 250 } }"Kills": [
{ "NPCGroups": [ "Your_Bandits" ], "Amount": 5 },
{ "NPCGroups": [ "Your_Night_Creatures" ], "Amount": 1, "Season": "Your_Event" }
]Reading standing
Two readings join the shared factor vocabulary, so a Requires block, a conversation condition or a loot roll can ask about any reputation:
| Factor | Param | Reads |
|---|---|---|
ziggfreedcommon:reputation | <Id> | The standing the player has earned |
ziggfreedcommon:reputation_rank | <Id>/<Rank> | 1 at or above that rank's floor, 0 below it |
Each one fails closed: a reputation the server lacks or has switched off, a rank not on the ladder, or no live player answers nothing, and the gate stays shut. A player who has never touched a reputation reads its starting value. Write a Min on every condition. The worked spellings are on Shared Schemas.
"Requires": {
"Factors": [
{ "Factor": "ziggfreedcommon:reputation_rank", "Param": "Hallows_Eve_Old_Jack/Honored", "Min": 1 }
]
}How a lock reads
A lock on a rank names the rank and the reputation by itself: the rank's name (its Ranks name, else the library's word) with the reputation's own name, so a gate on Town_Guard/Honored reads "Requires Honored with Town Guard". A board slot, a contract and a shop offer all read it this way. A shop offer that asks for several things lists each on a line of its own, and one with more than one way in reads "Unlocked by:" with each way; hovering the offer, or pressing Buy, says the same. The generic line ("a rank with a reputation") reads only when the reputation names itself nowhere or the rank is not on its ladder.
To word a lock your own way, such as "Requires Trusted with Old Jack" in place of "Trusted with Old Jack's Favor", ship a naming overlay with a ParamNames.Keys entry for each exact Param you gate on, each pointing at a full lang key. An overlay entry is asked first and wins:
{
"Factor": "ziggfreedcommon:reputation_rank",
"ParamNames": {
"Keys": {
"Hallows_Eve_Old_Jack/Friendly": "hallowseve.progression.factor.hallows_eve_old_jack.friendly",
"Hallows_Eve_Old_Jack/Honored": "hallowseve.progression.factor.hallows_eve_old_jack.honored"
}
}
}Those two keys read "Regular with Old Jack" and "Trusted with Old Jack". A gate on a rank the overlay does not list reads the library's own line, the rank's name with the reputation's.
A step on a rank
The REPUTATION_RANK objective kind counts holding a rank: Target is the rank id and Qualifier the reputation id (leave it out to count any reputation). Every rank from the reputation's starting rank up to the one held is credited, at login and after every reward or kill, so a jump never misses a rank. Below the starting rank, only the ranks reached going down are credited. A quest step and an achievement's criterion both take it. Jack's Confidant in Seasons of Orbis is an achievement whose one criterion is reaching Revered with Old Jack:
"Criteria": {
"reach-confidant": {
"Kind": "REPUTATION_RANK",
"Target": "Revered",
"MatchMode": "EXACT",
"Qualifier": "Hallows_Eve_Old_Jack",
"Amount": 1,
"TextKey": "objective.hallows_eve.jack_confidant"
}
}Write MatchMode EXACT
CONTAINS by default, and Friendly is inside Unfriendly. EXACT counts the rank you named and nothing else.What a player sees
- The Reputation tab on the shared menu, once they have any standing with a reputation. A line at the top says what reputation is for, then one row per reputation they have met ("Who knows you"): its rank, and how far it is to the next rank or, past the top, to the next reward when the reputation pays one.
- The page of the one they pick: their rank and a bar toward the next one, the description whole, then How to earn (your
Earnlines, and a last line with how much their gear raises or lowers each gain, while it does), Ranks (every rank from the starting one to the top, plus the one they hold if it is below the start, each with the standing it takes, what it opens and the achievement it earns with what that pays), Past the top rank whenBeyondpays, with what is waiting and the Collect button, and Your standing (what they have earned and the most they can earn). - What a rank opens is read from the content itself, with nothing to author: every shop offer and every board slot whose
Requiresasks for that rank, by its name and where it is ("Burning Jack Helm at Old Jack's Stall", "An extra Night Work contract at Old Jack's Board"). It lists them all year, so a seasonal stall that is packed away still shows what each rank holds. - A bar on the World bars panel each time a reward or a kill out in the world moves their standing, beside the skill XP bars. It reads the reputation's name and picture alone with the gain, and fills through the rank held; the rank shows on the Reputation tab and in the rank-up notice.
- Standing earned inside a menu (collecting a reward, buying something, taking a quest that pays out at once or picking a line in a conversation) is listed in the notice that pops up in that menu, with the rest of what they got, such as "+250 Town Guard". When a reputation's
Capheld part of it back, the notice shows the part they got. It does not play again as a bar once the menu closes, so the Settings tab has no "Reputation changes in menus" switch any more. - A notice when a rank goes up during play: the
Reputation_Rankfeedback moment, which a pack or a server owner replaces by shipping a file of the same name. A fall raises no notice, and logging in raises none.
A conversation line or a placement opens the page through the Reputation destination: "Open": "Reputation" opens on the first reputation the player has met, and { "Type": "Reputation", "Reputation": "<Id>" } on that one. Old Jack's "How do we stand?" uses the second form.
Switching off and retuning
mods/ziggfreedcommon/reputation.json$Enabled is the switch over every reputation. Every other top-level key is a reputation id, merged leaf by leaf over what the packs ship.
{ "$Enabled": false } // every reputation off
{ "Hallows_Eve_Old_Jack": { "Cap": 9000 } } // retune one, leaf by leaf
{ "Hallows_Eve_Hallowed": { "Enabled": false } } // switch one offA reputation switched off is gone from the server: its readings answer nothing, rewards naming it refuse to pay, and the page leaves it out. Nobody's standing is touched, so switching it back on picks up where every player left off. Hytale's own /reputation command sets a player's standing directly: every reading sees the new number, but the Cap does not apply and no bar, notice or Beyond reward follows.
Checking your work
The library audits every reputation at boot and logs its errors once, so a server without MMO Skill Tree still hears them. The whole audit, warnings included, runs at boot on a server started with the environment variable ZIGGFREEDCOMMON_AUDIT_ON_BOOT=1, under [reputation] audit beside the library's other passes, and each error is still printed once. On an MMO Skill Tree server, /mmoconfig validate lists the findings under reputation with the rest of the content audit.
| Finding | Severity | Means |
|---|---|---|
TOO_FEW_RANKS | error | Fewer than two ranks are loaded, so the game cannot bound standing. Something replaced or removed the library's ladder. |
GROUP_WITHOUT_NPC_GROUPS | error | A reputation group has no NPCGroups key. Write "NPCGroups": []. |
KILL_WITHOUT_GROUPS | error | A Kills row lists no NPC groups, so it never counts a kill. |
FROM_ON_SHARED_RANK | error | A From sits on one of the server's own ranks, whose floors are the same for every reputation. It is ignored; a rank above the top needs an id of the reputation's own. |
TIER_OUT_OF_RANGE | error | A rank of the reputation's own has a From that is not above the top rank's floor and below its ceiling, so it is left off this reputation's ladder. |
TIER_SHARES_FLOOR | error | Two of the reputation's own ranks have the same From, so one could never be reached and is left off. |
TIER_SHARES_ID | error | A rank of its own is written twice in two cases. Ids match without regard to case, so only the first by floor stands. |
NO_NATIVE_GROUP | warning | A companion file matches no reputation group, so nothing reads it. |
UNKNOWN_NPC_GROUP | warning | A reputation group names an NPC group that is not loaded, and the game throws on every NPC added while it is missing. |
UNKNOWN_KILL_GROUP | warning | A Kills row names an NPC group that is not loaded, so that group counts nothing. |
UNKNOWN_ICON | warning | Icon is no loaded item, so the picture is missing. |
UNKNOWN_RANK | warning | Ranks names a rank that is not on the ladder, so that name never shows. |
CAP_BELOW_LADDER | warning | Cap sits below the ladder's bottom, so every gain is cut to nothing. |
TIER_ABOVE_CAP | warning | Cap sits below the floor of one of the reputation's own ranks, so rewards and kills never reach it. |
TIER_WITHOUT_NAME | warning | A rank of the reputation's own has a From but no Name, so players read its id where its name belongs. |
UNKNOWN_SEASON | warning | A Kills row's Season names no calendar event on this server, so that row never counts. Add the event's calendar file, or correct the id. |
The library's own words live in ziggfreedcommon.reputation.lang: the seven rank names, the generic factor names, the page, the bar and the notice. A reputation's name, description and rank names are keys in your own lang file.
See also
- Shared Schemas - the
Reputationreward kind, the factor spellings and naming overlays. - Beats that pay - a daily line that pays standing.
- A slot's own gate - a board posting that opens with standing.
- ZiggfreedCommon - what the library owns, and its owner files.