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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions