devzone.org.ua/post/rozrobka-kartkovoyi-hry-z-vidkrytym-kodom-openlegends.md
2025-11-01 14:28:20 +02:00

140 lines
No EOL
10 KiB
Markdown
Raw Permalink 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.

# Розробка карткової гри з відкритим кодом OpenLegends
[OpenLegends](https://github.com/openlegends) - це проект реалізації вільного рушія та інтерфейсу багатокористувацької карткової гри [The Elder Scrolls Legends](https://bethesda.net/en/game/legends), в першу чергу орієнтованого на браузерний формат з використанням технологій HTML5.
Початковий код реалізовано мовою PHP 8, з використанням пакетного менеджеру Composer. Причина обрання цієї мови - наявний досвід та переконання що її можливостей буде цілком достатньо для опису ігрової логіки. Також це зручно для інтеграції веб-застосунків.
В процесі, можливо буде виконано адаптацію для десктопів на Rust з використанням QT, хоча більш ймовірною буде імплементація на Electron. Окремо хотілось би мати альтернативу для CLI та протоколу [Gemini](https://devzone.org.ua/post/protokol-gemini-iak-legka-alternativa-http), з підтримкою графіки ASCII.
Враховуючи функціональний потенціал оригінальної гри - завдання для однієї людини не тривіальне, утім мені все ж цікаво спробувати здійснити цю давню мрію і можливо, за цей час хтось також долучитися до розробки!
## Структура
Проект ділиться на три окремі гілки розробки:
* `core-php` - базовий інтерфейс рушія та набір абстрактних класів ядра
* `asset-php` - ігрові набори: карти, ігрові режими та інші компоненти, що реалізують `core-php`
* *сервер* - багатокористувацький інтерфейс, ймовірно буде реалізований на базі фреймворку Symfony
## Ядро (core-php)
Мета [core-php](https://github.com/openlegends/core-php) - відділити будь яку ігрову логіку від базової структури рушія, що дозволить робити менш часті оновлення ядра (зберігаючи сумісність як найдовше) та активніше розвивати зовнішні інтерфейси - наприклад, ігрові набори, що реалізують певну його версію.
Наразі перебуває на стадії прототипу, для встановлення використовується остання версія з репозиторія:
```
composer require openlegends/core:dev-main
```
З появою першої стабільної версії, буде виконано перехід на [Семантичні версії](https://semver.org/lang/uk/) релізів.
По суті, ядро складається з класів двох типів - Інтерфейси, що власне описують можливості класів карт, гравців, ігрових сесій тощо, та Абстрактні класи - що частково реалізують ці інтерфейси та використовуються ігровими наборами.
Здебільшого, Абстрактні класи містять у собі такі універсальні методи як Сетери і Гетери, але можуть містити й інші - для запобігання їх дублікації в наборах (де наприклад тільки карткових класів може бути близько тисячі).
Також, Абстрактні класи містять деякі абстрактні методи, які вимагають специфічної реалізації окремим класом: наприклад, дія карти, або гравця, яка в TES Legends мало чи не описує всю ігрову логіку в одному акті.
## Ігрові набори (asset-php)
Ігрові набори представлені в репозиторії [asset-php](https://github.com/openlegends/asset-php) і описують ігрову логіку.
Сюди входить оголошення та опис кожної карти, гравця, режиму гри та їх можливостей. Ігровий набір у своєму релізі має орієнтуватись на певну версію ядра `core-php`, що спростить розробку та супровід окремо взятого ігрового серверу, який реалізує певний набір.
В розробці використовується остання версія репозиторія, яка наразі не містить стабільних релізів:
```
composer require openlegends/asset:dev-main
```
Дана версія включає тільки умовний тестовий набір класів, що складається з декількох умовних гравців (Player1, Player2), карт (Mouse, Goblin, Rat) та режиму гри з двох гравців (Arena), достатніх для тестування `core-php` та майбутнього ігрового серверу.
Після появи першого стабільного релізу ядра, можна буде створити реальний набір, оскільки ядро перебуває в розробці а інтерфейс може змінюватись, у тестовому наборі не доречно обслуговувати більше трьох карт.
Говорячи про реліз, ймовірно, це буде копія набору TES Legends, оскільки розрахунок нового ігрового балансу - це окреме завдання з області математики і потребує немало часу, включно з тестуванням реальними гравцями.
Ігрові дані для набору можна подивитись на сайті [TES Legends Pro](https://teslegends.pro) а також запозичити звідти графіку. По зрозумілим причинам, розмістити такі дані в рамках проекту OpenLegends не є доречним, але це не заважає розгорнути альтернативний форк `asset-php`.
## Приклади роботи
Завдання будь якого рушія - спрощення розробки гри. Отже, для кращого розуміння що собою являє рушій OpenLegends, розглянемо декілька найпростіших прикладів на основі тестового набору.
У даному матеріалі не будуть описані інші можливості, враховуючи що вони можуть різнитися в новіших версіях.
### Взаємодія карт
```
<?php
$mouse = new \OpenLegends\Asset\Test\Card\Mouse();
$rat = new \OpenLegends\Asset\Test\Card\Rat();
$damage = new \OpenLegends\Asset\Test\Card\Action\Damage(
$mouse
);
$damage->card(
$rat
);
var_dump(
$rat->getHealth()
);
```
### Картковий пул
Використовується здебільшого в ігрових сесіях для організації карткових наборів, наприклад колоди, стопки скиду, карт в руці, тощо:
```
<?php
$deck = new \OpenLegends\Asset\Test\Pool\Card();
$deck->addCard(
new \OpenLegends\Asset\Test\Card\Goblin()
);
$deck->addCard(
new \OpenLegends\Asset\Test\Card\Mouse()
);
$deck->addCard(
new \OpenLegends\Asset\Test\Card\Rat()
);
var_dump(
$deck->getRandomCard()->getName()
);
```
### Ігрова сесія
На реальному сервері, гра та її учасники створюються інтерактивно через запити графічного інтерфейсу.
У тестовому наборі, сесія кожного гравця ініціюється [в конструкторі його класу](https://github.com/openlegends/asset-php/blob/main/src/Test/Game/Player/Player1.php) автоматично, реалізуючи абстрактний клас ядра `\OpenLegends\Core\Abstract\Game\Player`, що включає готові набори карт, об'єкт користувача, статус здоров'я тощо.
Після того, як об'єкт або клас гравця з картковими пулами було створено, ці дані передаються до об'єкту нової гри та ініціюється сценарій старту:
```
<?php
$game = new \OpenLegends\Asset\Test\Game\Arena();
$game->addPlayer(
new OpenLegends\Asset\Test\Game\Player\Player1()
);
$game->addPlayer(
new OpenLegends\Asset\Test\Game\Player\Player2()
);
$game->start();
```
Інші приклади (зокрема специфіка роботи ігрового серверу через веб-сокети, взаємодія з базами даних, створення інтерактивних інтерфейсів) вартують розгляду в рамках окремої гілки серії.
Сподіваюсь, на даному етапі, мені вдалось описати загальний статус та принципи розробки проекту.
Кому цікава реалізація TES Legends з відкритим кодом - ласкаво просимо до OpenLegends!
## Посилання
* [Сторінка на GitHub](https://github.com/openlegends)