pet.trezy.gameConfig

trezy.pet

{
  "id": "pet.trezy.gameConfig",
  "defs": {
    "main": {
      "key": "literal:self",
      "type": "record",
      "record": {
        "type": "object",
        "required": [
          "stageMoneyCap",
          "activePetCap",
          "starterGrantCap",
          "hungerDecayRate",
          "happinessDecayRate",
          "interactionCooldown",
          "terrariumFoodCap"
        ],
        "properties": {
          "activePetCap": {
            "type": "integer",
            "minimum": 0,
            "description": "How many pets can be on the stage at once. Only active pets earn, so this is the ceiling on income rather than a display limit. Replaces the literal 3 in createPet's active-slot CASE and the MAX_PETS constant deleted in Task 4."
          },
          "stageMoneyCap": {
            "type": "integer",
            "minimum": 0,
            "description": "A SANITY BOUND, NOT A GAME MECHANIC — and it used to be the other way round, which is why this says so. It caps what can accrue between one settle and the next: while it is met, active pets stop producing entirely. It no longer shapes play, because DECAY already does that job better: care quality falls to zero within about a day and a half, so a pet earns roughly one care cycle however long somebody stays away, and a player who never returns is bounded without any ceiling being involved. Set it well clear of what honest play can reach — a full stage of well-kept pets makes a few hundred coins from one session — so that it can only ever fire on a bug in the curve. A cap tight enough to bind in normal play punishes the ONE THING the design asks for, which is that checking in once a day is enough: with money banking itself, the only way a player could dodge a tight cap is to open the game more often. Raising it is safe at any time; lowering it below what a player has already accrued is not."
          },
          "hungerDecayRate": {
            "type": "integer",
            "minimum": 1,
            "description": "Seconds for one feeding to fall from full to nothing — a duration, not a per-second rate, despite the name. THE SAME NUMBER DECIDES WHAT A PET LOOKS LIKE AND WHAT IT EARNED: collectCoins and getWallet price a stretch of care from this curve, while getStats and getLeaderboard draw the bar from it. It lives here because it was a literal in all four of those files and they drifted: a rebalance to a once-a-day return schedule landed on the two that pay and missed the two that display, so the game paid as though a day away was fine and simultaneously showed the pet with nothing left. Readers must FAULT when it is absent or unusable rather than falling back to a default, because a silent default is exactly how that drift became invisible."
          },
          "starterGrantCap": {
            "type": "integer",
            "minimum": 0,
            "description": "The most the server will grant a player for their very first pet. A new player has no income until they have a pet and no pet until they can pay for one, so createPet grants the price of the pet they choose and buys it on their behalf — but only up to this much, or a hand-rolled call would make an epic the free starter. A species dearer than this falls through to the ordinary affordability check and refuses cannot-afford. NOT the lowest tier's price: at 50 the grantable pool would be the two purchasable commons, which is smaller than the three onboarding offers and excludes both slimes. Raising it is safe; lowering it only affects players who have not had their grant yet, because a grant is once per DID and recorded in trezy_pet_grants."
          },
          "terrariumFoodCap": {
            "type": "integer",
            "minimum": 1,
            "description": "How many morsels may lie on a player's ground at once. Basic food is free and unlimited, so without a ceiling a player can carpet three viewports of world; dropFood refuses past this with \"There's plenty down there already.\" ⚠ ITS REAL MEANING IS A TIME HORIZON, AND THAT HORIZON IS DERIVED FROM THE OTHER TWO NUMBERS HERE, NOT INDEPENDENT OF THEM: cap divided by activePetCap is how many morsels each pet gets, and each is worth one interactionCooldown. At 30, an activePetCap of 3 and a cooldown of 1800 that is ten morsels a pet and about five hours of feeding — but doubling activePetCap halves the horizon without this number changing, so the two must be reconsidered together. Readers must FAULT when it is absent or unusable rather than defaulting, for the same reason as the decay rates and the cooldown: a silent default is how a rule the game is paced by changes without anybody deciding to change it."
          },
          "happinessDecayRate": {
            "type": "integer",
            "minimum": 1,
            "description": "Seconds for one petting to fall from full to nothing. Same rules and the same four readers as hungerDecayRate; kept separate because the two halves of care need not fade at the same speed, even where they currently do."
          },
          "interactionCooldown": {
            "type": "integer",
            "minimum": 1,
            "description": "Seconds after feeding or petting before the SAME action is allowed on the SAME pet again. Two scripts need it and they must agree: createInteraction ENFORCES it, and getStats REPORTS how much of it is left so the buttons can show a countdown rather than discovering the rule by being refused. It was a literal `30 * 60` in createInteraction and a second copy as COOLDOWN_MS in the web client, which is the same three-way drift hazard the decay rates had — with a worse failure, because a client that thinks the wait is shorter than the server does invites the player to click a button that then refuses them. Readers must FAULT when it is absent rather than defaulting, for the same reason as the decay rates."
          }
        }
      },
      "description": "The game's tunable numbers — caps, and the curves that decay a pet's care — published in the game's own repo (did:plc:ollch4g7tes2reb5eceiwuol) at rkey `self`. Only records from that DID are ever read — record.index:pet.trezy.gameConfig refuses the rest, and a forged config is worth more to an attacker than a forged tier because it raises every cap at once. These are records rather than constants because an upgrade system is coming: players will unlock higher caps as records in their OWN repo, so every cap resolves as base-from-here plus that player's unlocks, and the upgrade system adds records instead of restructuring readers."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1
}

Validate Record

Validate a record against pet.trezy.gameConfig

Validation Options
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:ollch4g7tes2reb5eceiwuol
CID
bafyreigmjiigndcnszolsyftefayf5tsyq2f2ycko7y2mbw7ywcojivjoi
Indexed At
2026-08-12 02:42 UTC
AT-URI
at://did:plc:ollch4g7tes2reb5eceiwuol/com.atproto.lexicon.schema/pet.trezy.gameConfig

Version History (2 versions)

Lexicon Garden

@