عميل Godot لخادم Nakama المكتوب بلغة GDScript.
Nakama هو خادم مفتوح المصدر مصمم لتشغيل الألعاب والتطبيقات الحديثة. تتضمن الميزات حسابات المستخدمين، والدردشة، والتواصل الاجتماعي، وصانع الثقاب، ومتعدد اللاعبين في الوقت الفعلي، وغير ذلك الكثير.
يطبق هذا العميل واجهة برمجة التطبيقات (API) وخيارات المقبس الكاملة مع الخادم. إنه مكتوب بلغة GDScript لدعم Godot Engine 4.0+
.
التوثيق الكامل متاح على الإنترنت - https://heroiclabs.com/docs
أنت تنظر حاليًا إلى إصدار Godot 4 من عميل Nakama لـ Godot.
إذا كنت تستخدم 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
.
يشتمل العميل على الكثير من واجهات برمجة التطبيقات المضمنة لمختلف ميزات خادم اللعبة. يمكن الوصول إليها باستخدام الطرق غير المتزامنة. يمكنه أيضًا استدعاء المنطق المخصص في وظائف 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 واجهة برمجة تطبيقات متعددة اللاعبين عالية المستوى، مما يسمح للمطورين بإنشاء عمليات 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 عددًا من الواجهات الخلفية المضمنة لإرسال RPCs، بما في ذلك: ENet وWebSockets وWebRTC.
ومع ذلك، يمكنك أيضًا استخدام عميل Nakama كواجهة خلفية! يمكن أن يسمح لك هذا بمواصلة استخدام واجهة برمجة التطبيقات متعددة اللاعبين عالية المستوى المألوفة من Godot، ولكن مع إرسال RPCs بشفافية عبر مباراة Nakama في الوقت الفعلي.
للقيام بذلك، تحتاج إلى استخدام فئة 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"، يمكنك البدء في إرسال RPCs كالمعتاد باستخدام وظيفة rpc()
، واستدعاء أي وظائف أخرى مرتبطة بـ High-level Multiplayer API، مثل get_tree().get_multiplayer().get_unique_id()
و node.set_network_authority(peer_id)
و node.is_network_authority()
.
إذا كنت تستخدم إصدار .NET من Godot مع دعم C#، فيمكنك استخدام عميل Nakama .NET، والذي يمكن تثبيته عبر NuGet:
dotnet add package NakamaClient
يتضمن هذا الملحق بعض فئات C# للاستخدام مع عميل .NET، لتوفير تكامل أعمق مع Godot:
GodotLogger
: مسجل يقوم بالطباعة على وحدة تحكم Godot.GodotHttpAdapter
: محول HTTP يستخدم عقدة Godot's HTTPRequest.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 Client للتواصل مع 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
لجعل الإصدار الجديد جاهزًا للتوزيع، ما عليك سوى ضغط مجلد الإضافات بشكل متكرر (ربما إضافة CHANGELOG
و LICENSE
و README.md
أيضًا).
على أنظمة يونكس، يمكنك تشغيل الأمر التالي (استبدال $VERSION
برقم الإصدار المطلوب). تذكر تحديث ملف CHANGELOG
أولاً.
zip -r nakama- $VERSION .zip addons/ LICENSE CHANGELOG.md README.md
تم ترخيص هذا المشروع بموجب ترخيص Apache-2.