Files
QuizPlease/Agent/TASK.md
T
horooko 6c46b3043a feat: add agent tasks and update documentation
- Create 7 new task files (TASK-0001 through TASK-0007)
- Add task template file for future use
- Update Agent.md with project information
- Update TASK.md with task tracking
2026-05-27 03:36:25 +07:00

217 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задача: Unity / C# Middle
## Кратко
Нужно реализовать загрузочный поток приложения в Unity через собственную state machine.
Проект создается с нуля. Базовые абстракции, сервисы, View/ViewModel и state machine нужно написать самостоятельно, потому что это часть оценки.
Ориентировочное время выполнения: около 1,5 часов. Если ушло больше или меньше времени, это нормально, но нужно честно указать это в документации.
## Технические требования
- Unity 2022 LTS+.
- C#.
- Использовать VContainer, UniTask и UniRx.
- Опционально можно использовать Odin Inspector и DOTween.
## Архитектурные требования
### Reactive
Использовать UniRx для реактивных значений и подписок.
Если дополнительно понадобится собственная обертка `ReactiveValue<T>`, она должна поддерживать сигнатуру подписки:
```csharp
IDisposable Subscribe(Action<T> cb, bool invokeImmediately = true)
```
Требования:
- каждая подписка должна корректно диспозиться;
- нельзя использовать голые `event Action` без отписки.
### Async
Все async-операции должны быть реализованы только через UniTask и `CancellationToken`.
Запрещено использовать `async void`, кроме Unity-колбэков.
### Dependency Injection
Использовать VContainer.
Все сервисы регистрируются как интерфейсы:
```csharp
builder.Register<Impl>(Lifetime.Singleton).As<IInterface>();
```
Запрещено использовать:
- `FindObjectOfType`;
- `Singleton.Instance`;
- `static`-хранилища состояния.
### UI
Нужно сделать базовую пару View/ViewModel:
```csharp
public class UIView : MonoBehaviour
{
public virtual void Initialize() { }
public virtual void Release() { }
}
public class UIView<TVm> : UIView where TVm : IUIViewModel
{
}
```
Требования:
- ViewModel должна быть обычным C#-классом, не `MonoBehaviour`;
- логика находится во ViewModel;
- View хранит только Unity-ссылки и биндинги.
### Services
Сервисы должны иметь асинхронный жизненный цикл:
```csharp
UniTask InitializeAsync(CancellationToken ct)
UniTask ReleaseAsync(CancellationToken ct)
```
Требования:
- сервисы оформляются как `Service : IService`;
- фоновые циклы стартуют в `InitializeAsync`;
- фоновые циклы останавливаются через `CancellationTokenSource.Cancel()` в `ReleaseAsync`.
### Config
Конфиги должны быть `ScriptableObject` с суффиксом `*Settings`.
Регистрация в `LifetimeScope`:
```csharp
[SerializeField] private SomeSettings _settings;
protected override void Configure(IContainerBuilder builder)
{
builder.RegisterInstance(_settings);
}
```
## Задача: Boot Flow
Реализовать загрузочный поток приложения через собственную state machine из трех состояний.
### 1. База state machine
Нужно реализовать собственные абстракции:
- `IState`;
- `IStatesController<TEnum>`;
- `StatesController<TEnum>`.
В `StatesController<TEnum>` должен быть метод:
```csharp
UniTask EnterStateAsync(TEnum code, CancellationToken ct)
```
Контракт перехода между состояниями:
```csharp
await currentState.ExitAsync(ct);
await newState.EnterAsync(ct);
```
Требования:
- `CancellationToken` пробрасывается через всю цепочку вызовов;
- `CancellationToken` должен реально отменять внутренние ожидания;
- повторные входы в состояния не должны ломать UI и подписки.
### 2. Состояния
Нужно реализовать три состояния.
#### SplashState
Поведение:
- показывает лого;
- ждет 1 секунду через `UniTask.Delay(..., ct)`;
- переходит в следующее состояние.
#### LoadState
Поведение:
- имитирует загрузку;
- выполняет 5 шагов по 200 мс;
- хранит `ReactiveValue<float> Progress` со значением от `0` до `1`;
- обновляет `Progress` после каждого шага.
#### MenuState
Поведение:
- показывает `MenuUIView`;
- содержит одну кнопку `Restart`;
- по клику на `Restart` возвращает приложение в `LoadState`.
### 3. UI
Нужно реализовать `LoadingUIView`.
Требования:
- `LoadingUIView` подписывается на `LoadState.Progress`;
- прогресс-бар обновляется через DOTween или ручной Lerp;
- при `ExitAsync` все подписки должны корректно очищаться;
- при повторном входе в `LoadState` не должно быть `NullReferenceException` и дублирующихся подписок.
## Что сдать
- GitHub-репозиторий или zip-архив без `Library/`, `Temp/`, `obj/`.
- `README.md` с инструкцией запуска.
- В `README.md` добавить 5-10 строк о том, что было бы доделано при наличии еще 2 часов.
- `SELF_NOTES.md` с описанием собственных решений.
- `AI_LOG.md` с описанием использования AI. Если AI не использовался, нужно написать почему.
## SELF_NOTES.md
В `SELF_NOTES.md` нужно своими словами описать:
- какие идеи были рассмотрены и почему выбрана текущая реализация;
- какие места в коде были придуманы и написаны самостоятельно, без AI;
- что в коде понятно до последней строки;
- что осталось непонятным или воспринимается как магия;
- ответы на 2-3 ключевых вопроса вида: почему здесь сделано именно так.
## AI_LOG.md
В `AI_LOG.md` нужно описать:
- какие промпты использовались;
- где AI ошибся;
- что было переписано руками;
- если AI не использовался, почему было принято такое решение.
## Что не требуется
Не нужно тратить время на:
- красивый арт;
- сложные анимации;
- звук;
- мобильную сборку.
Главное: архитектурные слои, стиль кода, корректная работа жизненного цикла и понимание собственных решений.