Add technical documentation structure
This commit is contained in:
235
docs/tech/products.md
Normal file
235
docs/tech/products.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# Продукты (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<string> | Требуемые технологии |
|
||||
|
||||
### Вычисляемые свойства
|
||||
|
||||
- `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
|
||||
Reference in New Issue
Block a user