Client Godot pour serveur Nakama écrit en GDScript.
Nakama est un serveur open source conçu pour alimenter les jeux et applications modernes. Les fonctionnalités incluent les comptes d'utilisateurs, le chat, les réseaux sociaux, le matchmaker, le multijoueur en temps réel et bien plus encore.
Ce client implémente toutes les options d'API et de socket avec le serveur. Il est écrit en GDScript pour prendre en charge Godot Engine 4.0+
.
La documentation complète est en ligne - https://heroiclabs.com/docs
Vous consultez actuellement la version Godot 4 du client Nakama pour Godot.
Si vous utilisez Godot 3, vous devez utiliser la branche « godot-3 » sur GitHub.
Vous devrez configurer le serveur et la base de données avant de pouvoir vous connecter au client. Le moyen le plus simple est d'utiliser Docker, mais consultez la documentation du serveur pour d'autres options.
Installez et exécutez les serveurs. Suivez ces instructions.
Téléchargez le client à partir de la page des versions et importez-le dans votre projet. Vous pouvez également le télécharger depuis le référentiel d'actifs.
Ajoutez le singleton Nakama.gd
(dans addons/com.heroiclabs.nakama/
) en tant que chargement automatique dans Godot.
Utilisez les informations d'identification de connexion pour créer un objet client à l'aide du singleton.
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 )
L'objet client dispose de nombreuses méthodes pour exécuter diverses fonctionnalités sur le serveur ou ouvrir des connexions socket en temps réel avec le serveur.
Il existe différentes manières de s'authentifier auprès du serveur. L'authentification peut créer un utilisateur s'il n'existe pas déjà avec ces informations d'identification. Il est également facile de s'authentifier avec un profil social de Google Play Games, Facebook, Game Center, etc.
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 )
Une fois authentifié, le serveur répond avec un jeton d'authentification (JWT) qui contient des propriétés utiles et est désérialisé dans un objet 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 )
Il est recommandé de stocker le jeton d'authentification de la session et de vérifier au démarrage s'il a expiré. Si le token a expiré, vous devez vous authentifier à nouveau. Le délai d'expiration du jeton peut être modifié en tant que paramètre sur le serveur.
var authtoken = "restored from somewhere"
var session2 = NakamaClient . restore_session ( authtoken )
if session2 . expired :
print ( "Session has expired. Must reauthenticate!" )
REMARQUE : La durée de vie d'une session peut être modifiée sur le serveur avec l'argument d'indicateur de commande --session.token_expiry_sec
.
Le client comprend de nombreuses API intégrées pour diverses fonctionnalités du serveur de jeu. Ceux-ci sont accessibles avec les méthodes asynchrones. Il peut également appeler une logique personnalisée dans les fonctions RPC sur le serveur. Ceux-ci peuvent également être exécutés avec un objet socket.
Toutes les demandes sont envoyées avec un objet de session qui autorise le client.
var account = await client . get_account_async ( session )
print ( account . user . id )
print ( account . user . username )
print ( account . wallet )
Étant donné que Godot Engine ne prend pas en charge les exceptions, chaque fois que vous effectuez une requête asynchrone via le client ou le socket, vous pouvez vérifier si une erreur s'est produite via la méthode 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" )
Le client peut créer un ou plusieurs sockets avec le serveur. Chaque socket peut avoir ses propres écouteurs d'événements enregistrés pour les réponses reçues du serveur.
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 fournit une API multijoueur de haut niveau, permettant aux développeurs de créer des RPC, appelant des fonctions qui s'exécutent sur d'autres pairs dans une partie multijoueur.
Par exemple:
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 fournit un certain nombre de backends intégrés pour envoyer les RPC, notamment : ENet, WebSockets et WebRTC.
Cependant, vous pouvez également utiliser le client Nakama comme backend ! Cela peut vous permettre de continuer à utiliser l'API multijoueur de haut niveau familière de Godot, mais avec les RPC envoyés de manière transparente lors d'un match Nakama en temps réel.
Pour ce faire, vous devez utiliser la classe 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 )
Vous pouvez également vous connecter à l'un des signaux habituels sur MultiplayerAPI
, par exemple :
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 )
Ensuite, vous devez rejoindre une partie en utilisant l'une des méthodes suivantes :
Créez une nouvelle correspondance privée, avec votre client comme hôte.
multiplayer_bridge . create_match ()
Rejoignez un match privé.
multiplayer_bridge . join_match ( match_id )
Créez ou rejoignez une correspondance privée avec le nom donné.
multiplayer_bridge . join_named_match ( match_name )
Utilisez le matchmaker pour rechercher et rejoindre un match public.
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 )
Une fois le signal "match_joined" émis, vous pouvez commencer à envoyer des RPC comme d'habitude avec la fonction rpc()
et appeler toute autre fonction associée à l'API multijoueur de haut niveau, telle que get_tree().get_multiplayer().get_unique_id()
et node.set_network_authority(peer_id)
et node.is_network_authority()
.
Si vous utilisez la version .NET de Godot avec le support C#, vous pouvez utiliser le client Nakama .NET, qui peut être installé via NuGet :
dotnet add package NakamaClient
Cet addon inclut certaines classes C# à utiliser avec le client .NET, pour fournir une intégration plus approfondie avec Godot :
GodotLogger
: Un enregistreur qui imprime sur la console Godot.GodotHttpAdapter
: Un adaptateur HTTP qui utilise le nœud HTTPRequest de Godot.GodotWebSocketAdapter
: Un adaptateur de socket qui utilise le WebSocketClient de Godot.Voici un exemple de la façon de les utiliser :
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 ) ;
Remarque : Le client Nakama .NET prêt à l'emploi fonctionnera parfaitement avec les versions de bureau de votre jeu ! Cependant, cela ne fonctionnera pas avec les versions HTML5, sauf si vous utilisez les classes GodotHttpAdapter
et GodotWebSocketAdapter
.
Satori est un serveur liveops pour les jeux qui alimente des analyses exploitables, des tests A/B et une configuration à distance. Utilisez le client Satori Godot pour communiquer avec Satori depuis votre jeu Godot.
Satori n'est compatible qu'avec Godot 4.
La documentation complète est en ligne - https://heroiclabs.com/docs/satori/client-libraries/godot/index.html
Ajoutez le singleton Satori.gd
(dans addons/com.heroiclabs.nakama/
) en tant que chargement automatique dans Godot.
Créez un objet client qui accepte la clé API qui vous a été fournie en tant que client 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 )
Authentifiez-vous ensuite auprès du serveur pour obtenir votre session.
// 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." )
En utilisant le client, vous pouvez obtenir toutes les expériences ou indicateurs de fonctionnalités auxquels l'utilisateur appartient.
var experiments = await _client . get_experiments_async ( session , [ "experiment1" , "Experiment2" ])
var flag = await _client . get_flag_async ( session , "FlagName" )
Vous pouvez également envoyer des événements arbitraires au serveur :
var _event = Event . new ( "gameFinished" , Time . get_unix_time_from_system ())
await _client . event_async ( session , _event )
La feuille de route de développement est gérée car les problèmes GitHub et les demandes d'extraction sont les bienvenus. Si vous souhaitez améliorer le code, veuillez ouvrir un ticket pour discuter des modifications ou venir en discuter sur le forum de la communauté.
Pour exécuter des tests, vous devrez exécuter le serveur et la base de données. La plupart des tests sont écrits sous forme de tests d'intégration qui s'exécutent sur le serveur. Une approche rapide que nous utilisons avec notre flux de travail de test consiste à utiliser le fichier de composition Docker décrit dans la documentation.
De plus, vous devrez copier (ou créer un lien symbolique) le dossier addons
dans le dossier test_suite
. Vous pouvez maintenant exécuter le projet test_suite
à partir de l'éditeur Godot.
Pour exécuter les tests sur une machine sans tête (sans GPU), vous pouvez télécharger une copie de Godot Headless et l'exécuter à partir de la ligne de commande.
Pour automatiser cette procédure, déplacez le binaire sans tête vers test_suite/bin/godot.elf
et exécutez les tests via le script shell test_suite/run_tests.sh
(le code de sortie signalera l'échec/le succès du test).
cd nakama
docker-compose -f ./docker-compose-postgres.yml up
cd ..
cd nakama-godot
sh test_suite/run_tests.sh
Pour préparer une nouvelle version à la distribution, compressez simplement le dossier des modules complémentaires de manière récursive (en ajoutant éventuellement CHANGELOG
, LICENSE
et README.md
également).
Sur les systèmes Unix, vous pouvez exécuter la commande suivante (en remplaçant $VERSION
par le numéro de version souhaité). N'oubliez pas de mettre à jour le fichier CHANGELOG
en premier.
zip -r nakama- $VERSION .zip addons/ LICENSE CHANGELOG.md README.md
Ce projet est sous licence Apache-2.