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 (RINGMoments). 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
_liststamp 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
Pushstate — updates only when somebody pushes.
The play¶
- Write three cron jobs. Replace "daily" / "10-daily" / "round-end" with actual scheduled txs:
- Every 23 hours:
Joinat each paid QING you chat at. - Every 9 days: re-encrypt or copy out any ENCRYPT-stored message you want to keep.
- On round change: re-submit your vote (old vote is silently invalid).
- Don't over-schedule the non-timers. Polling
CO2every minute is waste — its movement is driven by other players' WAR.Faa, not by wall-clock. Subscribe to WAR events instead. - Reserve Codes for monotonic-farm value. A Code updates
_creatorsandMoments— 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. - 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. - Bundle TTL refreshes with productive work. A
Joindoesn't need to stand alone — include it in the same tx as a chat or a vote. See Meta: DSS Bundling. - (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
Prunepurely 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.Chatreverts 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 manualPruneif they care. - USERVOTE
Submissionsisuint8(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
_taannever roll over. Both areuint256. At the rate today's game consumes them, you will never see overflow. Treat them as unbounded. Moments[Soul]is not private. It is apublic mapping— anyone can read anyone's current Moment. If that bothers you, be aware of it before you act.
Where it cross-connects¶
- Venues: Guest-List Rotation — the 1-day timer in play.
- Timing: Pole & Ring — why
Momentsis overwrite-not-TTL. - Timing: First-Mover Tradeoffs — monotonic ledgers (
_taan,CO2) structurally favor whoever writes first. - Meta: Word Games Tactics — USERVOTE round mechanics.
- Meta: DSS Bundling — stapling a TTL refresh onto a productive tx.
- Cheat Sheet: Timing — dense reference of every timer.