Разберём, как создать сбалансированную систему лута для TFS (The Forgotten Server) с учётом редкости и баланса.
Шаг 1. Определение категорий редкости
Установите чёткие уровни редкости с процентными шансами выпадения:
- Обычные (Common) — 70–80 % (зелёный цвет): зелья маны, базовые свитки, монеты.
- Необычные (Uncommon) — 15–20 % (синий цвет): улучшенные зелья, редкие компоненты.
- Редкие (Rare) — 5–10 % (фиолетовый цвет): уникальные мечи, магические амулеты.
- Эпические (Epic) — 1–2 % (оранжевый цвет): легендарные доспехи, артефакты.
- Легендарные (Legendary) — 0,1–0,5 % (красный цвет): оружие с особыми эффектами, реликвии.
Шаг 2. Создание таблицы лута
Создайте JSON‑файл data/items/loot_table.json:
json
{
"goblin": {
"common": [
{"item_id": 268, "chance": 80, "count": [1, 3]},
{"item_id": 2148, "chance": 90, "count": [5, 20]}
],
"uncommon": [
{"item_id": 3061, "chance": 25, "count": 1}
]
},
"dragon": {
"rare": [
{"item_id": 7440, "chance": 40, "count": 1}
],
"epic": [
{"item_id": 8874, "chance": 5, "count": 1}
],
"legendary": [
{"item_id": 9999, "chance": 0.5, "count": 1}
]
}
}
Шаг 3. Реализация системы выпадения лута (Lua)
Создайте скрипт data/scripts/loot_system.lua:
lua
local lootSystem = {}
-- Загрузка таблицы лута
function lootSystem.loadLootTable()
local file = io.open("data/items/loot_table.json", "r")
if not file then return {} end
local content = file:read("*all")
file:close()
return json.decode(content)
end
-- Генерация лута для моба
function lootSystem.generateLoot(mobName)
local lootTable = lootSystem.loadLootTable()
local mobLoot = lootTable[mobName] or {}
local result = {}
for rarity, items in pairs(mobLoot) do
for _, itemData in ipairs(items) do
if math.random(1, 100) <= itemData.chance then
local count = math.random(itemData.count[1], itemData.count[2] or itemData.count)
table.insert(result, {
item_id = itemData.item_id,
count = count,
rarity = rarity
})
end
end
end
return result
end
-- Функция для выдачи лута игроку
function lootSystem.giveLootToPlayer(player, mobName)
local loot = lootSystem.generateLoot(mobName)
if #loot == 0 then return false end
for _, item in ipairs(loot) do
player:addItem(item.item_id, item.count)
player:sendTextMessage(MESSAGE_INFO_DESCR,
string.format("Вы получили: %dx %s (%s)",
item.count,
ItemType(item.item_id):getName(),
item.rarity
)
)
end
return true
end
return lootSystem
Шаг 4. Интеграция с системой мобов
Добавьте в скрипт моба (data/creaturescripts/monsters/dragon.lua):
lua
function onDeath(creature, corpse, killer)
if killer and killer:isPlayer() then
local lootSystem = require("data/scripts/loot_system")
lootSystem.giveLootToPlayer(killer, "dragon")
end
return true
end
Шаг 5. Баланс характеристик предметов
Правила баланса:
- Уровень предмета = уровень моба × 0,8–1,2.
- Урон оружия: базовый урон моба × 0,7–1,3.
- Защита брони: базовая защита моба × 0,6–1,4.
- Ограничения по уровню: предмет доступен с уровня = уровень моба × 0,9.
Пример расчёта для дракона (уровень 100):
- меч: урон 80–130, требуется уровень 90;
- броня: защита 60–140, требуется уровень 90.
Шаг 6. Уникальные свойства для редких предметов
Добавьте особые эффекты для эпических и легендарных предметов:
lua
-- data/items/unique_items.lua
local uniqueItems = {
[9999] = { -- ID легендарного меча
name = "Клинок Вечности",
attributes = {
attack = 150,
defense = 50,
element_fire = 20, -- +20 урона огнём
speed = 10
},
effects = {
onHit = function(player, target)
if math.random(1, 100) <= 15 then -- 15 % шанс
target:addDamage(50, COMBAT_FIREDAMAGE)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Ваш клинок поджёг врага!")
end
end
}
}
}
function applyUniqueItemEffects(itemId, player, target)
local item = uniqueItems[itemId]
if item and item.effects and item.effects.onHit then
item.effects.onHit(player, target)
end
end
Шаг 7. Настройка выпадения лута
Факторы влияния на редкость:
- Уровень моба: чем выше, тем выше шанс редких предметов.
- Время суток: ночные мобы дают больше редких предметов (+20 %).
- События сервера: во время ивентов шанс легендарных предметов ×2.
- Прогрессия игрока: для высокоуровневых игроков шанс редких предметов снижается на 30 %.
Модификаторы шанса:
lua
function lootSystem.calculateRarityModifier(mobLevel, playerLevel)
local baseModifier = 1.0
if playerLevel > mobLevel * 1.5 then
baseModifier = baseModifier * 0.7 -- -30 % для сильных игроков
end
if isNightTime() then
baseModifier = baseModifier * 1.2 -- +20 % ночью
end
return baseModifier
end
Тестирование системы
Чек‑лист:
- Обычные мобы (гоблины) дают только common/uncommon предметы.
- Боссы (драконы) дают rare/epic/legendary предметы.
- Шансы выпадения соответствуют настройкам в JSON.
- Уникальные эффекты работают корректно.
- Ограничения по уровню соблюдаются.
- Модификаторы времени суток и прогрессии работают.
Команды для тестирования:
- /reload loot — перезагрузка таблицы лута;
- /testloot dragon — тестирование лута босса;
- /lootinfo — просмотр статистики выпадения.
Устранение распространённых проблем
- «Лута нет»: проверьте таблицу лута и шансы выпадения.
- «Слишком много редких предметов»: уменьшите шансы в JSON или модификаторы.
- «Эффекты не работают»: проверьте ID предметов и функции в unique_items.lua.
- «Ошибки в логах»: проверьте синтаксис Lua и JSON.
- «Предметы не добавляются»: убедитесь, что ID предметов существуют в items.xml.
Рекомендации по балансу
- Не более 1 легендарного предмета на 200 обычных мобов.
- Уникальные эффекты не должны ломать баланс: максимум +30 % к урону.
- Ограничение по уровню: предметы должны быть актуальны 2–3 уровня.
- Экономический баланс: редкие предметы не должны обесценивать торговлю.