Skip to content

PlayRewards feature #15

@remdui

Description

@remdui

Titel
PlayRewards – beloningen op speeltijd, drempels, login-streaks en permissie-tiers

Is your feature request related to a problem? Please describe.
We willen een generieke reward-laag die automatisch beloningen uitdeelt op basis van speeltijd (periodiek en op vaste drempels), login-streaks en vergelijkbare triggers. Spelers met bepaalde permissies moeten in aanmerking komen voor verschillende tiers en beloningsgradaties. Nu ontbreekt centrale logica, progress-tracking en anti-dubbeluitgifte.

Describe the solution you'd like
Een modulaire PlayRewards-plugin met:

  • Triggers

    • Speeltijd (periodiek): bijv. elke 60 min online → reward (met per-speler cooldown/progress).
    • Speeltijd (drempels): bij 100h, 200h, … éénmalige rewards.
    • Login-streaks: X dagen achter elkaar inloggen (daggrens configureerbaar).
    • Dag/week-activiteit (optioneel): bijv. 5 uur in een week, of daily login bonus.
  • Permissie-tiers

    • Eligibility via permissies, bijv. playrewards.tier.bronze|silver|gold. Hoger tier ⇒ rijkere beloning bij dezelfde trigger.
  • AFK-integratie

    • Speeltijd telt niet door tijdens AFK (koppeling met onze AFK-module/DataRegistry).
  • Uitgifte-model

    • Directe uitgifte of claimbaar via /rewards GUI (met backfill als speler offline was).
  • Anti-abuse & idempotentie

    • Deduplicatie per trigger; throttle; geen meervoudige toekenning bij reconnects.
  • Commands & permissies

    • Speler: /rewards (GUI/overzicht), /rewards claim, /rewards progress, /rewards streak.
    • Staff: /rewards admin grant <player> <rewardId>, recalc <player>, reload.
    • Permissies: playrewards.use, playrewards.tier.*, playrewards.admin.

Additional context

  • Config (schets)

    playrewards:
      timezone: "Europe/Amsterdam"
      day_reset_hour: 0              # daggrens voor streaks
      count_afk_time: false          # AFK uitgesloten
      delivery: "claim"              # "auto" of "claim"
      triggers:
        - id: "playtime_hourly"
          type: "playtime_recurring"
          every_minutes: 60
          tiers:
            bronze:
              permission: "playrewards.tier.bronze"
              reward: [ "crate give {player} vote 1" ]
            silver:
              permission: "playrewards.tier.silver"
              reward: [ "crate give {player} vote 1", "eco give {player} 500" ]
            gold:
              permission: "playrewards.tier.gold"
              reward: [ "crate give {player} epic 1", "eco give {player} 1000" ]
        - id: "playtime_thresholds"
          type: "playtime_threshold"
          thresholds_hours: [100, 200, 400]
          reward:
            default: [ "title {player} subtitle &a100 uur bereikt!", "lp user {player} permission set cosmetics.trail.sparkles true" ]
        - id: "login_streaks"
          type: "login_streak"
          thresholds_days:
            "3":   [ "key give {player} daily 1" ]
            "7":   [ "crate give {player} rare 1" ]
            "30":  [ "lp user {player} parent add veteran" ]
      messages:
        earned_now: "🎁 Je hebt een beloning verdiend: {reward}"
        claim_prompt: "🎁 Je hebt {count} onopgehaalde beloningen. Gebruik /rewards."
  • Data & persistentie (compact)

    -- Per speler voortgang
    CREATE TABLE pr_player (
      uuid BINARY(16) PRIMARY KEY,
      last_seen DATETIME(3) NOT NULL
    );
    
    -- Recurring progress (bv. resterende minuten tot volgende uur)
    CREATE TABLE pr_progress (
      uuid BINARY(16) NOT NULL,
      trigger_id VARCHAR(64) NOT NULL,
      progress_ms BIGINT NOT NULL DEFAULT 0,
      PRIMARY KEY (uuid, trigger_id)
    );
    
    -- Eénmalige drempels/claims om dubbele uitgifte te voorkomen
    CREATE TABLE pr_grants (
      uuid BINARY(16) NOT NULL,
      trigger_id VARCHAR(64) NOT NULL,
      token VARCHAR(64) NOT NULL,         -- bv. "threshold:100h" of "streak:7"
      granted_at DATETIME(3) NOT NULL,
      PRIMARY KEY (uuid, trigger_id, token)
    );
    
    -- Optioneel: wachtrij voor te claimen beloningen
    CREATE TABLE pr_pending_reward (
      id BIGINT AUTO_INCREMENT PRIMARY KEY,
      uuid BINARY(16) NOT NULL,
      payload TEXT NOT NULL,              -- command(s)/meta in JSON
      created_at DATETIME(3) NOT NULL
    );
  • Integraties

    • Speeltijdbron: DataRegistry/online-teller (niet AFK).
    • AFK: events om speeltijd te pauzeren.
    • Perms: LuckPerms voor tier-checks.

Acceptatiecriteria

  1. Periodieke speeltijd-rewards (bijv. elke 60 min) worden correct uitgedeeld/claimbaar, zonder AFK-tijd.
  2. Drempel-rewards bij 100h/200h/… worden éénmalig per drempel toegekend.
  3. Login-streaks tellen door volgens daggrens; rewards bij 3/7/30 dagen werken en resetten correct bij een gemiste dag.
  4. Permissie-tiers bepalen welke beloning je krijgt voor dezelfde trigger.
  5. Geen dubbele rewards bij reconnects of meerdere servers; progress en grants zijn persistent en idempotent.
  6. /rewards toont progress/claimables; admin-commands werken en loggen acties zonder console-errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions