Сопствен производ · Carrom

Вистинска карома, со физика што ја напишавме сами.

Carrom е игра на табла првенствено за телефон, на дрвена табла со прецизна физика на дисковите. Има пет типа игра, меѓу нив 29 Game и Tal Gach што се играат низ Бангладеш, Индија и Пакистан, со онлајн 1 против 1 и 2 против 2, ботови и додавање и играње. Една TypeScript кодна база работи на веб, Android и iOS, а онлајн играта работи на сопствен сервер во реално време.

Во живо на веб, на App Store (iPhone и iPad) и на Google Play (Android).

  • Web (PWA)
  • Android
  • iOS
  • iPadOS
типа игра, секој со свој engine за правила
5
удари, бит по бит идентични во сите прелистувачки engine-и
4.320
автоматски тестови: 396 unit и 150 тестови во прелистувач, секој прелистувачки тест на три големини на екран
540+
прво вчитување на забавен Fast 3G
≤ 3 s

Во апликацијата

Вистински екрани од апликацијата што е во употреба, како што се појавуваат во описите во продавниците.

Што добиваат играчите

  • Пет типа игра

    Classic, 29 Game (прв до 29), Tal Gach (разбијте кула од 19 фигури, прв до 170), Disc Pool и Freestyle, плус дневен предизвик и упатство.

  • Онлајн 1 против 1 и 2 против 2

    Quick Match по рејтинг, со ботови што ги пополнуваат празните места, приватни соби, врски за предизвик што ја отвораат апликацијата, лоби со отворени соби, реванш, емотикони, часовник од 20 секунди по потег и Elo рејтинг за секој тип игра.

  • Ботови и додавање и играње

    Ботови во 4 нивоа на тежина (од Лесен до Експерт) и 4 личности (избалансиран, агресивен, одбранбен, трик-удар), секој со свое име и знаме, и додавање и играње за 2 или 4 играчи на еден уред.

  • Напредок што ве следи

    Монети, продавница со анимирани табли, ударачи и сетови фигури, достигнувања, статистики и дневни серии. Најавете се со Google или Apple за да го чувате на сите уреди.

  • Алатки за оператор

    Нашиот админ-панел покажува партии и играчи во живо, води модерација, ги менува монетите на кој било играч со порака до него и менува реклами, задолжителни ажурирања, барања за оцена, прекинувачи за спарување па дури и изглед без ново издание на апликацијата.

  • Насекаде од една кодна база

    Веб, Android, iPhone и iPad од една кодна база и може да се инсталира како веб-апликација. Врските до соби ја отвораат апликацијата ако е инсталирана, а во спротивно веб-играта.

Изградено од нула

Секој слој е наш, од правилата на играта до серверот на кој работи.

  1. Клиент на играта

    Строг TypeScript, Vite и Canvas 2D, без game engine и без UI framework. Вртливите табли и прегледите на кулата во Tal Gach се чист CSS 3D.

    • TypeScript
    • Vite
    • Canvas 2D
    • CSS 3D
  2. Наша сопствена физика

    Физика на дисковите водена од настани со фиксен чекор од 1/120 s, независна од бројот на слики во секунда: челусти на џебовите, фигура што паѓа само кога доволен дел од неа е над дупката, излетување од џебот и кула што се распаѓа. Замени општа библиотека за физика.

    • Deterministic
    • Seeded randomness
    • Headless tests
  3. Backend во реално време

    Наш сопствен Node сервер на MongoDB, што зборува мал JSON-преку-WebSocket протокол: get, set, compare-and-set, watch и presence. Ја проценува истата датотека со безбедносни правила што би ја користел Firebase Realtime Database.

    • Node.js
    • MongoDB
    • WebSocket
    • esbuild
  4. Апликации и најава

    Capacitor апликации за Android и iOS. Најавата со Google и Apple минува преку Firebase Auth, а нашиот сервер самиот го проверува секој токен. Рекламите доаѓаат од AdMob, без купувања со вистински пари.

    • Capacitor
    • Firebase Auth
    • AdMob
    • App Links

Операции

Ги водиме серверите сами

Без сервис за game backend помеѓу: наш сопствен сервер, наши сопствени распоредувања, наш сопствен мониторинг.

  • Наш сопствен Linux сервер: nginx ја опслужува играта со Let’s Encrypt TLS зад Cloudflare
  • WebSocket, конфигурацијата на апликацијата и проверките на здравјето се проксираат до Node сервисот под systemd
  • Админ-панелот работи како посебен сервис и повикува API за оператор што одговара само на самата машина
  • Распоредување со една команда: билд, качување на издание со временски печат, префрлање, рестарт, проверка на здравјето; последните 5 изданија се чуваат за веднаш враќање
  • Околу 210 ms медијана на пат туркај-врати од Бангладеш преку Cloudflare (измерено при лансирањето)
  • Скриптирани билдови на апликацијата за Google Play и App Store Connect
  • Android App Links и iOS universal links за покани во соби

Тешки проблеми што ги решивме

Деловите што играчите никогаш не ги гледаат, со броевите што ги измеривме.

  1. Иста физика на секој телефон

    Проблемот
    Во онлајн игра секој телефон самиот го симулира ударот на противникот. Ако два уреда некогаш пресметаат еден број различно, таблите би се разминале, па физиката мораше да биде прецизна насекаде.
    Што направивме
    Симулацијата користи само операции што се точни на секој JavaScript engine, со наши сопствени hypot, log, acos, sin и cos засновани на квадратен корен. Целата случајност е со seed, а јадрото никогаш не го чита часовникот.

    Резултат 4.320 удари проверени во engine-ите на Chromium и WebKit: секоја табла бит по бит идентична.

  2. Десинхронизација, пронајдена и оградена

    Проблемот
    Играчи со различни верзии на апликацијата, со малку различна физика, се спарувале заедно и нивните табли не се совпаѓале.
    Што направивме
    Верзија на протоколот сега го условува спарувањето и собите, а тест со отпечаток на физиката го прекинува билдот ако физиката се промени без да се зголеми верзијата.

    Резултат Само играчи со идентична физика некогаш делат табла.

  3. Кула што се распаѓа праведно

    Проблемот
    Во Tal Gach отворачкиот удар погодува наредена кула од 19 фигури. Мора да се чувствува како вистинско и да биде праведен кон двајцата играчи.
    Што направивме
    Удар со 70% брзина или повеќе исфрла една или две долни фигури и ја остава кулата да стои; послабите удари ја превртуваат. Случајноста е со seed, па сите уреди го гледаат истото распаѓање.

    Резултат Силните удари ги чистат долните фигури во 90% од случаите, исто на секој екран.

  4. Звук на Mac

    Проблемот
    Апликацијата за iPad што работи на Mac со Apple silicon не можеше да декодира ниту AAC ниту Opus звук.
    Што направивме
    Апликацијата вклучува 16-битни WAV копии на звуците и музиката, а играта сама ги декодира.

    Резултат Ист звук на секој уред, Mac вклучени.

  5. Напуштање на доставувач без допирање на играта

    Проблемот
    Онлајн играта почна на Firebase Realtime Database, а сакавме податоците на играта да бидат на наш сервер без да ја препишуваме играта.
    Што направивме
    Секоја онлајн функција зборува со еден интерфејс на базата. Нашиот сервер ја спроведува истата датотека со правила со иста семантика, а еден сет проверки од цели натпревари и повеќе од 180 дозволени или одбиени запишувања се извршува против двата backend-а.

    Резултат Податоците на играта сега се на наш сервер, а префрлањето меѓу backend-ите е прекинувач од две поставки во билдот.

  6. Брзо до првиот удар

    Проблемот
    Лежерната игра има секунди да го придобие играчот, често на бавна мобилна врска.
    Што направивме
    Без engine или framework за преземање, без звук пред првиот допир и тест на перформанси што го извршува производниот билд на забавена врска.

    Резултат Прво вчитување за 3 s или помалку на забавен Fast 3G.

Тестирано како производ, не како демо

  • 396 unit тестови и 150 тестови во прелистувач, секој извршен на големина на телефон, таблет и десктоп со базни слики од екран (над 400 извршувања)
  • Извршувања за баланс бот против бот и monkey тест
  • Сет на емулатор што игра цели онлајн натпревари против правилата на базата
  • Удари симулирани без екран во unit тестови, благодарение на детерминистичката физика

Технологија

  • TypeScript
  • Vite
  • Canvas 2D
  • Node.js
  • MongoDB
  • WebSocket
  • Capacitor
  • Firebase Auth
  • AdMob
  • Vitest
  • Playwright
  • nginx
  • Cloudflare
  • systemd

GPScom: целосен редизајн на gpscom.gr

Сите наши проекти

Сакате игра или апликација во реално време изградена вака?

Дизајнираме, градиме и водиме игри и платформи во реално време од почеток до крај: апликации, сервери, продавници и операции.