Tài liệu này giải thích chi tiết cách project Ezytank tích hợp và sử dụng game-master-server-plugin để quản lý các phòng chơi (game instances) từ backend đến client.

Dự án Ezytank không tự xây dựng logic quản lý phòng chơi. Thay vào đó, Ezytank tận dụng plugin game-master-server như một module có sẵn của EzyPlatform bằng cách tích hợp các thành phần của nó vào hai module chính:

  1. ezytank-admin-plugin: Tích hợp giao diện và API admin của game-master-server, cho phép quản trị viên cấu hình và quản lý các máy chủ gameplay.
  2. ezytank-web-plugin: Tích hợp các API web của game-master-server, cho phép client (ứng dụng khách gameplay) truy vấn danh sách phòng chơi.

Cách này giúp Ezytank kế thừa toàn bộ chức năng mạnh mẽ của game-master-server mà không cần viết lại logic, chỉ cần khai báo dependency là xong.

Tích hợp backend

Để tích hợp game-master-server vào Ezytank:

  • Khai báo dependency trong pom.xml:
<!-- File: ezytank-admin-plugin/pom.xml -->
<dependencies>
        ...
        <dependency>
            <groupId>org.youngmonkeys</groupId>
            <artifactId>game-master-server-sdk</artifactId>
            <version>${game.master.server.version}</version>
            <scope>system</scope>
            <systemPath>${ezyplatform.home}/admin/plugins/game-master-server/lib/game-master-server-sdk-${game.master.server.version}.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.youngmonkeys</groupId>
            <artifactId>game-master-server-admin-plugin</artifactId>
            <version>${game.master.server.version}</version>
            <scope>system</scope>
            <systemPath>${ezyplatform.home}/admin/plugins/game-master-server/lib/game-master-server-admin-plugin-${game.master.server.version}.jar
            </systemPath>
        </dependency>
        ...
</dependencies>

...
                <resources>
                    ...
                    <resource>
                        <directory>${ezyplatform.home}/admin/plugins/game-master-server/resources</directory>
                    </resource>
                    ...
                </resources>
File: ezytank-web-plugin/pom.xml
    <dependencies>
        ...
        <dependency>
            <groupId>org.youngmonkeys</groupId>
            <artifactId>game-master-server-sdk</artifactId>
            <version>${game.master.server.version}</version>
            <scope>system</scope>
            <systemPath>${ezyplatform.home}/web/plugins/game-master-server/lib/game-master-server-sdk-${game.master.server.version}.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.youngmonkeys</groupId>
            <artifactId>game-master-server-web-plugin</artifactId>
            <version>${game.master.server.version}</version>
            <scope>system</scope>
            <systemPath>${ezyplatform.home}/web/plugins/game-master-server/lib/game-master-server-web-plugin-${game.master.server.version}.jar
            </systemPath>
        </dependency>
        ...
    </dependencies>
...
                <resources>
                    ...
                    <resource>
                        <directory>${ezyplatform.home}/web/plugins/game-master-server/resources</directory>
                    </resource>
                    ...
                </resources>
  • Khai báo dependency trong module.properties:
# File: ezytank-admin-plugin/module.properties
...
dependencies=ezymail,ezylogin,ezyarticle,game-master-server
# File: ezytank-web-plugin/module.properties
...
dependencies=ezymail,ezylogin,ezyarticle,game-master-server
  • Build máy chủ gameplay unity theo hướng dẫn ở đây. Lưu thư mục build ở đường dẫn ezytank/ezytank-admin-plugin/src/main/resources/static/ezytank/unity
  • Mở terminal lên và chạy lệnh:
cd ezytank
bash export.sh
  • Sau đó bạn có thể chạy Ezyplatform từ terminal hoặc từ IDE và truy cập địa chỉ admin (thường là http://localhost:9090/)
  • Bấm chọn Game Master Server bên menu tay trái, và chọn Instances
  • Nhập quantity = 2 và bấm nút "Tạo"
  • Chờ vài giây và refresh trang, 2 máy chủ gameplay được tạo và có trạng thái "AVAILABLE"
Screenshot from 2025-09-23 15-31-12.png

Tích hợp phía Client

Phía client Unity, LobbyHttpController.cs chịu trách nhiệm gửi HTTP request đến backend để lấy danh sách phòng.

// File: ezytank-unity/Assets/Scripts/Controller/LobbyHttpController.cs

using System;
using UnityEngine;

namespace Youngmonkeys.EzyTank
{
	public class LobbyHttpController : SceneSingleton<LobbyHttpController>
	{
		public void SendGetRoomsRequest(
			string nextPageToken,
			Action<PaginationModel<RoomModel>> handler
		)
		{
			var pageTokenParam = nextPageToken == null ? "" : "?nextPageToken=" + nextPageToken;
			HttpGetRequest request = new HttpGetRequest(
				HttpUtils.ToApiUrl($"/game-master-server/instances{pageTokenParam}"),
				PlayerPrefs.GetString("accessToken")
			);
			HttpClient.Instance.SendHttpRequest<HttpGetRequest, PaginationResponse<RoomResponse>>(
				request,
				response => handler.Invoke(HttpResponseToModelConverter.ToModel(response))
			);
		}
	}
}

Endpoint /api/v1/game-master-server/instances này được cung cấp bởi game-master-server-web-plugin.

  • Các phòng chơi (rooms) ở đây chính là các máy chủ gameplay unity vì mỗi máy chủ gameplay ứng với một phòng. Thông tin mỗi phòng sẽ chứa socket port của máy chủ unity tương ứng.
  • Dựa vào thông tin socket port vừa lấy được và address đã được cấu hình ở GameConfigManager.Instance.GameConfig.Socket.Address, ứng dụng khách gameplay sẽ có thể gửi yêu cầu kết nối đến máy chủ gameplay unity khi người chơi chọn tham gia một phòng. Bạn có thể tham khảo chi tiết ở file ezytank-unity/Assets/Scripts/Presenter/LobbyRoomPresenter.cs:

using UnityEngine;

namespace Youngmonkeys.EzyTank
{
	public class LobbyRoomPresenter : SceneSingleton<LobbyRoomPresenter>
	{
            ...
		public void JoinRoom(int roomId)
		{
			RoomModel room = RoomRepo.Instance.GetRoomById(roomId);
			ClientNetworkStreamDriverEntryPresenter.Instance.StartClientAndServer(
				GameConfigManager.Instance.GameConfig.Socket.Address,
				room.Port.ToString()
			);
		}
           ...
	}
}

Tóm tắt luồng hoạt động hoàn chỉnh

  1. Tích hợp: Lập trình viên khai báo dependency của game-master-server trong các file pom.xmlmodule.properties.
  2. Cấu hình máy chủ: Quản trị viên tạo các phòng chơi (các máy chủ gameplay) trong giao diện admin của game-master-server.
  3. Lấy danh sách phòng: Người chơi mở game và ứng dụng khách gameplay gửi request GET /api/v1/game-master/server/instances đến máy chủ web.
  4. Phản hồi: game-master-server-web-plugin trên máy chủ web nhận request, lấy danh sách các Instance đang "AVAILABLE" và trả về cho ứng dụng khách gameplay.
  5. Yêu cầu kết nối: Người chơi chọn một phòng, ứng dụng khách gameplay lúc này sẽ biết port của máy chủ gameplay tương ứng phòng đó và có thể gửi yêu cầu kết nối đến nó.
  6. Vào phòng chơi: Nếu máy chủ gameplay chấp nhận yêu cầu kết nối, ứng dụng khách gameplay và máy chủ gameplay sẽ kết nối đến nhau và người chơi vào phòng chơi thành công.