Клиент Godot для сервера Nakama, написанный на GDScript.
Nakama — это сервер с открытым исходным кодом, предназначенный для поддержки современных игр и приложений. Функции включают учетные записи пользователей, чат, социальные сети, подбор игроков, многопользовательскую игру в реальном времени и многое другое.
Этот клиент реализует полный API и параметры сокетов с сервером. Он написан на GDScript для поддержки Godot Engine 4.0+
.
Полная документация доступна онлайн — https://heroiclabs.com/docs.
В настоящее время вы просматриваете версию клиента Nakama для Godot Godot 4.
Если вы используете Godot 3, вам необходимо использовать ветку godot-3 на GitHub.
Прежде чем вы сможете подключиться к клиенту, вам необходимо настроить сервер и базу данных. Самый простой способ — использовать Docker, но другие варианты можно найти в документации сервера.
Установите и запустите серверы. Следуйте этим инструкциям.
Загрузите клиент со страницы релизов и импортируйте его в свой проект. Вы также можете скачать его из хранилища ресурсов.
Добавьте синглтон Nakama.gd
(в addons/com.heroiclabs.nakama/
) в качестве автозагрузки в Godot.
Используйте учетные данные подключения для создания клиентского объекта с помощью синглтона.
extends Node
func _ready ():
var scheme = "http"
var host = "127.0.0.1"
var port = 7350
var server_key = "defaultkey"
var client := Nakama . create_client ( server_key , host , port , scheme )
Клиентский объект имеет множество методов для выполнения различных функций на сервере или открытия сокетных соединений с сервером в реальном времени.
Существует множество способов аутентификации на сервере. Аутентификация может создать пользователя с этими учетными данными, если он еще не существует. Также легко пройти аутентификацию с помощью профиля социальной сети Google Play Games, Facebook, Game Center и т. д.
var email = "[email protected]"
var password = "batsignal"
# Use 'await' to wait for the request to complete.
var session : NakamaSession = await client . authenticate_email_async ( email , password )
print ( session )
При аутентификации сервер отвечает токеном аутентификации (JWT), который содержит полезные свойства и десериализуется в объект NakamaSession
.
print ( session . token ) # raw JWT token
print ( session . user_id )
print ( session . username )
print ( "Session has expired: %s " % session . expired )
print ( "Session expires at: %s " % session . expire_time )
Рекомендуется сохранить токен аутентификации из сеанса и проверить при запуске, не истек ли срок его действия. Если срок действия токена истек, вам необходимо пройти повторную аутентификацию. Срок действия токена можно изменить в настройках сервера.
var authtoken = "restored from somewhere"
var session2 = NakamaClient . restore_session ( authtoken )
if session2 . expired :
print ( "Session has expired. Must reauthenticate!" )
ПРИМЕЧАНИЕ. Продолжительность существования сеанса можно изменить на сервере с помощью аргумента флага команды --session.token_expiry_sec
.
Клиент включает в себя множество встроенных API для различных функций игрового сервера. Доступ к ним можно получить с помощью асинхронных методов. Он также может вызывать пользовательскую логику в функциях RPC на сервере. Их также можно выполнить с помощью объекта сокета.
Все запросы отправляются с объектом сеанса, который авторизует клиента.
var account = await client . get_account_async ( session )
print ( account . user . id )
print ( account . user . username )
print ( account . wallet )
Поскольку Godot Engine не поддерживает исключения, всякий раз, когда вы делаете асинхронный запрос через клиент или сокет, вы можете проверить, произошла ли ошибка, с помощью метода is_exception()
.
var an_invalid_session = NakamaSession . new () # An empty session, which will cause and error when we use it.
var account2 = await client . get_account_async ( an_invalid_session )
print ( account2 ) # This will print the exception
if account2 . is_exception ():
print ( "We got an exception" )
Клиент может создать с сервером один или несколько сокетов. Каждый сокет может иметь свои собственные прослушиватели событий, зарегистрированные для ответов, полученных от сервера.
var socket = Nakama . create_socket_from ( client )
socket . connected . connect ( self . _on_socket_connected )
socket . closed . connect ( self . _on_socket_closed )
socket . received_error . connect ( self . _on_socket_error )
await socket . connect_async ( session )
print ( "Done" )
func _on_socket_connected ():
print ( "Socket connected." )
func _on_socket_closed ():
print ( "Socket closed." )
func _on_socket_error ( err ):
printerr ( "Socket error %s " % err )
Godot предоставляет многопользовательский API высокого уровня, позволяющий разработчикам создавать RPC, вызывая функции, которые выполняются на других узлах в многопользовательском матче.
Например:
func _process ( delta ):
if not is_multiplayer_authority ():
return
var input_vector = get_input_vector ()
# Move the player locally.
velocity = input_vector * SPEED
move_and_slide ()
# Then update the player's position on all other connected clients.
update_remote_position . rpc ( position )
@rpc ( any_peer )
func update_remote_position ( new_position ):
position = new_position
Godot предоставляет ряд встроенных серверных средств для отправки RPC, в том числе: ENet, WebSockets и WebRTC.
Однако вы также можете использовать клиент Nakama в качестве бэкэнда! Это может позволить вам продолжать использовать знакомый многопользовательский API высокого уровня Godot, но с прозрачной отправкой RPC во время матча Накама в реальном времени.
Для этого вам нужно использовать класс NakamaMultiplayerBridge
:
var multiplayer_bridge
func _ready ():
# [...]
# You must have a working 'socket', created as described above.
multiplayer_bridge = NakamaMultiplayerBridge . new ( socket )
multiplayer_bridge . match_join_error . connect ( self . _on_match_join_error )
multiplayer_bridge . match_joined . connect ( self . _on_match_joined )
get_tree (). get_multiplayer (). set_multiplayer_peer ( multiplayer_bridge . multiplayer_peer )
func _on_match_join_error ( error ):
print ( "Unable to join match: " , error . message )
func _on_match_join () -> void :
print ( "Joined match with id: " , multiplayer_bridge . match_id )
Также можно подключиться к любому из обычных сигналов MultiplayerAPI
, например:
get_tree (). get_multiplayer (). peer_connected . connect ( self . _on_peer_connected )
get_tree (). get_multiplayer (). peer_disconnected . connect ( self . _on_peer_disconnected )
func _on_peer_connected ( peer_id ):
print ( "Peer joined match: " , peer_id )
func _on_peer_disconnected ( peer_id ):
print ( "Peer left match: " , peer_id )
Затем вам необходимо присоединиться к матчу, используя один из следующих способов:
Создайте новый частный матч с вашим клиентом в качестве организатора.
multiplayer_bridge . create_match ()
Присоединяйтесь к частному матчу.
multiplayer_bridge . join_match ( match_id )
Создайте или присоединитесь к частному матчу с указанным именем.
multiplayer_bridge . join_named_match ( match_name )
Используйте сваху, чтобы найти публичный матч и присоединиться к нему.
var ticket = await socket . add_matchmaker_async ()
if ticket . is_exception ():
print ( "Error joining matchmaking pool: " , ticket . get_exception (). message )
return
multiplayer_bridge . start_matchmaking ( ticket )
После выдачи сигнала match_joined вы можете начать отправлять RPC, как обычно, с помощью функции rpc()
и вызывать любые другие функции, связанные с API многопользовательской игры высокого уровня, например get_tree().get_multiplayer().get_unique_id()
и node.set_network_authority(peer_id)
и node.is_network_authority()
.
Если вы используете версию Godot для .NET с поддержкой C#, вы можете использовать клиент Nakama .NET, который можно установить через NuGet:
dotnet add package NakamaClient
Это дополнение включает в себя некоторые классы C# для использования с клиентом .NET, обеспечивающие более глубокую интеграцию с Godot:
GodotLogger
: Регистратор, который печатает на консоль Godot.GodotHttpAdapter
: HTTP-адаптер, использующий узел HTTPRequest Godot.GodotWebSocketAdapter
: адаптер сокета, использующий WebSocketClient Godot.Вот пример того, как их использовать:
var http_adapter = new GodotHttpAdapter ( ) ;
// It's a Node, so it needs to be added to the scene tree.
// Consider putting this in an autoload singleton so it won't go away unexpectedly.
AddChild ( http_adapter ) ;
const string scheme = "http" ;
const string host = "127.0.0.1" ;
const int port = 7350 ;
const string serverKey = "defaultkey" ;
// Pass in the 'http_adapter' as the last argument.
var client = new Client ( scheme , host , port , serverKey , http_adapter ) ;
// To log DEBUG messages to the Godot console.
client . Logger = new GodotLogger ( "Nakama" , GodotLogger . LogLevel . DEBUG ) ;
ISession session ;
try {
session = await client . AuthenticateDeviceAsync ( OS . GetUniqueId ( ) , "TestUser" , true ) ;
}
catch ( ApiResponseException e ) {
GD . PrintErr ( e . ToString ( ) ) ;
return ;
}
var websocket_adapter = new GodotWebSocketAdapter ( ) ;
// Like the HTTP adapter, it's a Node, so it needs to be added to the scene tree.
// Consider putting this in an autoload singleton so it won't go away unexpectedly.
AddChild ( websocket_adapter ) ;
// Pass in the 'websocket_adapter' as the last argument.
var socket = Socket . From ( client , websocket_adapter ) ;
Примечание. Готовый клиент Nakama .NET отлично работает со сборками вашей игры для настольных компьютеров! Однако он не будет работать со сборками HTML5, если вы не используете классы GodotHttpAdapter
и GodotWebSocketAdapter
.
Satori — это liveops-сервер для игр, который обеспечивает действенную аналитику, A/B-тестирование и удаленную настройку. Используйте клиент Satori Godot для общения с Satori из вашей игры Godot.
Сатори совместим только с Godot 4.
Полная документация доступна онлайн — https://heroiclabs.com/docs/satori/client-libraries/godot/index.html.
Добавьте синглтон Satori.gd
(в addons/com.heroiclabs.nakama/
) в качестве автозагрузки в Godot.
Создайте объект клиента, который принимает ключ API, который вы получили как клиент Satori.
extends Node
func ready ():
var scheme = "http"
var host = "127.0.0.1"
var port : Int = 7450
var apiKey = "apiKey"
var client := Satori . create_client ( apiKey , host , port , scheme )
Затем авторизуйтесь на сервере, чтобы получить сеанс.
// Authenticate with the Satori server .
var session = await _client . authenticate_async ( "your-id" )
if session . is_exception ():
print ( "Error authenticating: " + session . get_exception (). _message )
else :
print ( "Authenticated successfully." )
Используя клиент, вы можете получить любые эксперименты или флаги функций, к которым принадлежит пользователь.
var experiments = await _client . get_experiments_async ( session , [ "experiment1" , "Experiment2" ])
var flag = await _client . get_flag_async ( session , "FlagName" )
Вы также можете отправлять на сервер произвольные события:
var _event = Event . new ( "gameFinished" , Time . get_unix_time_from_system ())
await _client . event_async ( session , _event )
Дорожная карта разработки управляется, поскольку проблемы GitHub и запросы на включение приветствуются. Если вы заинтересованы в улучшении кода, откройте вопрос, чтобы обсудить изменения, или зайдите и обсудите его на форуме сообщества.
Для запуска тестов вам понадобится запустить сервер и базу данных. Большинство тестов написаны как интеграционные тесты, которые выполняются на сервере. Быстрый подход, который мы используем в нашем рабочем процессе тестирования, — это использовать файл компоновки Docker, описанный в документации.
Кроме того, вам нужно будет скопировать (или создать символическую ссылку) папку addons
внутри папки test_suite
. Теперь вы можете запустить проект test_suite
из редактора Godot.
Чтобы запустить тесты на безголовой машине (без графического процессора), вы можете загрузить копию Godot Headless и запустить ее из командной строки.
Чтобы автоматизировать эту процедуру, переместите безголовый двоичный файл в test_suite/bin/godot.elf
и запустите тесты с помощью сценария оболочки test_suite/run_tests.sh
(код выхода сообщит об ошибке/успехе теста).
cd nakama
docker-compose -f ./docker-compose-postgres.yml up
cd ..
cd nakama-godot
sh test_suite/run_tests.sh
Чтобы подготовить новый выпуск к распространению, просто рекурсивно заархивируйте папку addons (возможно, добавив также CHANGELOG
, LICENSE
и README.md
).
В системах unix вы можете запустить следующую команду (заменив $VERSION
на нужный номер версии). Не забудьте сначала обновить файл CHANGELOG
.
zip -r nakama- $VERSION .zip addons/ LICENSE CHANGELOG.md README.md
Этот проект распространяется по лицензии Apache-2.