feat: per-member island activity counters (foundation for #30) - #35
Merged
Conversation
The counting substrate that a contribution ledger (#7), a season leaderboard (#10) and a relay score (#9) all read from, built once instead of three times. Counters are keyed on (island, member): activity is only credited while the player is actually on the island's team, so recruiting a veteran cannot import old progress, and a member who leaves keeps their contribution credited to the island they made it on. Activity no member can be credited with (level changes, re-locks, minion breaks) is recorded at island scope. Each counter stores a lifetime total plus per-day buckets, so daily, weekly and season windows are all sums over the same data. Buckets older than a configurable retention (default 100 days) are pruned; lifetime totals never are. "Chunks claimed" means distinct chunks: a claimedEver set that survives re-locks tells a first claim from the recovery of re-locked territory, so nothing is counted twice. Writers observe the addon's own events at MONITOR priority; ChunkUnlockEvent now carries the claiming player's UUID. A new member-activity request handler lets other plugins ask e.g. how many chunks a member claimed for their island in the last 7 days. Foundation for #30. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W8GghDu6oXiUf6eCoimJqD
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes #30.
The counting substrate that the contribution ledger (#7), leagues (#10) and cooperative relay (#9) each need, built once. Nothing here is player-facing; it is done when something else can ask "how many chunks did this member claim for this island in the last 7 days" and get an answer — which the new
member-activityrequest handler now answers.Design points from the issue, as implemented
ActivityManager.recorddrops amounts attributed to a player who is not on the island's team, so recruiting a veteran cannot import old progress, and a member who leaves keeps their contribution credited to the island they made it on.IslandActivity(tableChunkBlockActivity) stores a lifetime total plus per-day buckets as flatString -> Longmaps with composite keys (member|COUNTER/member|COUNTER|epochDay) — a shape every database backend serializes without custom adapters. Daily, weekly and season readouts are all sums over the same buckets.chunkblock.activity.daily-retention-days(default 100) prunes old buckets on write; lifetime totals are never pruned.claimedEverset — which deliberately survives re-locks and clears only on island create/reset — distinguishesCHUNKS_CLAIMEDfromCHUNKS_RECLAIMED.Counters
MAGIC_BLOCKS,LEVELS_EARNED(island scope — Level cannot attribute a level change to a member),CHUNKS_CLAIMED,CHUNKS_RECLAIMED,CHUNKS_RELOCKED,RINGS_COMPLETED.Wiring
ActivityListenerobserves the addon's own events at MONITOR priority (MagicBlockEvent,ChunkUnlockEvent,ChunkRelockEvent,RingCompleteEvent— counted even when cancelled, since the completion is a fact) plus island create/reset/delete for lifecycle.ChunkUnlockEventnow carries the claiming player's UUID (additive; the old constructor remains).LevelListener.applyLevel, where the delta is known.Tests
30 new tests:
ActivityManagerTest(attribution, windows, retention, the distinct-claim rule, save throttling),ActivityListenerTest,MemberActivityHandlerTest. Full suite: 700 tests, 0 failures.🤖 Generated with Claude Code
https://claude.ai/code/session_01W8GghDu6oXiUf6eCoimJqD