Promo Codes

The promo code system allows administrators to create codes that players can redeem for rewards. Codes can be defined in mod assets (read-only) or created at runtime via admin commands. <span class="since-badge">v2.9.0</span>

Code Types

TypeDescription
singleOne use total on the server (first come, first served)
personalOne use per player
multiLimited total uses (see maxUses)
unlimitedNo usage limits

Reward Types

TypeDescriptionFields
actionItemGives an action item by ID from itemconfig.jsonitemId, amount, applyQuality, forceQuality
itemGives a vanilla/modded item by asset codeitemCode or itemId, amount
questStarts a questquestId
reputationAdds reputationreputationId, reputationAmount, reputationType ("npc" or "faction")

Conditions

Promo codes can have redemption conditions:

FieldTypeDescription
validFromstringCode is only valid after this date (UTC ISO format)
validUntilstringCode is only valid until this date (UTC ISO format)
requiredQuestsstring[]Player must have completed these quests

Security

  • Rate limiting: max maxAttemptsPerMinute (default 5) failed attempts per minute
  • Lockout: after lockoutThreshold (default 15) failed attempts, player is locked out for lockoutMinutes (default 10) minutes
  • Case insensitive: codes are case-insensitive by default
  • Security by obscurity: invalid codes return the same error regardless of whether the code exists

Redemption Flow

graph TD
    A[Player types /promo] --> B[Enter code dialog]
    B --> C{Player locked out?}
    C -->|Yes| D[Show lockout timer]
    C -->|No| E{Code exists?}
    E -->|No| F[Generic error:
invalid or expired] E -->|Yes| G{Type valid?} G -->|No| F G -->|Yes| H{Conditions met?} H -->|No| I[Condition fail message] H -->|Yes| J{Uses left?} J -->|No| K[Already redeemed] J -->|Yes| L[Grant rewards] L --> M[Mark used] M --> N[Show success message] N --> O[Sync to database]

Asset-based Configuration

Defined in mod assets (config/promocodes.json), read-only:

{
  "settings": {
    "maxAttemptsPerMinute": 5,
    "lockoutMinutes": 10,
    "lockoutThreshold": 15,
    "caseInsensitive": true
  },
  "codes": [
    {
      "code": "WELCOME2025",
      "type": "personal",
      "maxUses": 0,
      "enabled": true,
      "message": "yourmod:promo-welcome-success",
      "rewards": [
        {
          "type": "actionItem",
          "itemId": "starter-sword",
          "amount": 1,
          "applyQuality": true
        }
      ],
      "conditions": {
        "validFrom": "2025-01-01T00:00:00Z",
        "validUntil": "2025-12-31T23:59:59Z",
        "requiredQuests": []
      }
    }
  ]
}

Runtime Configuration

Stored in ModConfig/alegacyvsquest/promocodes-runtime.json. Created and managed via /avq promo commands.

Commands

Admin Commands (/avq promo)

Require give privilege.

CommandArgumentsDescription
/avq promo create<code> [type] [maxUses]Create a new promo code
/avq promo delete<code>Delete a promo code
/avq promo list—List all promo codes
/avq promo info<code>Show info about a promo code
/avq promo addreward<code> <rewardType> <itemId> [amount]Add a reward to an existing code
/avq promo reload—Reload promo code configs
/avq promo reset<playerName> <code>Reset a player's usage of a code

Player Command

CommandPrivilegeDescription
/promochatOpens the promo code redemption dialog

Database Sync

When a code is redeemed, the data is synced to an external database (if configured):

  • Fields: player_uid, player_name, code, rewards_json
  • Endpoint: POST /vsquest/promo-redemptions

Complete Example

Starter pack code (asset-based)

{
  "code": "WELCOME2025",
  "type": "personal",
  "enabled": true,
  "message": "yourmod:promo-welcome",
  "rewards": [
    {
      "type": "actionItem",
      "itemId": "starter-sword",
      "amount": 1,
      "applyQuality": true
    },
    {
      "type": "item",
      "itemCode": "game:healthpotion",
      "amount": 5
    }
  ],
  "conditions": {
    "validFrom": "2025-01-01T00:00:00Z",
    "validUntil": "2025-12-31T23:59:59Z"
  }
}

Event raffle code (runtime)

/avq promo create RAFFLE50 multi 50
/avq promo addreward RAFFLE50 item game:gear-rusty 1
/avq promo addreward RAFFLE50 actionItem yourmod:firework-launcher 1

Reputation reward code

{
  "code": "LOYALFAN",
  "type": "single",
  "enabled": true,
  "rewards": [
    {
      "type": "reputation",
      "reputationId": "yourmod:community",
      "reputationAmount": 100,
      "reputationType": "faction"
    }
  ]
}

Quest-start code

{
  "code": "SECRETQUEST",
  "type": "personal",
  "enabled": true,
  "rewards": [
    {
      "type": "quest",
      "questId": "yourmod:hidden-quest"
    }
  ],
  "conditions": {
    "requiredQuests": ["yourmod:main-story-5"]
  }
}

Examples

Creating a promo code via command

/avq promo create NEWYEAR personal
/avq promo addreward NEWYEAR actionItem firework-launcher 3

Limited-use code

/avq promo create RAFFLE50 multi 50
/avq promo addreward RAFFLE50 item game:gear-rusty 1

Resetting player usage

/avq promo reset PlayerName WELCOME2025

Localization

{
  "yourmod:promo-welcome": "Welcome! Here's your starter pack.",
  "yourmod:promo-invalid": "Invalid or expired code.",
  "yourmod:promo-locked": "Too many attempts. Try again in {0} minutes.",
  "yourmod:promo-already": "You already redeemed this code.",
  "yourmod:promo-conditions": "You don't meet the requirements for this code."
}

Press ESC to close