# Продукты (Products) Система продуктов и товаров в игре. ## Обзор Продукты — основа экономической модели. Каждый продукт имеет тип (конфигурацию) и экземпляр (количество). 📂 **Код:** [`backend/src/MyBiz.Core/Product*.cs`](../../backend/src/MyBiz.Core/) --- ## Архитектура ``` ┌─────────────────┐ ┌─────────────────┐ │ ProductType │ │ Product │ │ (конфигурация) │ ──────► │ (экземпляр) │ │ - Id │ Type │ - Quantity │ │ - Name │ │ - CurrentPrice │ │ - BasePrice │ │ - Quality │ │ - ShelfLife │ │ - IsSpoiled │ └─────────────────┘ └─────────────────┘ ▲ │ ┌─────────────────┐ │ ProductRegistry │ │ (реестр типов) │ └─────────────────┘ ``` --- ## ProductType **Назначение:** Конфигурация типа продукта для моддинга. 📂 **Исходный код:** [`ProductType.cs`](../../backend/src/MyBiz.Core/ProductType.cs) ### Основные свойства | Свойство | Тип | Описание | |----------|-----|----------| | `Id` | string | Уникальный идентификатор (для моддинга) | | `Name` | string | Отображаемое имя | | `Description` | string | Описание продукта | | `Category` | ProductCategory | Категория (сырьё/компонент/товар) | | `BasePrice` | decimal | Базовая цена | | `BaseDemand` | int | Базовый спрос в тик | | `DemandElasticity` | float | Эластичность спроса (0-1) | | `ShelfLife` | int | Срок хранения в тиках (0 = бессрочно) | | `StackSize` | int | Размер стека в инвентаре | | `AvailableFromYear` | int | Год доступности (исторический режим) | | `RequiredTechnologies` | List | Требуемые технологии | ### Вычисляемые свойства - `IsPerishable` — портится ли продукт (ShelfLife > 0) ### Методы - `Clone()` — создание независимой копии --- ## Product **Назначение:** Экземпляр продукта в инвентаре/на складе. 📂 **Исходный код:** [`Product.cs`](../../backend/src/MyBiz.Core/Product.cs) ### Основные свойства | Свойство | Тип | Описание | |----------|-----|----------| | `Id` | Guid | Уникальный ID экземпляра | | `Type` | ProductType | Ссылка на конфигурацию типа | | `Quantity` | int | Количество | | `CurrentPrice` | decimal | Текущая цена за единицу | | `CreatedAtTick` | int | Тик создания (для срока годности) | | `Quality` | int | Качество (0-100) | | `IsSpoiled` | bool | Испорчен ли | ### Вычисляемые свойства - `TotalValue` — общая стоимость (Quantity × CurrentPrice) - `IsUsable` — можно ли использовать (Quantity > 0 && !IsSpoiled) ### Методы | Метод | Описание | |-------|----------| | `Add(int amount)` | Добавить количество | | `Remove(int amount)` | Удалить количество (возвращает факт. удалённое) | | `Update(int currentTick)` | Обновить состояние (проверка срока годности) | --- ## ProductRegistry **Назначение:** Централизованный реестр типов продуктов. 📂 **Исходный код:** [`ProductRegistry.cs`](../../backend/src/MyBiz.Core/ProductRegistry.cs) ### Методы | Метод | Описание | |-------|----------| | `Register(ProductType)` | Зарегистрировать тип | | `GetById(string)` | Получить по ID | | `GetOrThrow(string)` | Получить или выбросить исключение | | `Exists(string)` | Проверка существования | | `GetByCategory(ProductCategory)` | Фильтр по категории | | `GetAvailableInYear(int)` | Фильтр по году доступности | | `Remove(string)` | Удалить тип | | `LoadFromConfig(string)` | Загрузить из JSON (TODO) | | `ExportToJson()` | Экспорт в JSON (TODO) | ### События - `ProductTypeAdded` — добавлен новый тип (для моддинга) - `ProductTypeModified` — изменён тип --- ## Дефолтные продукты **12 продуктов в 3 категориях:** 📂 **Исходный код:** [`DefaultProducts.cs`](../../backend/src/MyBiz.Core/DefaultProducts.cs) ### Сырьё (RawMaterial) | ID | Название | Базовая цена | Портится | С года | |----|----------|--------------|----------|---------| | `raw_cotton` | Хлопок | 5 | ❌ | 1900 | | `raw_steel` | Сталь | 15 | ❌ | 1900 | | `raw_plastic` | Пластик | 8 | ❌ | 1950 | | `raw_food` | Сельхозпродукция | 3 | ✅ (10 тиков) | 1900 | ### Компоненты (Component) | ID | Название | Базовая цена | Портится | С года | |----|----------|--------------|----------|---------| | `comp_fabric` | Ткань | 12 | ❌ | 1900 | | `comp_metal_parts` | Металлоизделия | 25 | ❌ | 1900 | | `comp_plastic_parts` | Пластиковые детали | 18 | ❌ | 1950 | | `comp_electronics` | Электронные компоненты | 50 | ❌ | 1960 | ### Товары (ConsumerGoods) | ID | Название | Базовая цена | Портится | С года | |----|----------|--------------|----------|---------| | `goods_food` | Продукты питания | 8 | ✅ (5 тиков) | 1900 | | `goods_clothing` | Одежда | 35 | ❌ | 1900 | | `goods_electronics` | Электроника | 150 | ❌ | 1960 | | `goods_automobile` | Автомобили | 5000 | ❌ | 1920 | --- ## Примеры использования ### Регистрация типа продукта ```csharp var registry = new ProductRegistry(); var bread = new ProductType { Id = "food_bread", Name = "Хлеб", Category = ProductCategory.ConsumerGoods, BasePrice = 10m, ShelfLife = 5, AvailableFromYear = 1900 }; registry.Register(bread); ``` ### Создание экземпляра продукта ```csharp var product = new Product { Type = registry.GetOrThrow("goods_food"), Quantity = 100, CurrentPrice = 8m, CreatedAtTick = 0 }; product.Add(50); // +50 единиц product.Remove(30); // -30 единиц product.Update(10); // проверка через 10 тиков ``` ### Фильтрация продуктов ```csharp // Все сырьевые продукты var rawMaterials = registry.GetByCategory(ProductCategory.RawMaterial); // Доступные в 1950 году var available1950 = registry.GetAvailableInYear(1950); // Скоропортящиеся var perishable = registry.AllProductTypes.Where(p => p.IsPerishable); ``` --- ## Тесты 📂 **Код:** [`backend/tests/MyBiz.Tests/ProductTests.cs`](../../backend/tests/MyBiz.Tests/ProductTests.cs) | Тест | Описание | |------|----------| | `ProductType_Creation_ShouldInitializeProperties` | Создание типа продукта | | `ProductType_Clone_ShouldCreateIndependentCopy` | Клонирование типа | | `Product_Add_ShouldIncreaseQuantity` | Добавление количества | | `Product_Remove_ShouldDecreaseQuantity` | Удаление количества | | `Product_Perishable_ShouldSpoilAfterShelfLife` | Порча продуктов | | `Registry_*` | Тесты реестра | --- ## Связанные документы - [Ядро](core.md) — базовые классы - [Производство](production.md) — использование продуктов в цепочках - [Торговля](trade.md) — рынки и цены --- **Последнее обновление:** 20.02.2026