Tier System
1. Summary
Goal: Единая система визуального различения предметов по редкости. Один источник истины для цветов, градиентов и glow эффектов.
User Value: Мгновенное понимание ценности предмета по цвету. Редкие предметы выделяются — создаёт желание их получить.
2. Business Logic
Tier Levels
| Tier | Название | HEX | Tailwind |
|---|---|---|---|
TIER_0 | Обычный | #9CA3AF | gray-400 |
TIER_1 | Необычный | #22C55E | green-500 |
TIER_2 | Редкий | #3B82F6 | blue-500 |
TIER_3 | Эпический | #A855F7 | purple-500 |
TIER_4 | Мифический | #EF4444 | red-500 |
TIER_5 | Легендарный | #EAB308 | yellow-500 |
Все tier получают визуальное оформление: цветная рамка + градиент снизу. Цвет определяется по таблице выше.
Resolution Logic
- SKIN
- FRAGMENT / BLUEPRINT
- BUFF
- SCRAP / XP
- RESOURCE
Источник tier: Собственный item.tier из БД
Пример: Dragon Rocket Launcher → TIER_4 (Мифический, красный)
Источник tier: Наследует от targetSkin.tier
Fallback: Если нет targetSkin → собственный item.tier
Фрагмент скина TIER_5 должен выглядеть так же ценно, как сам скин. Иначе пользователь не понимает что собирает.
Источник tier: item.tier напрямую из БД
Пример: XP Catalyst +100% → TIER_3 (задаётся в админке)
Tier: Всегда null → интерпретируется как TIER_0
Цвет рамки/glow: Серый (#9CA3AF)
Для узнаваемости в тексте: SCRAP = green-400, XP = yellow-400. Это не tier система, а Currency Display.
Tier: Всегда null → TIER_0
Пример: Ключи, расходники
Dark Colors (для рулетки)
Затемнённые версии для тёмных фонов (секторы колеса):
| Tier | HEX | Tailwind |
|---|---|---|
TIER_0 | #3d4654 | — |
TIER_1 | #166534 | green-800 |
TIER_2 | #1e40af | blue-800 |
TIER_3 | #581c87 | purple-800 |
TIER_4 | #991b1b | red-800 |
TIER_5 | #854d0e | yellow-800 |
3. ADR (Architectural Decisions)
Почему SCRAP/XP не имеют собственного tier?
Проблема: Предлагалось создать TIER_SCRAP, TIER_XP, TIER_SP для унификации.
Решение: Отклонено. Валюты получают tier = null → TIER_0.
Альтернативы (отклонены):
TIER_SCRAP/TIER_XP— смешивает концепции (редкость ≠ валюта)- Отдельные HEX для каждой валюты в tier системе — усложняет shouldGlow(), getTierColor()
Tier = редкость ПРЕДМЕТА (рамки, glow) Currency Display = узнаваемость валют в тексте (green/yellow/orange)
Не смешивать!
Последствия: Чистая архитектура, но нужно понимать разницу между системами.
Почему единый источник истины?
Проблема: Было 3 файла с константами tier (shared, frontend, admin). HEX цвета расходились.
Решение: Всё в shared/item-display-system/core/tier.system.ts, остальные реэкспортируют.
Что было удалено
| Файл | Удалённый код |
|---|---|
shared/tier.system.ts | CURRENCY_COLORS, getCurrencyColor() |
frontend/tiers.ts | RESOURCE_TEXT_COLORS, getResourceColor(), getTierFromMultiplier() |
Последствия: Любое изменение цвета — в одном месте. Гарантированная консистентность.
4. Architecture
Resolution Flow
Key Components
| Компонент | Путь | Описание |
|---|---|---|
| tier.system.ts | shared/src/item-display-system/core/tier.system.ts | Единый источник констант и функций |
| item.resolver.ts | shared/src/item-display-system/core/item.resolver.ts | resolveItemProps() для UI |
| tiers.ts | frontend/src/constants/tiers.ts | Frontend-специфичные стили (реэкспорт + Tailwind) |
| Currency | frontend/src/components/ui/Currency/ | Display цвета для валют |
5. API
Core Functions
// Получить tier с учётом наследования
resolveTier(item: UnifiedItem): ItemTier | null
// HEX цвет (null → TIER_0)
getTierColor(tier: ItemTier | null): string
// Затемнённый цвет для рулетки
getDarkTierColor(tier: ItemTier | null): string
// Tailwind класс градиента
getTierGradient(tier: ItemTier | null): string
// Название на русском
getTierName(tier: ItemTier | null): string
// Нужен ли glow (TIER_2+)
shouldGlow(item: UnifiedItem): boolean
Usage
- Frontend
- Admin
import {
resolveTier,
getTierColor,
getDarkTierColor,
shouldGlow,
} from '@goloot/shared/item-display-system';
// Для карточки предмета
const tier = resolveTier(item);
const color = getTierColor(tier);
const hasGlow = shouldGlow(item);
// Для рулетки (тёмный фон)
const sectorColor = getDarkTierColor(tier);
import { resolveTier, getTierColor } from '@goloot/shared/item-display-system';
// Цвет слота награды
const tier = resolveTier(item);
const slotColor = getTierColor(tier);
6. Contexts
Где что используется
| Контекст | Система | Результат для SCRAP/XP |
|---|---|---|
| 🎰 Рулетка (сектор) | Tier | Серый #3d4654 |
| 📦 Кейс (рамка/glow) | Tier | Серый, без glow |
| 📋 История | Tier | Серый текст |
| 📰 LiveFeed | Currency Display | Зелёный/Жёлтый текст |
| 🎁 TopFloating | Currency Display | Зелёный/Жёлтый текст |
Отдельная валюта лояльности. Цвет: orange-400. Не часть tier системы.
7. Related
- Buffs — баффы используют tier из БД
- Cases — награды кейсов с tier
- Daily Spins — секторы рулетки с tier цветами
- Inventory — отображение предметов с tier стилями