Увеличен лимит очков до 1000 и добавлена документация
- Максимум очков за челлендж/прохождение: 500 → 1000 - Добавлена документация по системе типов игр (docs/game-types.md) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
242
docs/game-types.md
Normal file
242
docs/game-types.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Система типов игр
|
||||
|
||||
## Обзор
|
||||
|
||||
В системе существует два типа игр, определяющих логику выдачи заданий:
|
||||
|
||||
| Тип | Значение | Описание |
|
||||
|-----|----------|----------|
|
||||
| **Челленджи** | `challenges` | При спине выдаётся один случайный челлендж из списка |
|
||||
| **Прохождение** | `playthrough` | Нужно пройти игру целиком, челленджи становятся бонусными |
|
||||
|
||||
---
|
||||
|
||||
## Модели данных
|
||||
|
||||
### Game
|
||||
|
||||
```
|
||||
game_type: str # "challenges" | "playthrough"
|
||||
playthrough_points: int? # Очки за прохождение (только для playthrough)
|
||||
playthrough_description: str? # Описание задания
|
||||
playthrough_proof_type: str? # Тип пруфа: screenshot/video/steam
|
||||
playthrough_proof_hint: str? # Подсказка для пруфа
|
||||
```
|
||||
|
||||
### Assignment
|
||||
|
||||
```
|
||||
challenge_id: int? # ID челленджа (для challenges)
|
||||
game_id: int? # ID игры (для playthrough)
|
||||
is_playthrough: bool # True если это прохождение
|
||||
```
|
||||
|
||||
### BonusAssignment
|
||||
|
||||
```
|
||||
main_assignment_id: int # Ссылка на основное задание (playthrough)
|
||||
challenge_id: int # ID бонусного челленджа
|
||||
status: str # "pending" | "completed"
|
||||
proof_path: str? # Путь к файлу пруфа
|
||||
proof_url: str? # URL пруфа
|
||||
proof_comment: str? # Комментарий со ссылкой
|
||||
points_earned: int # Заработанные очки
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Логика спина
|
||||
|
||||
### Тип "Челленджи" (challenges)
|
||||
|
||||
```
|
||||
1. Выбрать случайную игру из доступных
|
||||
2. Отфильтровать уже выполненные челленджи этой игры
|
||||
3. Выбрать случайный невыполненный челлендж
|
||||
4. Создать Assignment с challenge_id
|
||||
```
|
||||
|
||||
**Игра исключается из спина**, если все её челленджи выполнены.
|
||||
|
||||
### Тип "Прохождение" (playthrough)
|
||||
|
||||
```
|
||||
1. Выбрать случайную игру из доступных
|
||||
2. Создать Assignment с game_id и is_playthrough=True
|
||||
3. Создать BonusAssignment для каждого челленджа игры
|
||||
4. События (Jackpot, Golden Hour и т.д.) ИГНОРИРУЮТСЯ
|
||||
```
|
||||
|
||||
**Игра исключается из спина**, если есть Assignment со статусом COMPLETED или DROPPED.
|
||||
|
||||
---
|
||||
|
||||
## Завершение заданий
|
||||
|
||||
### Челлендж (challenges)
|
||||
|
||||
```
|
||||
POST /marathons/{id}/complete-assignment
|
||||
```
|
||||
|
||||
1. Загрузить пруф (файл или комментарий)
|
||||
2. Начисляются очки челленджа × модификатор события
|
||||
3. Увеличивается серия участника
|
||||
4. Статус → COMPLETED
|
||||
|
||||
### Прохождение (playthrough)
|
||||
|
||||
```
|
||||
POST /marathons/{id}/complete-assignment
|
||||
```
|
||||
|
||||
1. Загрузить пруф прохождения
|
||||
2. Начисляются очки за прохождение (`playthrough_points`)
|
||||
3. Бонусные очки добавляются из completed BonusAssignments
|
||||
4. Увеличивается серия участника
|
||||
5. Все pending BonusAssignments удаляются (больше нельзя выполнить)
|
||||
6. Статус → COMPLETED
|
||||
|
||||
### Бонусный челлендж
|
||||
|
||||
```
|
||||
POST /marathons/{id}/assignments/{assignment_id}/bonus/{challenge_id}/complete
|
||||
```
|
||||
|
||||
1. Доступно только пока основное задание ACTIVE
|
||||
2. Загрузить пруф бонусного челленджа
|
||||
3. BonusAssignment.status → COMPLETED
|
||||
4. Очки накапливаются в BonusAssignment.points_earned
|
||||
5. **Очки НЕ добавляются сразу** — добавятся при завершении основного задания
|
||||
|
||||
**Исключение:** Если main assignment уже COMPLETED (перепрохождение после диспута), очки добавляются сразу.
|
||||
|
||||
---
|
||||
|
||||
## Фильтрация игр для спина
|
||||
|
||||
### Функция `get_available_games_for_participant`
|
||||
|
||||
```python
|
||||
for game in approved_games:
|
||||
if game.game_type == "playthrough":
|
||||
# Исключить если есть COMPLETED или DROPPED assignment
|
||||
if has_finished_playthrough(participant, game):
|
||||
continue
|
||||
else: # challenges
|
||||
# Исключить если ВСЕ челленджи выполнены
|
||||
if all_challenges_completed(participant, game):
|
||||
continue
|
||||
|
||||
available.append(game)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Система очков
|
||||
|
||||
### Челлендж
|
||||
|
||||
```
|
||||
base_points = challenge.points
|
||||
modifier = event_modifier (если есть активное событие)
|
||||
total = base_points × modifier
|
||||
```
|
||||
|
||||
### Прохождение
|
||||
|
||||
```
|
||||
base_points = game.playthrough_points
|
||||
bonus_points = sum(bonus.points_earned for bonus in completed_bonuses)
|
||||
total = base_points + bonus_points
|
||||
```
|
||||
|
||||
**События НЕ влияют на очки за прохождение.**
|
||||
|
||||
---
|
||||
|
||||
## Дроп задания
|
||||
|
||||
### Челлендж
|
||||
|
||||
- Штраф в очках (зависит от настроек марафона)
|
||||
- Серия обнуляется
|
||||
- Игра остаётся доступной (можно получить другой челлендж)
|
||||
|
||||
### Прохождение
|
||||
|
||||
- Штраф в очках
|
||||
- Серия обнуляется
|
||||
- **Игра исключается из спина навсегда**
|
||||
- Все BonusAssignments удаляются
|
||||
|
||||
---
|
||||
|
||||
## Диспуты
|
||||
|
||||
### Оспаривание прохождения
|
||||
|
||||
Если диспут признан недействительным:
|
||||
1. Assignment → RETURNED
|
||||
2. Вычитаются все очки (прохождение + бонусы)
|
||||
3. Серия обнуляется
|
||||
4. Все BonusAssignments сбрасываются в PENDING
|
||||
|
||||
### Оспаривание бонуса
|
||||
|
||||
Если диспут признан недействительным:
|
||||
1. BonusAssignment → PENDING
|
||||
2. Вычитаются очки бонуса
|
||||
3. Proof данные очищаются
|
||||
4. Можно попробовать выполнить заново
|
||||
|
||||
---
|
||||
|
||||
## API эндпоинты
|
||||
|
||||
| Метод | Путь | Описание |
|
||||
|-------|------|----------|
|
||||
| POST | `/marathons/{id}/spin` | Крутить колесо |
|
||||
| POST | `/marathons/{id}/complete-assignment` | Завершить основное задание |
|
||||
| POST | `/marathons/{id}/assignments/{id}/bonus/{challenge_id}/complete` | Завершить бонус |
|
||||
| GET | `/marathons/{id}/available-games` | Список доступных игр |
|
||||
| GET | `/marathons/{id}/available-games-count` | Количество доступных игр |
|
||||
|
||||
---
|
||||
|
||||
## Схема работы
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ СПИН │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┴───────────────┐
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ PLAYTHROUGH │ │ CHALLENGES │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Assignment │ │ Assignment │
|
||||
│ game_id = X │ │ challenge_id │
|
||||
│ is_playthrough │ │ = X │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
▼ │
|
||||
┌─────────────────┐ │
|
||||
│ BonusAssignment │ │
|
||||
│ × N (по числу │ │
|
||||
│ челленджей) │ │
|
||||
└─────────────────┘ │
|
||||
│ │
|
||||
├───────────────────────────────┤
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ COMPLETE │
|
||||
│ • Загрузка пруфа │
|
||||
│ • Начисление очков │
|
||||
│ • Увеличение серии │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
Reference in New Issue
Block a user