Skip to content

Timing — TTL Calendar

TL;DR: Three wall-clock timers (guest list 1d, ENCRYPT 10d, round-gated USERVOTE). Everything else is either monotonic-forever (WAR _taan, CO2) or single-slot overwrite (RING Moments). Set three cron jobs and the rest takes care of itself.

Why this matters

Every TTL in the game falls into one of four categories, and each category rewards a different habit:

Category Examples Optimal habit
Short wall-clock Guest-list (1d) Refresh early, never late.
Long wall-clock ENCRYPT (10d) Pin important messages; drop the rest.
Round-gated USERVOTE Re-vote every new round; submissions zero out.
Monotonic / per-call WAR _taan, CO2, RING Moments Different mental model entirely — not a timer, a ledger.

If you try to treat a monotonic counter like a timer you'll grind yourself to nothing. If you treat the guest-list as "set and forget" you'll lose cover to silent expirations.

The numbers

Player-visible TTLs

Mechanism Duration Unit Effect at expiry Source
QING guest list (_list[UserToken]) block.timestamp + 1 days wall clock Next Join re-pays CoverCharge. Chat reverts with PayCover if CoverCharge > 0. QING
ENCRYPT entry (_encryptions[i].Expiry) block.timestamp + 10 days wall clock Decrypt wipes the slot; Prune sweeps expired entries. ENCRYPT
USERVOTE validity userVotes[soul].Round == currentRound round counter Vote no longer counts when round advances. Submissions counter resets in behavior (the struct field carries, but its meaning is gated by Round). USERVOTE

That's it. Those three items are the only player-visible expirations.

Monotonic ledgers (not timers, but time-shaped)

Mechanism Ledger type Decrement path? Notes
WAR._taan[Caude][Position] uint256 per (Caude, Position) None. Each new high-score overwrites upward; can never fall. Per-position — rotate coords to farm fresh ones.
WAR.CO2 uint256 global None. Purely additive on every new WAR high-score. See Territory: CO2 Dynamics.
WORLD._creators[Lat][Chi][Cause] uint256 per 3-tuple Zeroed only by Distribute Accumulates on every in-range Code; cashout via Distribute.

Single-slot overwrites (“last write wins”)

Mechanism Storage Cadence
RING.Moments[Soul] mapping uint64→uint256 Overwrites every RING.Eta().
YUE.Hypobar[Phobos], YUE.Epibar[Phobos] accumulators, per your YUE Added to on every React. Monotonic per YUE but cleared on YUE withdrawals/resets as applicable. See Power: Entropy Discipline.

Non-TTLs you might mistake for TTLs

  • Cover charge. There is no "cover cooldown" — the 1-day _list stamp is the cover-refresh timer. Cover is neither time-locked nor round-gated; it's just the same guest-list clock in disguise.
  • QING Entropy() — shifts on activity, not on time. A ghost-town QING's Entropy stays put.
  • PANG Push state — updates only when somebody pushes.

The play

  1. Write three cron jobs. Replace "daily" / "10-daily" / "round-end" with actual scheduled txs:
  2. Every 23 hours: Join at each paid QING you chat at.
  3. Every 9 days: re-encrypt or copy out any ENCRYPT-stored message you want to keep.
  4. On round change: re-submit your vote (old vote is silently invalid).
  5. Don't over-schedule the non-timers. Polling CO2 every minute is waste — its movement is driven by other players' WAR.Faa, not by wall-clock. Subscribe to WAR events instead.
  6. Reserve Codes for monotonic-farm value. A Code updates _creators and Moments — both persist. A Code is never "wasted on a TTL" because there's no expiry to burn — it always lives in the ledger until Distribute.
  7. Respect the strict comparison on _list. _list[UserToken] > block.timestamp — equal fails. Refresh at 23h not 24h; otherwise a block ambiguity can land you on the wrong side.
  8. Bundle TTL refreshes with productive work. A Join doesn't need to stand alone — include it in the same tx as a chat or a vote. See Meta: DSS Bundling.
  9. (inferred) Consider giving up on ENCRYPT stale data. 10 days is a lot of blocks of storage. If you're not decrypting, let it prune. Don't Prune purely out of hygiene — it costs gas; let auto-prune on next decrypt handle it.

Worked example

You are an active player: chat at 3 QINGs, code territory 5x/week, play ACRONYM, and hold 2 ENCRYPT messages.

Your timer calendar for one week:

Day Task Why
Mon 09:00 Join all 3 QINGs (refresh _list) 23h cadence across the week
Tue 08:00 Join all 3 QINGs shift slightly earlier each day
Wed 07:00 Join + vote (round is typically mid-week; adjust) USERVOTE round may advance
Thu 06:00 Join all 3 QINGs continue shift
Fri 05:00 Join + ENCRYPT refresh check if original msgs ≥ 8 days old, copy them
Sat 04:00 Join keep rotating
Sun 03:00 Join + weekly review CO2/Moments audit via read

Note: because your "start" time shifts forward 1h/day, you naturally slide around the clock. If you want a fixed wall-clock cadence (e.g. always 09:00), you have to either set an alarm every 23 hours exactly or drop the refresh earlier (say 22h) — which is harmless; you just pay a couple free-rejoins.

What you do not put on the calendar: CO2, _taan, Moments, _creators. Those update as a side-effect of your productive ops; no separate timer.

Gotchas

  • Strict > on guest-list check. Chat reverts when _list[UserToken] == block.timestamp. Refresh at 23h, not 24h sharp.
  • ENCRYPT Prune is permissionless but costs the caller gas. Don't expect altruism. The system auto-prunes on Decrypt, so by reading an expired message it gets cleaned — but a sender with no readers pays the gas for manual Prune if they care.
  • USERVOTE Submissions is uint8 (max 255 per round, see USERVOTE). Submission 256 in a round reverts. If you're a prolific submitter, pace yourself — or trigger the round advance.
  • Round advance isn't automatic. Somebody has to call the acronym contract's round-advance path. Watch the on-chain round counter, not a wall clock, for USERVOTE validity.
  • (inferred) CO2 and _taan never roll over. Both are uint256. At the rate today's game consumes them, you will never see overflow. Treat them as unbounded.
  • Moments[Soul] is not private. It is a public mapping — anyone can read anyone's current Moment. If that bothers you, be aware of it before you act.

Where it cross-connects