Существует немало игр, которые сообщество регулярно поддерживает модификациями. Для нежно любимой мной Fallout: New Vegas, модификации выходят и спустя шесть лет после окончания поддержки. Для каких-то других игр (привет, EVE!), люди ведут “гугловые” таблички, а для еще одних — просто пишут подробные гайды или рисуют небольшие схемы.

Я же расскажу вам про игру, ради которой в сообществе делают всё вышеперечисленное и даже больше, об Elite: Dangerous.


Elite Dangerous — это, изначально синглплеерный, а позднее, “обросший” мультиплеерной частью, космический симулятор, где можно:

  • Сражаться. С пиратами, с другими фракциями, с гражданскими, либо разом со всеми. Главное, что это прикольно! Игра очень хорошо передает ощущение того, что ты, как бы, в кабине сотнетонной махины посреди пустоты космоса, со всеми вытекающими.

  • Исследовать. Во-первых, в Элите сгенерирован (и довольно дотошно) весь Млечный Путь, в масштабе 1:1. Звёздные системы на сервере отрабатывает очень здоровский движок, Stellar Forge, который способен выдавать адекватные характеристики планет, на логичном расстоянии от звёзд, с нормальным ландшафтом, а совсем скоро, на планеты также добавится и атмосфера. Ну, и звездные системы не пустые, в разных регионах Млечного Пути встречаются свои аномалии и иные интересные объекты.
    Во-вторых, в игре можно исследовать древние руины и, скажем прямо, “офигевать”. В игре есть инопланетяне, аж две расы. Они, по своему, опасные, с ними нелегко воевать (но у некоторых получается), поэтому я, например, просто изучаю их, не вступая в прямые контакты.

  • Зарабатывать на подрыве астероидов и добыче ископаемых, на перевозке пассажиров, на выполнении рутинных внутрисистемных заданий.

  • Играть за какое-то сообщество, которых в игре много: исследовать расы Стражей и Таргоидов и расшифровывать их загадки в команде Canonn, мочить террористов в сортире и присоединять исторические родины во фракции Юрия Грома или иных галактических Сил (Сила в игре -- это сверхдержава со всеми атрибутами власти). Или оборонять системы от пришельцев, строить кластер союзников, развивать техническое оснащение, облагораживать все вокруг дипломатией и научным обменом, чем, например, занимается наша тусовка - Close Encounters Corps.

  • Заниматься всем вышеперечисленным, чтобы потом уйти на пенсию и валяться в джакузи, где-нибудь на роскошной Orca, либо почетно управлять по-имперски изящным Imperial Cutter.

Это все игра. А теперь, разумеется, о технологиях.

Сервисы

Во-первых, для нужд игроков есть официальный Frontier OAuth, который представляет из себя точку авторизации плюс несколько эндпоинтов для получения данных о командире. Типа, пользователь заходит туда своими доступами от игровой учётки, и вы получаете список его кораблей.
Официальная инструкция
Пример кода на Ktor (веб-фреймворк для Kotlin)

val FRONTIERSTORE_URL = "https://auth.frontierstore.net"
val settings = OAuthServerSettings.OAuth2ServerSettings(
   name = "frontier",
   authorizeUrl = "$FRONTIERSTORE_URL/auth",
   accessTokenUrl = "$FRONTIERSTORE_URL/token",
   requestMethod = HttpMethod.Post,
   clientId = "...",
   clientSecret = "...",
   defaultScopes = listOf("auth", "capi")
)
class CompanionAPI(val authType: String, val token: String) {
   val baseUrl = "https://companion.orerve.net"

   suspend fun getProfile(): JsonNode {
       val rawValue = get("/profile")
       val value = readJson(rawValue)
       return value
   }    

   suspend fun getFleetCarrier(): JsonNode {
       val rawValue = get("/fleetcarrier")
       val value = readJson(rawValue)
       return value
   }    

   private suspend fun get(url: String): String {
       return http.get(baseUrl + url) {
           header(HttpHeaders.Authorization, "$authType $token")
       }    
   }    
}

В 2015-м, спустя год после выхода игры, появился неигровой каталог практически всех звездных систем, назван он был EDSM. Сегодня это больше, чем каталог, у него есть подробные данные о системах, как населённых, так и не очень, можно строить свои маршруты, планы по исследованиям регионов, а ещё у него есть REST API.
https://www.edsm.net
Пример использования (httpie):

$ http https://www.edsm.net/api-v1/system 'systemName=HIP 74258' showCoordinates=1

{
    "coords": {
        "x": 112.4375,
        "y": 70.4375,
        "z": 206.65625
    },
    "coordsLocked": true,
    "name": "HIP 74258"
}

EDDB. Исчерпывающий каталог по населённым системам с удобным интерфейсом поиска товаров, оборудования и не только. Ещё позволяет строить торговые маршруты. Из API есть только полные JSON-дампы по разным категориям: товары и их средняя стоимость, системы, станции, фракции, и прочее. Что-то из дампов весит несколько сотен килобайт, а какие-то другие достигают около шести гигов. Код, увы, закрытый.
https://eddb.io

Colonia Region Systems Database. Каталог, сфокусированный на далеко расположенном аванпосте человечества — Колонии.
https://cdb.sotl.org.uk

Inara. Компаньон, социальная сеть для командиров и участников фракций, где находится всякая информация о пилотах, их имуществе, журнале полётов и заданий, и прочем. Я там часто зависаю чтобы понять, где у нашей фракции проседает влияние.
https://inara.cz
https://inara.cz/inara-api/

EDMarketConnector. Вот кто-то из вас, может быть, задумался, а откуда все эти сервисы берут данные? Ответ: ПК-игроки летают с включенным EDMC, это утилита на Python, которая парсит JSON-логи игры и отдаёт их доп.плагинам, а те, в свою очередь, отправляют то, что им надо, на API EDSM, INARA и EDDN, о котором сейчас и поговорим. Инструмент написан на Python 3, интерфейс на tkinter, код есть на гитхабе в свободном доступе.
https://github.com/EDCD/EDMarketConnector

EDDN. Сердцевина сети технического сообщества Elite. Принимает данные от EDMC и подобных ему систем, обезличивает их, и шлёт подписчикам. Я работал немного с его API, там ZeroMQ и JSON со схемой. Короче, по-человечески сделано, батя грит малаца. Код открыт, Python 3 и фронт на JS.
https://eddn.edcd.io
https://github.com/EDCD/EDDN

Coriolis и ED Shipyard. Сайты-конструкторы кораблей. Полезная в хозяйстве штука, особенно если вы хотите понять, налезет ли на ваш корабль восьмой пучковый лазер, какой вам нужен распределитель питания, какую скорость вы сможете развить с 180 тоннами груза в грузовых стеллажах и вообще, во сколько вам это всё обойдётся. Код открыт, оба инструмента на JavaScript, ибо фронт.
https://coriolis.io https://github.com/EDCD/coriolis
https://edsy.org https://github.com/EDCD/EDSY

EDDiscovery. Приложение, похожее немного на EDMC, однако сконцентрировано оно на исследовательском функционале: карта регионов, оптимальные маршруты с учётом топливного бака корабля, и прочее. Написано на C#, код открыт.
https://github.com/EDDiscovery/EDDiscovery

VoiceAttack. Если вам надоест управлять кораблём руками — попробуйте голосом! Ставите VA, платите денюжку ($10) и наслаждайтесь погружением в игру.
https://voiceattack.com

FCMS. Если у вас есть лишние миллиарды кредитов, вы можете приобрести в игре целый корабль-носитель, фактически личную передвижную станцию, и возить на нём свои корабли и корабли всех своих друзей. А с этим сервисом, вы сможете смотреть информацию по этому флотоносцу и интегрироваться с другими сервисами. Написан на Python, фронт на JS.
https://github.com/FuelRats/FCMS

Если вы ничего не поняли, то вот схема: EDMC и EDDiscovery зондируют логи игры, EDDN их отправляет на сервера EDDB, EDSM, INARA и не только, также, скажем, INARA берёт данные напрямую из EDMC, чтобы получать исчерпывающую информацию об игроке.

То есть вариантов анализа данных множество. Можно, например, периодически выгружать дампы из EDDB и подпитываться актуальными данными с EDDN, можно пользоваться API EDSM, а можно написать плагин для EDMC и иногда поглядывать на другие ресурсы, как мы и сделали.

Как сделали мы?

Когда я пришёл в команду Close Encounters Corps летом 2020, у нас был только навороченный плагин для EDMC, который зовется Triumvirate, он обрабатывал часть событий, несколько дискорд-вебхуков, поддерживал интеграции с несколькими API и база данных в виде, простите, google-таблиц.

Я, в то время, очень полюбил Kotlin. У него волшебный синтаксис, за ним стоит замечательная команда, он компилируется под разные платформы, от JVM до JS и бинарей. Я очень, очень хотел попробовать этот язык в продакшене, даже работу искал в качестве kotlin back-end'а, лол. Короче, я решил вынести большинство функционала из плагина в API-сервис. На Котлине.

Close Encounters Corps Platform

В качестве стека на бэкенде выбрал следующую связку:

  • Ktor. Просто потому что. HTTP4K слишком простой, Spring слишком монструозный, да и вообще, я на тот момент с Ktor’ом не работал, а хотелось. Как оказалось, умеет много чего вкусного, от пайплайнов из обработчиков и перехватчиков запросов до OAuth и… Ну, вообще, у него просто красивый API. И я говорил, что там есть корутины?

  • Сериализация — Jackson. На момент выбора стека kotlinx.serialization был ещё юным и мало чего умел, с Moshi мне не приходилось работать, а Jackson был мне знакомым и во всём устраивал.

  • Koin. Ешь-пей, жуй Koin. Как и многие другие проекты в сфере Kotlin, этот обладает очень красивым API. Койн очень круто и элегантно решил проблему Dependency Injection. Взял не раздумывая.

  • Hibernate. Примерно по той же причине, что и Jackson. Exposed мне кажется простеньким, а я предполагал, что запросы у нас будут сложные. Насчёт JOOQ — руки не дошли. Может, его нам хватит за глаза, может, нет.

  • MySQL. Я с ним много работал ранее, и поэтому имею много опыта. Однако вопрос перехода на постгрес стоит открытым. Может, перейдём, может, останемся, потому что от “базёнки нам” много и не надо. Мускул администрировать нетрудно, репликация есть, кластеризация с недавних пор тоже, JSON тоже, полнотекстовый индекс тоже, ну а что ещё нужно для счастья?

Фронт:

  • KVision. Я, если честно, до этого во фронте вообще не плавал, поэтому сравнить не с чем. Просто взял первый попавшийся фреймворк с прикольным количеством звёзд, и мне он понравился. Что-то он берёт от себя, что-то — от десктопных фреймворков, что-то — из импортируемых JS-библиотек, и ещё могу отметить то, что Robert Jaros энергично закрывает тикеты и отвечает на все вопросы в слаке котлина. За это ставлю ему лайк.

  • Fomantic UI. Когда я начал лезть во фронт, я начал таскать наброски из других проектов с открытым кодом. Так, я обнаружил, что Gitea во фронте использует Fomantic-UI, форк Semantic-UI. Он мне понравился больше, чем Bootstrap, поэтому я взял его.

  • Kotlinx-serialization. С голым JSON в Kotlin/JS работать не так удобно, как хотелось бы, а Jackson доступен только под JVM. Взяли Kotlinx.

Что ещё мы натворили в этом химерном проекте?

Например, мы написали свою библиотеку конфигурации — Krait. Я к ней настолько привык, что использую ее даже в рабочих проектах, благо она опенсорсная.

Например, мы написали обертку на Hibernate. Завернули туда DSL, корутины (через пул потоков в качестве CoroutineDispatcher, ну а как ещё), и прочее, по мелочи. Получилось “кусьна”! В паре мест всё ещё используется SessionFactory хибернейта, но, в остальной части проекта, — DSL.

Например, мы держим исторические данные (аудит действий над API, access-логи, журналы командиров) в ClickHouse. В комьюнити-библиотеке AORM не было пары функций, но нам не составило особого труда расширить её.

Например, мы хостимся (планируем хоститься) в Docker на трёх связанных Raspberry Pi 4. Не смейтесь. Во-первых, статический IP и три разогнанные малины дешевле хостинга двух-трёх VPS. Во-вторых, они действительно хорошо держат нагрузку, мы проверяли. Да и вообще, скажу, как владелец домашнего медиасервера, — три малины обслуживать куда проще, чем сервак. Разумеется, пришлось повозиться с дистрибутивами, потому что сначала мы были на Raspbian и не могли никак усидеться, затем, всё же, ушли на Ubuntu 20.10.

Также, у нас есть Caddy, потому что у него TLS проще настраивать, чем nginx.

Но и это ещё не всё! Мы хотим связать наш плагин, сервер и сайт в единую среду. Сайт ещё не совсем готов: какой-то функционал (типа оперативных задач сообщества) еще не доделан, где-то фронт просто по-уродски выглядит (как и всегда, если за UI принимается бэкендер), в общем, работы хватает. 

Захотели тоже поиграть? Посмотрите обзоры и решите, подходит ли эта игрушка вам. Ещё, одно время, можно было скачать демо и опробовать игру, но сейчас демо уже найти можно разве что на трекерах. Игра не на каждого, повторюсь, это космический симулятор, но одно время она раздавалась на Epic Games Store и вообще, можете её купить на ближайшей распродаже за 350 рублей и даже если ED вам не понравится, вы мало чего потеряете.

Если ищете пет-проект на Kotlin/JVM, Kotlin/JS или Python, хотите переписать наш фронт на каком-нибудь интересном JS-фреймворке, притащить кафку и микросервисы, или просто хотите помочь нам, Close Encounters Corps, то заходите в наш Discord-сервер или пишите сразу мне (dis: Osmium#5856). Инвайт на сервер есть, например, в ссылках ВК-сообщества. Мы будем рады вашим идеям и просто будем благодарны поддержке.

Если хотите помочь какому-нибудь из иных перечисленных проектов — большинство из них являются частью т.н. ED Community Developers, вот сайт, заходите там в дискорд EDCD, и ищите проект по душе.