Lucky Spin
Configurable prize wheels. Each wheel is its own file with its own entry requirements, cost, recharge schedule, and prize ring. Players spend a charge to spin; the wheel rolls a slot by weight and the prize lands in the inventory.
File Location#
Data/Plugins/LuckySpin/Config.xml master switch
Data/Plugins/LuckySpin/000.xml wheel 0
Data/Plugins/LuckySpin/001.xml wheel 1
...
Data/Plugins/LuckySpin/031.xml wheel 31 (maximum)
The file number is the wheel id. Up to 32 wheels (000-031). Loaded at GameServer startup and streamed to the client; a wheel that fails validation is skipped with a log line and does not affect the others.
Master Switch#
<LuckySpin Enabled="1" />
| Attribute | Type | Default | Effect |
|---|---|---|---|
Enabled | 0/1 | 1 | Master toggle for the whole system. 0 = no wheels load, the UI is unreachable |
Wheel File#
<LuckyWheel Name="..." AccountLevel="..." MinLevel="..." MaxLevel="..."
MinReset="..." MaxReset="..." Limit="..." Announce="...">
<Classes DW="1" DK="1" FE="1" MG="1" DL="1" SU="1" RF="1"/>
<Cost Zen="..." WCoinC="..." WCoinP="..." GoblinPoint="...">
<Item Type="..." Index="..." Level="..."/>
</Cost>
<Recharge Monday="..." Tuesday="..." Wednesday="..." Thursday="..."
Friday="..." Saturday="..." Sunday="..."/>
<Items>
<Item Position="1" Rate="..." Type="..." Index="..." .../>
<Empty Position="2" Rate="..."/>
</Items>
<Announce Success="..." Fail="..."/>
</LuckyWheel>
Wheel Attributes#
| Attribute | Type | Default | Effect |
|---|---|---|---|
Name | string (up to 32 chars) | - | Shown in the wheel list, the wheel view, and announcements |
AccountLevel | int | -1 | Minimum account/VIP level required to see and spin this wheel. -1 = no gate |
MinLevel | int | -1 | Minimum character level. -1 = no gate |
MaxLevel | int | -1 | Maximum character level. -1 = no gate |
MinReset | int | -1 | Minimum resets. -1 = no gate |
MaxReset | int | -1 | Maximum resets. -1 = no gate |
Limit | 1-255 | - | Charge cap. Fresh accounts start at this cap - the recharge schedule only tops charges back up afterwards |
Announce | 0-3 | 0 | 0 silent · 1 announce wins · 2 announce losses · 3 both |
Wheels a character does not qualify for are hidden from that character entirely, so gating by level or reset range is a safe way to build a progression ladder of wheels.
Classes#
<Classes DW="1" DK="1" FE="1" MG="0" DL="0" SU="0" RF="0"/>
Per base class, 1 = allowed, 0 = blocked. Evolutions inherit their base class flag. Omit the whole element to allow every class - an empty or partial element still blocks anything not set to 1.
| Code | Class |
|---|---|
DW | Dark Wizard |
DK | Dark Knight |
FE | Fairy Elf |
MG | Magic Gladiator |
DL | Dark Lord |
SU | Summoner |
RF | Rage Fighter |
Cost#
Charged per spin, in addition to consuming one charge. All non-zero parts are charged together.
| Attribute | Type | Effect |
|---|---|---|
Zen | int | Zen taken per spin |
WCoinC | int | WCoin (C) taken per spin |
WCoinP | int | WCoin (P) taken per spin |
GoblinPoint | int | Goblin Points taken per spin |
An optional <Item> child makes an inventory item part of the price. It is matched exactly on type, index, level and options - a +0 jewel will not pay for a +1 requirement.
Omit <Cost>, or leave every part at 0, for a wheel that costs charges only.
Recharge#
<Recharge Monday="1" Tuesday="1" Wednesday="1" Thursday="0"
Friday="0" Saturday="2" Sunday="2"/>
Charges granted at the first login of that weekday, capped at Limit. Missed days do not stack - a player who does not log in on Monday never receives Monday's charge.
Prize Ring#
Between 2 and 12 positions. The slot count is the highest Position present and positions 1..count must be contiguous - a gap invalidates the wheel. The client spaces the ring evenly (360°/count), so smaller wheels simply spread out. Position 1 is 12 o'clock, numbering clockwise.
| Attribute | Type | Default | Effect |
|---|---|---|---|
Position | 1-12 | - | Ring slot |
Rate | 0-10000 | - | Roll weight. Weights do not need to total 100 or 10000 - higher is likelier, relative to the other slots on this wheel |
X Y | int | 0 | Pixel nudge of the icon inside its cell |
Size | float | 1.0 | Icon scale |
<Empty> is a losing slot: it consumes the charge and the cost and grants nothing.
<Item> slots additionally take Type, Index, Level, Durability, Skill, Luck, Option, Excellent, Ancient, Harmony, Opt380.
| Prize attribute | Notes |
|---|---|
Excellent | 6-bit mask, 63 = all six excellent options |
Option | +option (JoL) level, 0-7 |
Durability | -1 = engine default for that item |
Skill Luck Ancient Harmony Opt380 | 0/1 flags |
Announcements#
<Announce Success="{name} struck gold and won {item} on the {wheel}!"
Fail="{name} spun the {wheel} but walked away empty-handed."/>
| Placeholder | Replaced with |
|---|---|
{name} | Character name |
{wheel} | Wheel Name |
{item} | Prize name, including +level when the prize has one |
Important Behavior#
- Charges start full. A brand-new account immediately has
Limitspins on every wheel it qualifies for. SetLimitto the burst you are comfortable handing a fresh account, not to a weekly total. - Rates are weights, not percentages. A slot's real chance is its
Ratedivided by the sum of allRatevalues on that wheel. Adding a slot dilutes every other slot. - Inventory space is checked before the roll. A spin is refused (nothing is charged) unless the inventory has a free spot as big as the wheel's largest prize. The size is the widest and the tallest prize on the wheel, taken separately (a 1x4 prize and a 2x2 prize on one wheel need a 2x4 spot). So a player cannot leave only a 1x1 gap to filter out big prizes.
- Wins are never dropped. The prize is given when the wheel stops (about 3.5 seconds). If the inventory filled up in that time, the player is told to make space and the server tries again every 2 seconds. The win is saved in the database until it is delivered, so a disconnect or crash gives the prize at next login.
- Do not use Muun or event items as prizes. They route to a separate inventory that bypasses the inventory space check, so the prize can be silently lost when that inventory is full.
- Announcement volume.
Announce="3"is useful while testing but broadcasts every loss to global chat. Production servers normally use1. - Wheels are validated independently. A typo in
003.xmldisables wheel 3 only; the rest keep working.
Common Issues#
- A wheel does not appear for a player - they fail one of
AccountLevel,MinLevel/MaxLevel,MinReset/MaxReset, or their class is not set to1in<Classes> - Nobody sees any wheel -
Config.xmlhasEnabled="0", or every wheel file failed validation (check the GameServer log at startup) - Wheel missing after edit - non-contiguous
Positionvalues, fewer than 2 or more than 12 slots, or malformed XML - Spin refused, nothing charged - besides cost and charges, check space: the inventory has no free spot as big as the wheel's largest prize. Free up room and spin again
- Prize did not land yet - the inventory filled up after the spin. The server retries every 2 seconds and keeps the win until it fits (also across relogs). A Muun/event item prize can still be lost (see above)
- Players never regain spins - every
<Recharge>day is0, or they only log in on days set to0 - The cost is not taken -
<Cost>is missing or all-zero, which is a free wheel by design