Cliente Godot para el servidor Nakama escrito en GDScript.
Nakama es un servidor de código abierto diseñado para impulsar juegos y aplicaciones modernos. Las características incluyen cuentas de usuario, chat, redes sociales, emparejamiento, multijugador en tiempo real y mucho más.
Este cliente implementa la API completa y las opciones de socket con el servidor. Está escrito en GDScript para admitir Godot Engine 4.0+
.
La documentación completa está en línea: https://heroiclabs.com/docs
Actualmente estás viendo la versión Godot 4 del cliente Nakama para Godot.
Si está utilizando Godot 3, debe utilizar la rama 'Godot-3' en GitHub.
Deberá configurar el servidor y la base de datos antes de poder conectarse con el cliente. La forma más sencilla es utilizar Docker, pero consulte la documentación del servidor para conocer otras opciones.
Instalar y ejecutar los servidores. Siga estas instrucciones.
Descargue el cliente desde la página de lanzamientos e impórtelo a su proyecto. También puedes descargarlo desde el repositorio de activos.
Agregue el singleton Nakama.gd
(en addons/com.heroiclabs.nakama/
) como carga automática en Godot.
Utilice las credenciales de conexión para crear un objeto de cliente utilizando el 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 )
El objeto cliente tiene muchos métodos para ejecutar varias funciones en el servidor o abrir conexiones de socket en tiempo real con el servidor.
Hay una variedad de formas de autenticarse con el servidor. La autenticación puede crear un usuario si aún no existe con esas credenciales. También es fácil autenticarse con un perfil 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 )
Cuando se autentica, el servidor responde con un token de autenticación (JWT) que contiene propiedades útiles y se deserializa en un objeto 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 )
Se recomienda almacenar el token de autenticación de la sesión y comprobar al inicio si ha caducado. Si el token ha caducado, deberá volver a autenticarse. El tiempo de vencimiento del token se puede cambiar como configuración en el servidor.
var authtoken = "restored from somewhere"
var session2 = NakamaClient . restore_session ( authtoken )
if session2 . expired :
print ( "Session has expired. Must reauthenticate!" )
NOTA: La duración de la vida útil de una sesión se puede cambiar en el servidor con el argumento del indicador del comando --session.token_expiry_sec
.
El cliente incluye muchas API integradas para diversas funciones del servidor del juego. Se puede acceder a ellos con los métodos asíncronos. También puede llamar a lógica personalizada en funciones RPC en el servidor. Estos también se pueden ejecutar con un objeto socket.
Todas las solicitudes se envían con un objeto de sesión que autoriza al cliente.
var account = await client . get_account_async ( session )
print ( account . user . id )
print ( account . user . username )
print ( account . wallet )
Dado que Godot Engine no admite excepciones, cada vez que realiza una solicitud asíncrona a través del cliente o socket, puede verificar si ocurrió un error mediante el método 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" )
El cliente puede crear uno o más sockets con el servidor. Cada socket puede tener sus propios detectores de eventos registrados para las respuestas recibidas del servidor.
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 proporciona una API multijugador de alto nivel, que permite a los desarrolladores crear RPC y llamar a funciones que se ejecutan en otros compañeros en una partida multijugador.
Por ejemplo:
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 proporciona una serie de backends integrados para enviar RPC, incluidos: ENet, WebSockets y WebRTC.
Sin embargo, ¡también puedes utilizar el cliente Nakama como backend! Esto puede permitirte continuar usando la conocida API multijugador de alto nivel de Godot, pero con los RPC enviados de forma transparente a través de una partida de Nakama en tiempo real.
Para hacer eso, necesitas usar la clase 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 )
También puedes conectarte a cualquiera de las señales habituales en MultiplayerAPI
, por ejemplo:
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 )
Luego debes unirte a una partida, usando uno de los siguientes métodos:
Crea una nueva partida privada, con tu cliente como anfitrión.
multiplayer_bridge . create_match ()
Únete a una partida privada.
multiplayer_bridge . join_match ( match_id )
Crea o únete a una partida privada con el nombre de pila.
multiplayer_bridge . join_named_match ( match_name )
Utilice el emparejador para buscar y unirse a una partida pública.
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 )
Después de que se emita la señal "match_joined", puede comenzar a enviar RPC como de costumbre con la función rpc()
y llamar a cualquier otra función asociada con la API multijugador de alto nivel, como get_tree().get_multiplayer().get_unique_id()
y node.set_network_authority(peer_id)
y node.is_network_authority()
.
Si está utilizando la versión .NET de Godot con soporte C#, puede usar el cliente Nakama .NET, que se puede instalar a través de NuGet:
dotnet add package NakamaClient
Este complemento incluye algunas clases de C# para usar con el cliente .NET, para proporcionar una integración más profunda con Godot:
GodotLogger
: un registrador que imprime en la consola Godot.GodotHttpAdapter
: un adaptador HTTP que utiliza el nodo HTTPRequest de Godot.GodotWebSocketAdapter
: un adaptador de socket que utiliza WebSocketClient de Godot.A continuación se muestra un ejemplo de cómo utilizarlos:
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 ) ;
Nota: ¡El cliente Nakama .NET listo para usar funcionará bien con las versiones de escritorio de tu juego! Sin embargo, no funcionará con compilaciones HTML5, a menos que uses las clases GodotHttpAdapter
y GodotWebSocketAdapter
.
Satori es un servidor de operaciones en vivo para juegos que impulsa análisis procesables, pruebas A/B y configuración remota. Utilice el Cliente Satori Godot para comunicarse con Satori desde su juego Godot.
Satori sólo es compatible con Godot 4.
La documentación completa está en línea: https://heroiclabs.com/docs/satori/client-libraries/godot/index.html
Agregue el singleton Satori.gd
(en addons/com.heroiclabs.nakama/
) como carga automática en Godot.
Cree un objeto de cliente que acepte la clave API que le proporcionaron como cliente de 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 )
Luego autentícate con el servidor para obtener tu sesión.
// 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." )
Al utilizar el cliente, puede obtener cualquier experimento o indicador de función al que pertenezca el usuario.
var experiments = await _client . get_experiments_async ( session , [ "experiment1" , "Experiment2" ])
var flag = await _client . get_flag_async ( session , "FlagName" )
También puedes enviar eventos arbitrarios al servidor:
var _event = Event . new ( "gameFinished" , Time . get_unix_time_from_system ())
await _client . event_async ( session , _event )
La hoja de ruta de desarrollo se gestiona ya que los problemas de GitHub y las solicitudes de extracción son bienvenidos. Si está interesado en mejorar el código, abra un problema para discutir los cambios o visite el foro de la comunidad y discútalo.
Para ejecutar pruebas necesitará ejecutar el servidor y la base de datos. La mayoría de las pruebas están escritas como pruebas de integración que se ejecutan en el servidor. Un enfoque rápido que utilizamos con nuestro flujo de trabajo de prueba es utilizar el archivo de redacción de Docker que se describe en la documentación.
Además, deberá copiar (o vincular simbólicamente) la carpeta de addons
dentro de la carpeta test_suite
. Ahora puede ejecutar el proyecto test_suite
desde el Editor Godot.
Para ejecutar las pruebas en una máquina sin cabeza (sin GPU), puede descargar una copia de Godot Headless y ejecutarla desde la línea de comandos.
Para automatizar este procedimiento, mueva el binario sin cabeza a test_suite/bin/godot.elf
y ejecute las pruebas a través del script de shell test_suite/run_tests.sh
(el código de salida informará el error o el éxito de la prueba).
cd nakama
docker-compose -f ./docker-compose-postgres.yml up
cd ..
cd nakama-godot
sh test_suite/run_tests.sh
Para preparar una nueva versión para su distribución, simplemente comprima la carpeta de complementos de forma recursiva (posiblemente agregando CHANGELOG
, LICENSE
y README.md
también).
En sistemas Unix, puede ejecutar el siguiente comando (reemplazando $VERSION
con el número de versión deseado). Recuerde actualizar primero el archivo CHANGELOG
.
zip -r nakama- $VERSION .zip addons/ LICENSE CHANGELOG.md README.md
Este proyecto está bajo la licencia Apache-2.