Розробка мобільного додатку для онлайн-шахів
Створюєте шаховий додаток і зіткнулися з розсинхроном ходів, суперечками щодо таймера або інтеграцією AI? Ми вирішуємо ці задачі на iOS, Android та Flutter вже багато років. Головна технічна складність — синхронізація стану партії між двома клієнтами в реальному часі з мінімальною затримкою та коректною обробкою таймера. Без продуманої архітектури гравці зіткнуться з розсинхроном, «залипанням» ходів та несправедливим таймінгом. WebSocket — єдиний підхожий протокол для обміну ходами; HTTP polling дає затримки та зайвий трафік. На iOS використовуємо URLSessionWebSocketTask, на Android — OkHttp WebSocket, на Flutter — web_socket_channel. Клієнт надсилає хід у UCI-нотації (e2e4), сервер валідує позицію та розсилає оновлення обом гравцям. Вся перевірка легальності — на сервері.
Як синхронізувати ходи в реальному часі?
WebSocket — єдиний підхожий протокол. HTTP polling дає затримки та зайвий трафік. На iOS використовуємо URLSessionWebSocketTask (нативний), на Android — OkHttp WebSocket, на Flutter — web_socket_channel. Протокол обміну: клієнт надсилає хід у UCI-нотації (e2e4), сервер валідує позицію та розсилає оновлення обом гравцям. Клієнт не довіряє собі в легальності ходу — всю перевірку робить сервер. Інакше модифікований додаток може робити нелегальні ходи.
// Android — надсилання ходу webSocket.send(Json.encodeToString(MoveMessage( gameId = currentGameId, move = "e2e4", remainingTimeMs = timerViewModel.whiteTimeMs ))) При розриві з'єднання клієнт переходить на HTTP polling кожні 2 секунди та намагається реконнект з exponential backoff. Партія триває — гравець з поганим з'єднанням не втрачає час автоматично.
Чому таймер має бути на сервері?
Таймер — джерело суперечок в онлайн-шахах. Якщо тримати його лише на клієнті, недобросовісний гравець може сповільнити свій таймер. Правильна схема: сервер зберігає white_remaining_ms та black_remaining_ms, оновлює при кожному ході та надсилає актуальні значення клієнтам. Клієнт відображає таймер (анімація зменшення), але не є джерелом істини. При реконнекті клієнт запитує поточний стан і синхронізує відображення.
Технології рендеру дошки
Для нативних додатків використовуємо Canvas API (Android) або CAShapeLayer + CALayer (iOS). Анімація ходу — переміщення ImageView/UIImageView через ValueAnimator / UIView.animate. У Flutter — кастомний CustomPainter з Canvas.drawImage для фігур. Фігури у форматі SVG конвертуються в растрові зображення під різні роздільності — це дозволяє перефарбовувати їх для різних тем.
Шаховий двигун для гри з AI
Stockfish — стандарт індустрії, відкритий, найсильніший. Компілюється як C++ бібліотека для iOS, через JNI для Android або через пакет stockfish для Flutter. Глибина пошуку керується UCI-командами: setoption name Skill Level value 10 (0–20), go movetime 1000. Аналіз позиції виконується в окремому потоці, щоб не блокувати UI. Налаштування двигуна дозволяють адаптувати складність: на рівні 0 він допускає грубі помилки, на 20 — грає на рівні гросмейстера.
Рейтинг Ело та матчмейкінг
Формула Ело: newRating = oldRating + K * (score - expectedScore). K = 32 для нових гравців, 16 для досвідчених. Матчмейкінг шукає суперника в діапазоні ±100 Ело з таймаутом розширення кожні 10 секунд. Черга зберігається в Redis Sorted Set, score = timestamp постановки. При пошуку обирається найближчий за рейтингом учасник. Алгоритм гарантує, що час очікування рідко перевищує 30 секунд при 500 одночасних гравцях.
Порівняння платформ: продуктивність та затримки
| Компонент | iOS (Swift) | Android (Kotlin) | Flutter (Dart) |
|---|---|---|---|
| WebSocket | URLSessionWebSocketTask | OkHttp WebSocket | web_socket_channel |
| Таймер | Server-sync | Server-sync | Server-sync |
| Двигун | Stockfish (C++) | Stockfish (JNI) | Stockfish (native plugin) |
| Рендер | CAShapeLayer | Canvas | CustomPainter |
| Затримка (p95) | < 50 ms | < 60 ms | < 80 ms (на старих пристроях) |
Нативний додаток на Swift/Kotlin дає на 20% менше затримок порівняно з Flutter на пристроях 5-річної давності. Для сучасних флагманів різниця несуттєва. Це підтверджують наші тести на iPhone 8 та Samsung Galaxy S9.
Як масштабувати додаток під тисячі гравців?
Архітектура побудована на мікросервісах: матчмейкінг, синхронізація та рейтинг винесені в окремі сервіси. База даних на PostgreSQL з шардуванням по games.id. Redis використовується для черг та кешу. WebSocket-сервер на Node.js з кластеризацією — для горизонтального масштабування. Це дозволяє витримувати тисячі одночасних партій без втрати продуктивності. Деталі архітектури
Ми використовуємо Kubernetes для оркестрації сервісів. Кожен сервіс має окремий балансувальник. WebSocket-сервер працює на кількох подах з загальним Redis pub/sub для розсилки ходів. Це дає відмовостійкість та лінійне масштабування.
Що входить в роботу
- Архітектурна документація (діаграми потоків, схеми БД).
- Вихідний код з Unit-тестами.
- Інтеграція з App Store Connect / Google Play Console.
- Інструкція по деплою та моніторингу.
- Навчання команди замовника (1–2 дні).
- Технічна підтримка 3 місяці після релізу.
Орієнтовні терміни
| Функціонал | Терміни |
|---|---|
| Гра проти AI (Stockfish) | 4–5 тижнів |
| Онлайн-гра + таймер | 6–8 тижнів |
| Матчмейкінг + рейтинг | 2–3 тижні |
| Повний додаток | 8–12 тижнів |
Чому варто замовити у нас
Наша команда має понад 8 років досвіду в мобільній розробці та більше 15 реалізованих проєктів у сфері онлайн-ігор. Використовуємо лише перевірені технології: WebSocket, Stockfish, нативні API. Оптимізація витрат — до 30% економії порівняно з розробкою власного двигуна. Ми пропонуємо розробку під ключ: від прототипу до публікації в сторах. App Store Review Guidelines (Section 4.2, 5.1) — наші інженери знають їх напам'ять.
Зв'яжіться з нами, щоб обговорити ваш проєкт. Отримайте консультацію з архітектури та оцінку вартості. Ми гарантуємо прозорість на кожному етапі. Замовте демонстрацію нашого підходу на реальному проєкті.







