Skip to content

feat: add playtime item rewards module - #60

Open
El-Limon wants to merge 9 commits into
mainfrom
feat/playtime-item-rewards
Open

El-Limon wants to merge 9 commits into
mainfrom
feat/playtime-item-rewards

Conversation

@El-Limon

@El-Limon El-Limon commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a configurable playtime-based item reward module that grants items after accumulated playtime, including role-specific reward profiles for Takaro and Discord-synced roles. Server owners can use a fixed interval or set a minimum and maximum so every player receives a persistent random interval for each reward cycle. Successful reward messages can be broadcast, private, both, or disabled.

Closes #59.

Catalog follow-up: gettakaro/community-modules-viewer#261

Architecture

five-minute cron
      |
      v
online player -> accumulated playtime -> default or role profile
                                           |
                                           v
                              persisted per-cycle schedule
                               (selected interval + threshold)
                                           |
                        eligible? ---------+--------- not yet -> stop
                           |
                           v
                    claim -> give item(s) -> configured message delivery
                           |
                           v
                    create next schedule

What Changed

  • Interval configuration: keeps playtimeIntervalMinutes as the minimum and fixed default, and adds optional playtimeIntervalMaximumMinutes for inclusive random ranges such as 120–300 minutes.
  • Persistent schedules: selects the random interval once per player and reward cycle, then stores the selected interval and accumulated-playtime threshold so cron reruns and reconnects cannot reroll it.
  • Role overrides: supports separate minimum/maximum ranges, item pools, selection modes, messages, and delivery choices for the highest-priority matching role.
  • Delivery controls: adds broadcast, private, both, and off; private delivery targets only the rewarded player's game identity.
  • Compatibility and safety: migrates existing consumed-bucket state without duplicate rewards, normalizes a maximum below the minimum to a fixed minimum, and advances a cycle only after successful delivery or a completed no-drop roll.
  • Tests and evidence: adds real Takaro API coverage for persistent ranges and invalid-range normalization, plus a checked-in Paper verification record.

Reviewer Guide

  • Start here: modules/playtime-item-rewards/module.json shows the complete administrator-facing configuration and descriptions.
  • Core behavior: modules/playtime-item-rewards/src/functions/playtime-item-reward-helpers.js resolves profiles, persists schedules, claims cycles, grants items, and sends messages.
  • Pay attention to: a selected random interval is stable until its cycle completes; a failed item grant intentionally leaves the schedule eligible for retry.
  • Compatibility: legacy [profileName, intervalMinutes] state is converted into the new schedule model without reopening consumed rewards.
  • Proof: docs/verification/2026-07-23-playtime-item-rewards-random-intervals.md records the live Paper execution, private recipient, item delivery, stable next schedule, disconnect, and reconnect.

Testing Plan

Automated

  • npm run build
  • npm run typecheck
  • JavaScript syntax checks for both runtime files
  • Focused real Takaro integration suite: 3 passed, 0 failed, 1 intentional Paper-only skip
  • Source-to-export conversion and schema assertions

Live Paper

  • Configure a 1–2 minute range and private reward message.
  • Verify an eligible player receives the item and only that player receives the message.
  • Verify the completed message reports the selected interval.
  • Trigger the cron again and verify the next selected interval and threshold do not change.
  • Disconnect/reconnect the player and verify the same schedule remains persisted.

CI Note

The current GitHub integration job did not reach the test command because the bootstrap could not pull takaro-app-api:latest from ECR (manifest unknown). The separate build/typecheck job passed; the focused real-API suite and mandatory Paper flow passed locally on this exact head.

@El-Limon El-Limon added the enhancement New feature or request label Jul 22, 2026
@koji-assistant

Copy link
Copy Markdown
Contributor

Harambe update from module-request scout:

Discord follow-up source: SVMOTNIK in #module-development, 2026-07-22T16:24:22Z (a9448e8c-75de-4748-844c-d5eadeca6f04) asked whether playtime reward messages can be sent only to the rewarded player instead of the whole server.

Implemented in c0758aee314df7ad4ac61751b8c8f3b1465a6330:

  • Added messageDelivery config for broadcast / private / both / off.
  • Added per-role override support for the same setting.
  • Private delivery uses gameServerControllerSendMessage with opts.recipient.gameId, matching existing PM patterns in the repo.

Verification:

  • npm install --legacy-peer-deps completed in the clean worktree.
  • npm run build passed locally.
  • node --check modules/playtime-item-rewards/src/functions/playtime-item-reward-helpers.js passed.
  • node dist/scripts/module-to-json.js modules/playtime-item-rewards /tmp/playtime-item-rewards-pr60.json plus JSON validation passed.
  • Focused sandbox test command was attempted; it did not complete in cron. First run lacked TAKARO_HOST, second run reached the before hook but timed out without exposing the underlying hook failure before the 300s cron command timeout.
  • GitHub checks on this head: Build and typecheck passed; Integration tests failed. Check annotations only expose generic exit code 1 and Actions job log download returned 403 for the GitHub App token, so I could not confirm whether this is the known shared integration bootstrap class or a module-specific failure from logs.

Not included yet: random/varying reward intervals (b9145019-7d9e-428a-b3b5-c9a3d9cb0fa3) and a total-playtime ranking/leaderboard command (51618bf3-187d-43f6-bdba-6bf9bd00d57c); those look like separate follow-up scope and need a design call before I cram more behavior into this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PlaytimeRewardItem

1 participant