Skip to main content

Tier System

1. Summary

Goal: Система визуального различения предметов по редкости. Определяет цвета, градиенты и glow эффекты для каждого tier.

User Value: Мгновенное понимание ценности предмета по цвету. Редкие предметы выделяются — создаёт желание их получить.

Не единый источник истины

Вопреки изначальному плану, tier-константы продублированы в трёх файлах с разными значениями (см. Architecture). Shared содержит core-функции и базовые константы, но frontend и admin определяют собственные расширенные наборы стилей.


2. Business Logic

Tier Levels

TierНазваниеHEXTailwind
TIER_0Обычный#9CA3AFgray-400
TIER_1Необычный#22C55Egreen-500
TIER_2Редкий#3B82F6blue-500
TIER_3Эпический#A855F7purple-500
TIER_4Мифический#EF4444red-500
TIER_5Легендарный#EAB308yellow-500
Визуальные стили

Все tier получают визуальное оформление: цветная рамка + градиент снизу. Цвет определяется по таблице выше.

Resolution Logic

Источник tier: Собственный item.tier из БД

Пример: Dragon Rocket Launcher → TIER_4 (Мифический, красный)

Dark Colors (для рулетки)

Затемнённые версии для тёмных фонов (секторы колеса):

TierHEXTailwind
TIER_0#3d4654
TIER_1#166534green-800
TIER_2#1e40afblue-800
TIER_3#581c87purple-800
TIER_4#991b1bred-800
TIER_5#854d0eyellow-800

3. ADR (Architectural Decisions)

Почему SCRAP/XP не имеют собственного tier?

Проблема: Предлагалось создать TIER_SCRAP, TIER_XP, TIER_SP для унификации.

Решение: Отклонено. Валюты получают tier = nullTIER_0.

Альтернативы (отклонены):

  • TIER_SCRAP/TIER_XP — смешивает концепции (редкость ≠ валюта)
  • Отдельные HEX для каждой валюты в tier системе — усложняет shouldGlow(), getTierColor()
Разные системы для разных целей

Tier = редкость ПРЕДМЕТА (рамки, glow) Currency Display = узнаваемость валют в тексте (green/yellow/orange)

Не смешивать!

Последствия: Чистая архитектура, но нужно понимать разницу между системами.

Почему планировался единый источник истины?

Проблема: Было 3 файла с константами tier (shared, frontend, admin). HEX цвета расходились.

Решение (частичное): Core-функции и базовые HEX-константы вынесены в shared/item-display-system/core/tier.system.ts. Однако frontend и admin по-прежнему содержат собственные определения tier-констант с отличающимися значениями.

Что было удалено
ФайлУдалённый код
shared/tier.system.tsCURRENCY_COLORS, getCurrencyColor()
frontend/tiers.tsRESOURCE_TEXT_COLORS, getResourceColor(), getTierFromMultiplier()
Текущая ситуация: дублирование с расхождениями

TIER_GRADIENTS определён в двух файлах с разными значениями:

Tiershared/.../tier.system.tsfrontend/.../tiers.ts
TIER_0from-neutral-700/90 via-neutral-800/60from-gray-900/80 via-gray-950/50
TIER_1from-green-900/60 via-green-950/30from-green-900/80 via-green-950/50
TIER_2from-blue-900/60 via-blue-950/30from-blue-900/80 via-blue-950/50
TIER_3from-purple-900/60 via-purple-950/30from-purple-900/80 via-purple-950/50
TIER_4from-red-900/60 via-red-950/30from-red-900/80 via-red-950/50
TIER_5from-yellow-900/60 via-yellow-950/30from-yellow-900/80 via-yellow-950/50

Ключевые отличия:

  • Shared использует neutral для TIER_0, frontend использует gray (gray имеет синий подтон)
  • Прозрачность: shared 90/60, frontend 80/50 (frontend более прозрачный)
  • Остальные tiers: shared 60/30, frontend 80/50 (frontend интенсивнее)

Аналогично TIER_NAMES, TIER_BG_COLORS дублированы между shared и frontend с одинаковыми значениями. TIER_TEXT_COLORS определена только в frontend и admin (не в shared).

Последствия: Shared определяет градиенты для ItemCell (используется через resolveItemProps), а frontend определяет свою версию для FlippableItemCard и других компонентов. Оба варианта используются в разных контекстах.


4. Architecture

Resolution Flow

Key Components

КомпонентПутьОписание
tier.system.tsshared/src/item-display-system/core/tier.system.tsCore-константы (HEX, gradients, borders) и функции (resolveTier, getTierColor и т.д.)
item.resolver.tsshared/src/item-display-system/core/item.resolver.tsresolveItemProps() — единый резолвер всех визуальных свойств для UI
tiers.ts (frontend)frontend/src/constants/tiers.tsРасширенный набор frontend-стилей: константы (TIER_GRADIENTS, TIER_CARD_STYLES, TIER_GLOW_COLORS, TIER_HSL_COLORS, TIER_HISTORY_CARD_STYLES, TIER_ACTION_BUTTON_STYLES, TIER_THIN_BORDER_STYLES, TIER_HEX_COLORS, TIER_CONFETTI_CONFIG, REWARD_CONFETTI_CONFIG), типы (ItemTier, TierNumber), конвертеры (TIER_TO_NUMBER, NUMBER_TO_TIER, tierFromNumber, tierToNumber), утилиты (getTierTextColor, getTierCardStyle, getTierHistoryCardStyle, getTierActionButtonStyle, getTierGlowColor, getTierThinBorderStyle, interpolateTierColor, getConfettiConfig и др.). Реэкспортирует только getDarkTierColor и TIER_DARK_COLORS из shared
tiers.ts (admin)admin/src/constants/tiers.tsНабор для админки: константы (TIER_NAMES, TIER_TEXT_COLORS, TIER_HEX_COLORS, TIER_BADGE_COLORS, TIER_BORDER_COLORS, TIER_SHORT_LABELS, TIER_BADGE_TEXT_HEX), утилиты (getTierName, getTierTextColor, getTierHexColor, getTierBadgeColor, getTierBorderColor, getTierNameOrNull, getTierBadgeConfig), тип ItemTier. Полностью независим от shared
Currencyfrontend/src/components/ui/Currency/Display цвета для валют

5. API

Core Functions (shared/tier.system.ts)

// Получить tier с учётом наследования
resolveTier(item: UnifiedItem): ItemTier | null

// Получить эффективный tier (null → TIER_0, всегда возвращает tier)
getEffectiveTier(item: UnifiedItem): ItemTier

// HEX цвет (null → TIER_0)
getTierColor(tier: ItemTier | null): string

// Затемнённый цвет для рулетки
getDarkTierColor(tier: ItemTier | null): string

// Tailwind класс градиента
getTierGradient(tier: ItemTier | null): string

// Tailwind класс border
getTierBorder(tier: ItemTier | null): string

// HEX цвет border (для inline styles)
getTierBorderColor(tier: ItemTier | null): string

// Tailwind класс bg
getTierBgColor(tier: ItemTier | null): string

// Название на русском
getTierName(tier: ItemTier | null): string

// Нужен ли glow по tier (TIER_2+)
shouldGlowByTier(tier: ItemTier | null): boolean

// Нужен ли glow для предмета (использует resolveTier)
shouldGlow(item: UnifiedItem): boolean

Usage

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);

6. Contexts

Где что используется

КонтекстСистемаРезультат для SCRAP/XP
🎰 Рулетка (сектор)TierСерый #3d4654
📦 Кейс (рамка/glow)TierСерый, без glow
📋 ИсторияTierСерый текст
📰 LiveFeedCurrency DisplayЗелёный/Жёлтый текст
🎁 TopFloatingCurrency DisplayЗелёный/Жёлтый текст
STREAK_POINTS

Отдельная валюта лояльности. Цвет: orange-400. Не часть tier системы.

BOOST_POINTS

Валюта Boost Pass. Цвет: text-blue-400. Определена в currency.constants.ts. Не часть tier системы.


  • Buffs — баффы используют tier из БД
  • Cases — награды кейсов с tier
  • Daily Spins — секторы рулетки с tier цветами
  • Inventory — отображение предметов с tier стилями