Нам часто заказывают мобильные симуляторы — от фермерских таймерных игр до полноценных физических симуляций транспорта или строительства. Объединяет их одно: сложные взаимосвязанные системы, которые должны работать согласованно и обеспечивать «живое» ощущение мира даже при закрытом приложении. Мы разрабатываем такие проекты под ключ: от концепта до релиза в сторах.
Как обеспечить офлайн-прогрессию без потери данных?
Главная техническая особенность симуляторов — offline progression. Игрок возвращается через 8 часов, и за это время должны были произойти события: созрели культуры, выработались ресурсы, завершились производственные цепочки.
Наивный подход — при открытии игры запустить цикл с шагом deltaTime и посчитать всё с момента последнего сохранения. Это работает для простых систем. При сложных взаимозависимостях (ресурс A нужен для производства B, B нужен для C, и у A может закончиться запас в середине периода) — нужна дискретная симуляция с фиксированным тиком.
Реализация: сохраняем lastTickTimestamp. При открытии вычисляем missedTicks = (now - lastTick) / tickInterval. Запускаем симуляцию на missedTicks шагов с tickInterval (например, 1 минута). Каждый тик — детерминированный: применяем производство, потребление, события. Ограничение: maxOfflineTicks (например, 8 часов = 480 тиков), остальное — теряется или накапливается в overflow buffer.
| Метод | Сложность | Производительность | Подходит для |
|---|---|---|---|
| Простой цикл на открытии | Низкая | Высокая | Простые линейные процессы |
| Дискретная симуляция с тиками | Средняя | Средняя | Взаимозависимые цепочки |
| Гибридный (тики + триггеры) | Высокая | Низкая | Очень сложные системы с event-driven |
Для игр с рыночной экономикой (цены меняются каждые 15 минут) используем гибридный подход: тики для базового производства и отдельные события для внешних воздействий. Это снижает нагрузку на процессор на 30% по сравнению с полной симуляцией.
Физика в транспортных и строительных симуляторах
Для физических симуляторов (автобус, кран, дорожное строительство) в Unity используем Configurable Joint для сложных сочленений + Rigidbody.AddForceAtPosition для физически корректного управления. Стандартные WheelCollider хороши для базовой автомобильной физики, но для нестандартных транспортных средств их limitations быстро появляются.
Важно: физические симуляторы с большим количеством Rigidbody (30+) на сцене требуют настройки Physics.simulationMode. Использование SimulationMode.Script (ручной вызов Physics.Simulate(fixedDeltaTime)) даёт точный контроль над порядком шагов — критично когда физика сочетается с игровой логикой.
На Android физика с Vulkan и ARMv8 — значительно быстрее из-за NEON SIMD оптимизаций в PhysX. Если таргет — low-end Android с OpenGL ES 3.0, ограничивай количество активных rigidbody через Sleep Threshold и Rigidbody.IsSleeping().
| Параметр | Vulkan / ARMv8 | OpenGL ES 3.0 / ARMv7 |
|---|---|---|
| Скорость физики | Высокая (NEON SIMD) | Средняя (без NEON) |
| Макс. активных Rigidbody | 60+ | 30 |
| Рекомендуемый simulationMode | Automatic или Script | Script с ручным управлением |
Почему агентная модель подходит для менеджмент-симуляторов?
Для симуляторов типа «тайкун» (ресторан, аэропорт, больница) — агентная модель. Каждый NPC — автономный агент с Behaviour Tree или Utility AI. Unity NavMesh Agent для перемещения, кастомная система задач для действий (взять заказ, принести, убрать).
При большом количестве агентов (50+) переходим на ECS-based agents через Unity DOTS: позиции и состояния в NativeArray, путём вычисляем через Job System. Unity DOTS — официальный пакет для работы с ECS. NavMesh Agents на DOTS пока в preview, но для 2D изометрических симуляторов своя тайловая навигация через A* Pathfinding Project (Aron Granberg) даёт лучший результат.
Пример: поведение официанта в симуляторе ресторана
Агент: официант. Behaviour Tree: - Принять заказ (перейти к столу, получить заказ) - Доставить заказ на кухню (перейти к кухне, передать заказ) - Забрать готовые блюда (перейти к раздаче, взять поднос) - Подать блюда клиентам (перейти к столу, отдать поднос) - Убрать посуду (перейти к столу, забрать тарелки) Параллельно: если свободен — принять новый заказ. Если клиент ушёл без оплаты — вызвать менеджера.Сохранение сложного состояния
Симуляторы с сотнями объектов и их состояниями — это сотни килобайт данных сохранения. JsonUtility Unity не справляется со сложными графами объектов. Используем Newtonsoft.Json (com.unity.nuget.newtonsoft-json) с кастомными конвертерами или MemoryPack для бинарной сериализации (быстрее в 5–10 раз для больших объёмов). Newtonsoft.Json — де-факто стандарт для .NET.
Автосохранение через UniTask.Delay на фоновом потоке — сериализация в Task.Run, запись на диск в UniTask.SwitchToMainThread минимальным способом. Крэш во время записи не должен портить существующее сохранение — пишем во временный файл, затем атомарно переименовываем.
Что входит в работу
- Концепт-документ с описанием архитектуры и метрик.
- Прототип ключевой механики (офлайн-симуляция, физика, агенты).
- Полный код с комментариями и README.
- Инструкция по сборке (build для iOS/Android).
- Поддержка после релиза — баг-фиксинг, оптимизация, обновления под новые версии ОС.
Сроки и стоимость
Сроки разработки: от 4 месяцев для простых симуляторов до 15 месяцев для сложных проектов с физикой. Стоимость рассчитывается индивидуально — свяжитесь с нами, чтобы мы оценили ваш проект за 2 дня.
Мы занимаемся мобильной разработкой 7+ лет, выпустили 15 проектов в App Store и Google Play. Обращайтесь — обсудим детали вашего симулятора. Получите консультацию по вашему проекту прямо сейчас.







