用 GDScript 編寫的 Nakama 伺服器的 Godot 用戶端。
Nakama 是一款開源伺服器,旨在為現代遊戲和應用程式提供支援。功能包括用戶帳戶、聊天、社交、媒人、即時多人遊戲等等。
此客戶端透過伺服器實現完整的 API 和套接字選項。它是用 GDScript 編寫的,支援 Godot Engine 4.0+
。
完整文件在線 - https://heroiclabs.com/docs
您目前正在查看 Godot 的 Nakama 用戶端的 Godot 4 版本。
如果您使用 Godot 3,則需要使用 GitHub 上的「godot-3」分支。
您需要先設定伺服器和資料庫,然後才能連接客戶端。最簡單的方法是使用 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 引擎不支援異常,因此每當您透過用戶端或套接字發出非同步請求時,您都可以透過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 用戶端作為後端!這可以讓您繼續使用 Godot 熟悉的高級多人遊戲 API,但透過即時 Nakama 比賽透明地發送 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()
。
如果您使用的是支援 C# 的 .NET 版本的 Godot,則可以使用 Nakama .NET 用戶端,該用戶端可以透過 NuGet 安裝:
dotnet add package NakamaClient
該插件包含一些與 .NET 客戶端一起使用的 C# 類,以提供與 Godot 的更深入整合:
GodotLogger
:列印到 Godot 控制台的記錄器。GodotHttpAdapter
:使用 Godot 的 HTTPRequest 節點的 HTTP 適配器。GodotWebSocketAdapter
:使用 Godot 的 WebSocketClient 的套接字適配器。以下是如何使用它們的範例:
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 用戶端在 Godot 遊戲中與 Satori 通訊。
Satori 僅與 Godot 4 相容。
完整文件在線 - https://heroiclabs.com/docs/satori/client-libraries/godot/index.html
新增Satori.gd
單例(在addons/com.heroiclabs.nakama/
中)作為 Godot 中的自動載入。
建立一個客戶端對象,該對象接受您作為 Satori 客戶提供的 API 金鑰。
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 compose 文件。
此外,您需要複製(或符號連結) test_suite
資料夾內的addons
資料夾。現在您可以從 Godot 編輯器執行test_suite
專案。
要在無頭機器(沒有 GPU)上執行測試,您可以下載 Godot Headless 的副本並從命令列運行它。
要自動化此過程,請將無頭二進位檔案移至test_suite/bin/godot.elf
,並透過test_suite/run_tests.sh
shell 腳本執行測試(退出程式碼將報告測試失敗/成功)。
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 許可證獲得許可。