Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Membuat skrip Realtime
Untuk menggunakan Server Realtime untuk game Anda, Anda perlu menyediakan skrip (dalam bentuk beberapa JavaScript kode) untuk mengonfigurasi dan menyesuaikan armada Server Realtime secara opsional. Topik ini mencakup langkah-langkah kunci dalam membuat skrip Realtime. Setelah skrip siap, unggah ke GameLift layanan Amazon dan gunakan untuk membuat armada (lihatMenerapkan skrip untuk Server Realtime).
Untuk menyiapkan skrip untuk digunakan dengan Server Realtime, tambahkan fungsionalitas berikut ke skrip Realtime Anda.
Mengelola siklus hidup sesi permainan (wajib)
Minimal, skrip Realtime harus menyertakan fungsionalitas Init()
, yang mempersiapkan Server Realtime untuk memulai sesi game. Juga sangat disarankan agar Anda juga menyediakan cara untuk mengakhiri sesi game, untuk memastikan bahwa sesi game baru dapat terus dimulai di armada Anda.
fungsionalitas callback Init()
, ketika dipanggil, dilewatkan objek sesi Realtime, yang berisi antarmuka untuk server Realtime. Lihat Antarmuka Server Realtime untuk detail lebih lanjut tentang antarmuka ini.
Untuk mengakhiri sesi game dengan cakap, skrip juga harus memanggil fungsionalitas server Realtimesession.processEnding
. Hal ini memerlukan beberapa mekanisme untuk menentukan kapan harus mengakhiri sesi. Kode contoh skrip menggambarkan mekanisme sederhana yang memeriksa koneksi pemain dan memicu penghentian sesi game ketika tidak ada pemain yang terhubung ke sesi selama jangka waktu tertentu.
Server Realtime dengan konfigurasi paling basic--inisialisasi dan penghentian proses server--pada dasarnya bertindak sebagai server relai stateless. Server Realtime meneruskan pesan dan data game antara klien game yang terhubung ke game, tetapi tidak mengambil tindakan independen untuk memproses data atau menjalankan logika. Anda dapat secara opsional menambahkan logika game, yang dipicu oleh peristiwa game atau mekanisme lain, sesuai kebutuhan untuk game Anda.
Tambahkan logika permainan sisi server (opsional)
Anda dapat menambahkan logika game ke skrip Realtime Anda secara opsional. Misalnya, Anda dapat menjalankan perintah berikut. Kode contoh skrip memberikan ilustrasi. Lihat Referensi skrip Amazon GameLift Realtime Server.
-
Tambahkan logika berbasis peristiwa. Menerapkan fungsionalitas callback untuk menanggapi peristiwa client-server. Lihat Callback skrip untuk Server Realtime untuk daftar lengkap callback.
-
Memicu logika dengan mengirim pesan ke server. Buat satu set kode operasi khusus untuk pesan yang dikirim dari klien game ke server, dan tambahkan fungsionalitas untuk menangani tanda terima. Gunakan callback
onMessage
, dan kurangi konten pesan menggunakan antarmukagameMessage
(lihat gameMessage.opcode). -
Aktifkan logika game untuk mengakses sumber daya AWS. Untuk detailnya, lihat Berkomunikasi dengan AWS sumber daya lain dari armada Anda.
-
Izinkan logika game mengakses informasi armada untuk instans yang sedang dijalankan. Untuk detailnya, lihat Mendapatkan data armada untuk GameLift instans Amazon.
Contoh skrip Server Realtime
Contoh ini menggambarkan script basic yang diperlukan untuk men-deploy Server Realtime ditambah beberapa logika kustom. Ini berisi fungsionalitas Init()
yang diperlukan, dan menggunakan mekanisme pengatur waktu untuk memicu penghentian sesi game berdasarkan lamanya waktu tanpa koneksi pemain. Ini juga mencakup beberapa hook untuk logika kustom, termasuk beberapa implementasi callback.
// Example Realtime Server Script 'use strict'; // Example override configuration const configuration = { pingIntervalTime: 30000, maxPlayers: 32 }; // Timing mechanism used to trigger end of game session. Defines how long, in milliseconds, between each tick in the example tick loop const tickTime = 1000; // Defines how to long to wait in Seconds before beginning early termination check in the example tick loop const minimumElapsedTime = 120; var session; // The Realtime server session object var logger; // Log at appropriate level via .info(), .warn(), .error(), .debug() var startTime; // Records the time the process started var activePlayers = 0; // Records the number of connected players var onProcessStartedCalled = false; // Record if onProcessStarted has been called // Example custom op codes for user-defined messages // Any positive op code number can be defined here. These should match your client code. const OP_CODE_CUSTOM_OP1 = 111; const OP_CODE_CUSTOM_OP1_REPLY = 112; const OP_CODE_PLAYER_ACCEPTED = 113; const OP_CODE_DISCONNECT_NOTIFICATION = 114; // Example groups for user-defined groups // Any positive group number can be defined here. These should match your client code. // When referring to user-defined groups, "-1" represents all groups, "0" is reserved. const RED_TEAM_GROUP = 1; const BLUE_TEAM_GROUP = 2; // Called when game server is initialized, passed server's object of current session function init(rtSession) { session = rtSession; logger = session.getLogger(); } // On Process Started is called when the process has begun and we need to perform any // bootstrapping. This is where the developer should insert any code to prepare // the process to be able to host a game session, for example load some settings or set state // // Return true if the process has been appropriately prepared and it is okay to invoke the // GameLift ProcessReady() call. function onProcessStarted(args) { onProcessStartedCalled = true; logger.info("Starting process with args: " + args); logger.info("Ready to host games..."); return true; } // Called when a new game session is started on the process function onStartGameSession(gameSession) { // Complete any game session set-up // Set up an example tick loop to perform server initiated actions startTime = getTimeInS(); tickLoop(); } // Handle process termination if the process is being terminated by GameLift // You do not need to call ProcessEnding here function onProcessTerminate() { // Perform any clean up } // Return true if the process is healthy function onHealthCheck() { return true; } // On Player Connect is called when a player has passed initial validation // Return true if player should connect, false to reject function onPlayerConnect(connectMsg) { // Perform any validation needed for connectMsg.payload, connectMsg.peerId return true; } // Called when a Player is accepted into the game function onPlayerAccepted(player) { // This player was accepted -- let's send them a message const msg = session.newTextGameMessage(OP_CODE_PLAYER_ACCEPTED, player.peerId, "Peer " + player.peerId + " accepted"); session.sendReliableMessage(msg, player.peerId); activePlayers++; } // On Player Disconnect is called when a player has left or been forcibly terminated // Is only called for players that actually connected to the server and not those rejected by validation // This is called before the player is removed from the player list function onPlayerDisconnect(peerId) { // send a message to each remaining player letting them know about the disconnect const outMessage = session.newTextGameMessage(OP_CODE_DISCONNECT_NOTIFICATION, session.getServerId(), "Peer " + peerId + " disconnected"); session.getPlayers().forEach((player, playerId) => { if (playerId != peerId) { session.sendReliableMessage(outMessage, playerId); } }); activePlayers--; } // Handle a message to the server function onMessage(gameMessage) { switch (gameMessage.opCode) { case OP_CODE_CUSTOM_OP1: { // do operation 1 with gameMessage.payload for example sendToGroup const outMessage = session.newTextGameMessage(OP_CODE_CUSTOM_OP1_REPLY, session.getServerId(), gameMessage.payload); session.sendGroupMessage(outMessage, RED_TEAM_GROUP); break; } } } // Return true if the send should be allowed function onSendToPlayer(gameMessage) { // This example rejects any payloads containing "Reject" return (!gameMessage.getPayloadAsText().includes("Reject")); } // Return true if the send to group should be allowed // Use gameMessage.getPayloadAsText() to get the message contents function onSendToGroup(gameMessage) { return true; } // Return true if the player is allowed to join the group function onPlayerJoinGroup(groupId, peerId) { return true; } // Return true if the player is allowed to leave the group function onPlayerLeaveGroup(groupId, peerId) { return true; } // A simple tick loop example // Checks to see if a minimum amount of time has passed before seeing if the game has ended async function tickLoop() { const elapsedTime = getTimeInS() - startTime; logger.info("Tick... " + elapsedTime + " activePlayers: " + activePlayers); // In Tick loop - see if all players have left early after a minimum period of time has passed // Call processEnding() to terminate the process and quit if ( (activePlayers == 0) && (elapsedTime > minimumElapsedTime)) { logger.info("All players disconnected. Ending game"); const outcome = await session.processEnding(); logger.info("Completed process ending with: " + outcome); process.exit(0); } else { setTimeout(tickLoop, tickTime); } } // Calculates the current time in seconds function getTimeInS() { return Math.round(new Date().getTime()/1000); } exports.ssExports = { configuration: configuration, init: init, onProcessStarted: onProcessStarted, onMessage: onMessage, onPlayerConnect: onPlayerConnect, onPlayerAccepted: onPlayerAccepted, onPlayerDisconnect: onPlayerDisconnect, onSendToPlayer: onSendToPlayer, onSendToGroup: onSendToGroup, onPlayerJoinGroup: onPlayerJoinGroup, onPlayerLeaveGroup: onPlayerLeaveGroup, onStartGameSession: onStartGameSession, onProcessTerminate: onProcessTerminate, onHealthCheck: onHealthCheck };