### Install godobuf Library Source: https://iohao.github.io/game/docs/examples/sdk_godot Clone the godobuf repository to your local machine to begin the setup process. ```bash git clone https://github.com/oniksan/godobuf.git ``` -------------------------------- ### Install and Run Vue Project Source: https://iohao.github.io/game/docs/examples/example_sdk_vue Commands to install dependencies and start the development server for the Vue project. ```bash npm install ``` ```bash npm run dev ``` -------------------------------- ### Start Server Application Source: https://iohao.github.io/game/docs/examples/client/example_unity_move Execute the generated JAR file to start the game server. ```bash java -jar target/mmo_server_demo.jar ``` -------------------------------- ### Start Game External Server Source: https://iohao.github.io/game/docs/manual/netty_run_one_non Configures and starts the external server on a specified port. ```java public static void main(String[] args) { ExternalServer externalServer = new MyExternalServer() .createExternalServer(ExternalGlobalConfig.externalPort); externalServer.startup(); } ``` -------------------------------- ### Start Game Logic Server Source: https://iohao.github.io/game/docs/manual/netty_run_one_non Starts the logic server using the BrokerClientApplication helper. ```java public static void main(String[] args) { WeatherLogicStartup weatherLogicStartup = new WeatherLogicStartup(); BrokerClientApplication.start(weatherLogicStartup); } ``` -------------------------------- ### Start Game Gateway Source: https://iohao.github.io/game/docs/manual/netty_run_one_non Initializes and starts the broker server instance. ```java public static void main(String[] args) throws Exception { BrokerServer brokerServer = new MyBrokerServer().createBrokerServer(); brokerServer.startup(); TimeUnit.SECONDS.sleep(1); } ``` -------------------------------- ### Configure and Start Multiple Logic Servers Source: https://iohao.github.io/game/docs/communication/request_multiple_response Initializes a hall server and multiple room servers using a broker client builder, then starts the network helper. ```java public class DemoInteractionSameApplication { public static void main(String[] args) { // cn: 创建 3 个房间逻辑服 // Create 3 DemoSameRoomLogicServer DemoSameRoomLogicServer roomServer1 = createRoomServer(1); DemoSameRoomLogicServer roomServer2 = createRoomServer(2); DemoSameRoomLogicServer roomServer3 = createRoomServer(3); // logicList. cn: 逻辑服列表 List logicList = List.of( // DemoSameHallLogicServer new DemoSameHallLogicServer(), // DemoSameRoomLogicServer: 1、2、3 roomServer1, roomServer2, roomServer3 ); // 游戏对外服端口 int port = 10100; NettySimpleHelper.run(port, logicList); } private static DemoSameRoomLogicServer createRoomServer(int id) { // BrokerClient 构建器,房间逻辑服的信息 BrokerClientBuilder brokerClientBuilder = BrokerClient.newBuilder() // cn: 逻辑服的唯一 id // gameLogicServer id .id(String.valueOf(id)) // cn: 游戏逻辑服名字 // gameLogicServer name. .appName("DemoSameRoomLogicServer-" + id) // cn: 同类型标签 // gameLogicServer tag. .tag("DemoSameRoomLogicServer"); // cn: 创建房间逻辑服 // Create DemoSameRoomLogicServer DemoSameRoomLogicServer roomLogicServer = new DemoSameRoomLogicServer(); roomLogicServer.setBrokerClientBuilder(brokerClientBuilder); return roomLogicServer; } } ``` -------------------------------- ### Clone Example Source Code Source: https://iohao.github.io/game/docs/quick_zero_demo Use this command to download the sample project repository. ```bash git clone https://github.com/iohao/ioGameSimpleOne.git ``` -------------------------------- ### Configure Application Startup Source: https://iohao.github.io/game/docs/manual/binding_logic_server Initializes the matching and room logic servers and starts the network helper. ```java public class DemoEndPointApplication { ... public static void main(String[] args) { DemoEndPointRoomServer roomServer1 = createRoomServer(1); DemoEndPointRoomServer roomServer2 = createRoomServer(2); List logicList = List.of( new DemoEndPointMatchServer(), roomServer1, roomServer2 ); NettySimpleHelper.run(ExternalGlobalConfig.externalPort, logicList); } } ``` -------------------------------- ### Initialize Simulation Client Source: https://iohao.github.io/game/docs/quick_zero_demo Configure and start the simulation client by registering the command regions. ```java public class DemoClient { public static void main(String[] args) { // closeLog. cn:关闭模拟请求相关日志 ClientUserConfigs.closeLog(); // Startup Client. cn:启动模拟客户端 new ClientRunOne() .setInputCommandRegions(List.of(new DemoRegion())) .startup(); } } ``` -------------------------------- ### Clone and Install ioGame from Source Source: https://iohao.github.io/game/docs/installation Download the source code and install it to your local Maven repository. ```bash git clone https://github.com/iohao/ioGame.git ``` ```bash mvnd install ``` -------------------------------- ### Install light-profile dependency Source: https://iohao.github.io/game/docs/extension_module/profile 在 pom.xml 中引入 light-profile 模块以启用多环境配置功能。 ```xml com.iohao.game light-profile ${ioGame.version} ``` -------------------------------- ### Start Game Server Source: https://iohao.github.io/game/docs/quick_zero_demo Initializes and runs the game server using NettySimpleHelper on a specified port. ```java public class DemoApplication { public static void main(String[] args) { int port = 10100; var demoLogicServer = new DemoLogicServer(); NettySimpleHelper.run(port, List.of(demoLogicServer)); } } ``` -------------------------------- ### Run Server JAR Source: https://iohao.github.io/game/docs/quick_zero_demo Execute the generated JAR file to start the server. ```bash java -jar simple-one-1.0-SNAPSHOT-jar-with-dependencies.jar ``` -------------------------------- ### Start Simulated Client Source: https://iohao.github.io/game/docs/manual/binding_logic_server Initializes a client endpoint with specific command regions to observe communication. ```java public class DemoForEndPointClient { public static void main(String[] args) { List inputCommandRegions = List.of( new InternalMatchRegion() , new InternalRoomRegion() ); new ClientRunOne() .setInputCommandRegions(inputCommandRegions) .startup(); } } ``` -------------------------------- ### Thread Monitor Plugin Output Example Source: https://iohao.github.io/game/docs/core_plugin/action_thread_monitor Example output showing the status of various business threads including execution count, average time, and remaining tasks. ```text 业务线程[RequestMessage-8-1] 共执行了 1 次业务,平均耗时 1 ms, 剩余 91 个任务未执行 业务线程[RequestMessage-8-2] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行 业务线程[RequestMessage-8-3] 共执行了 1 次业务,平均耗时 1 ms, 剩余 36 个任务未执行 业务线程[RequestMessage-8-4] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行 业务线程[RequestMessage-8-5] 共执行了 1 次业务,平均耗时 1 ms, 剩余 88 个任务未执行 业务线程[RequestMessage-8-6] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行 业务线程[RequestMessage-8-7] 共执行了 7 次业务,平均耗时 1 ms, 剩余 56 个任务未执行 业务线程[RequestMessage-8-8] 共执行了 1 次业务,平均耗时 1 ms, 剩余 0 个任务未执行 ``` -------------------------------- ### Verify Maven and Java Installation Source: https://iohao.github.io/game/docs/installation Check the installed versions of Maven and Java in the terminal to ensure they meet the requirements. ```text Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63) Maven home: /Users/join/soft/bash_profile/apache-maven-3.8.6 Java version: 21, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home Default locale: zh_CN_#Hans, platform encoding: UTF-8 OS name: "mac os x", version: "14.2.1", arch: "x86_64", family: "mac" ``` -------------------------------- ### Install TypeScript SDK Source: https://iohao.github.io/game/docs/examples/sdk_ts Command to install the ioGame SDK package via npm. ```bash npm i iohao-sdk ``` -------------------------------- ### Configure Network Settings Source: https://iohao.github.io/game/docs/examples/sdk_ts Setup the network connection and message callbacks for the ioGame client. ```typescript export class YourNetConfig { static startNet() { // --------- IoGameSetting --------- ioGameSetting.enableDevMode = true; // China or Us ioGameSetting.language = ioGameLanguage.CHINA; // message callback. cn: 回调监听 ioGameSetting.listenMessageCallback = new YourListenMessageCallback(); // socket ioGameSetting.url = "ws://127.0.0.1:10100/websocket"; ioGameSetting.netChannel = new YourNetChannel(); ioGameSetting.startNet() } } ``` -------------------------------- ### Start Multiple Servers in a Single Process Source: https://iohao.github.io/game/docs/manual/netty_run_one Initializes the external server, broker server, and logic server list, then uses NettyRunOne to launch them in a single process. ```java public class MyOneApplication { public static void main(String[] args) { ExternalServer externalServer = new MyExternalServer() .createExternalServer(ExternalGlobalConfig.externalPort); BrokerServer brokerServer = new MyBrokerServer() .createBrokerServer(); WeatherLogicStartup weatherLogicStartup = new WeatherLogicStartup(); List logicServerList = List.of(weatherLogicStartup); new NettyRunOne() .setExternalServer(externalServer) .setBrokerServer(brokerServer) .setLogicServerList(logicServerList) .startup(); } } ``` -------------------------------- ### Start Game Gateway Server Source: https://iohao.github.io/game/docs/quick_zero_demo Initializes and starts the game gateway server, which defaults to port 10200. ```java public static void main(String[] args) { BrokerServerBuilder brokerServerBuilder = BrokerServer.newBuilder(); brokerServerBuilder.build().startup(); } ``` -------------------------------- ### Configure Spring Application Startup Source: https://iohao.github.io/game/docs/manual/integration_spring Initializes the Spring application and starts the ioGame server, including the required ActionFactoryBeanForSpring bean. ```java @SpringBootApplication public class DemoSpringApplication { public static void main(String[] args) { SpringApplication.run(DemoSpringApplication.class, args); int port = ExternalGlobalConfig.externalPort; var demoLogicServer = new DemoSpringLogicServer(); NettySimpleHelper.run(port, List.of(demoLogicServer)); } @Bean public ActionFactoryBeanForSpring actionFactoryBean() { return ActionFactoryBeanForSpring.me(); } } ``` -------------------------------- ### Install Domain Event Module Source: https://iohao.github.io/game/docs/extension_module/domain_event Add the light-domain-event dependency to your project's pom.xml. ```xml com.iohao.game light-domain-event ${ioGame.version} ``` -------------------------------- ### Client Interaction Test Source: https://iohao.github.io/game/docs/communication/request_multiple_response Demonstrates a client setup that executes a command request after a short delay. ```java public class DemoInteractionSameClient { public static void main(String[] args) { ClientUserConfigs.closeLog(); List inputCommandRegions = List.of( new InternalRegion() ); new ClientRunOne() .setInputCommandRegions(inputCommandRegions) .startup(); } static class InternalRegion extends AbstractInputCommandRegion { @Override public void initInputCommand() { inputCommandCreate.cmd = DemoHallCmd.cmd; ofCommand(DemoHallCmd.count).setTitle("count"); TaskKit.runOnce(() -> { ofRequestCommand(DemoHallCmd.count).execute(); }, 10, TimeUnit.MILLISECONDS); } } } ``` -------------------------------- ### Int Action Controller Examples Source: https://iohao.github.io/game/docs/manual/protocol_fragment Demonstrates recommended primitive style versus wrapper class style for handling integer data in action controllers. ```java @ActionController(6) public class IntAction { @ActionMethod(10) public int int2int(int value) { return value + 1; } @ActionMethod(12) public List intList2intList(List intList) { return List.of(1, 2); } } ``` ```java @ActionController(6) public class IntAction { @ActionMethod(11) public IntValue intValue2intValue(IntValue intValue) { IntValue newIntValue = new IntValue(); newIntValue.value = intValue.value + 1; return newIntValue; } @ActionMethod(13) public IntValueList intValueList2intValueList(IntValueList intValueList) { List list = new ArrayList<>(); list.add(1); list.add(2); IntValueList newIntValueList = new IntValueList(); newIntValueList.values = list; return newIntValueList; } } ``` -------------------------------- ### Initialize Stress Test Client Source: https://iohao.github.io/game/docs/extension_module/simulation_client Configures and starts multiple client users to perform automated login and request tasks. ```java public class PressureClient { public static void main(String[] args) throws InterruptedException { ClientUserConfigs.closeScanner = true; ClientUserConfigs.closeLog(); int userSize = 80; for (int i = 1; i <= userSize; i++) { long userId = i; TaskKit.execute(() -> start(userId)); } TimeUnit.SECONDS.sleep(1); } static void start(long userId) { ClientUser clientUser = new DefaultClientUser(); String jwt = String.valueOf(userId); clientUser.setJwt(jwt); TaskKit.runOnceSecond(() -> { CmdInfo cmdInfo = LoginCmd.of(LoginCmd.login); clientUser.getClientUserInputCommands() .ofRequestCommand(cmdInfo) .requestCommand.execute(); }); List inputCommandRegions = List.of( new LoginInputCommandRegion() , new PressureInputCommandRegion() ); new ClientRunOne() .setClientUser(clientUser) .setInputCommandRegions(inputCommandRegions) .startup(); } } ``` -------------------------------- ### Long Action Controller Examples Source: https://iohao.github.io/game/docs/manual/protocol_fragment Demonstrates recommended primitive style versus wrapper class style for handling long data in action controllers. ```java @ActionController(6) public class LongAction { @ActionMethod(20) public long long2long(long value) { return value + 1; } @ActionMethod(22) public List longList2longList(List longList) { return List.of(1L, 2L); } } ``` ```java @ActionController(6) public class LongAction { @ActionMethod(21) public LongValue longValue2longValue(LongValue longValue) { LongValue newLongValue = new LongValue(); newLongValue.value = longValue.value + 1; return newLongValue; } @ActionMethod(23) public LongValueList LongValueList2longValueList(LongValueList longValueList) { List list = new ArrayList<>(); list.add(1L); list.add(2L); LongValueList newLongValueList = new LongValueList(); newLongValueList.values = list; return newLongValueList; } } ``` -------------------------------- ### Basic Client Startup Source: https://iohao.github.io/game/docs/extension_module/simulation_client Initializes the simulation client with a custom InputCommandRegion. ```java public class DemoClient { public static void main(String[] args) { new ClientRunOne() .setInputCommandRegions(List.of(new DemoRegion())) .startup(); } } ``` -------------------------------- ### 实现 startupSuccess 回调 Source: https://iohao.github.io/game/docs/overall/logic_intro 在逻辑服启动成功后执行,可用于获取业务框架、逻辑服对象或 EventBus 的引用。 ```java public class DemoLogicServer extends AbstractBrokerClientStartup { ... @Override public void startupSuccess(BrokerClient brokerClient) { // BarSkeleton barSkeleton = brokerClient.getBarSkeleton(); // ExecutorRegion executorRegion = barSkeleton.getExecutorRegion(); // EventBus eventBus = barSkeleton.option(SkeletonAttr.eventBus); // barSkeleton.option(SkeletonAttr.brokerClientContext); } } ``` -------------------------------- ### Registering ThreadMonitorInOut Source: https://iohao.github.io/game/docs/core_plugin/action_thread_monitor Basic setup to add the ThreadMonitorInOut plugin to the BarSkeletonBuilder. ```java BarSkeletonBuilder builder = ...; builder.addInOut(new ThreadMonitorInOut()); ``` -------------------------------- ### Install Light-jprotobuf Dependency Source: https://iohao.github.io/game/docs/extension_module/jprotobuf Add the light-jprotobuf dependency to your Maven pom.xml file. ```xml com.iohao.game light-jprotobuf ${ioGame.version} ``` -------------------------------- ### Implement Room Logic Server Source: https://iohao.github.io/game/docs/communication/request_multiple_response Defines the action to return room counts and the server startup configuration. ```java @ActionController(9) public class DemoRoomAction { @ActionMethod(0) public RoomNumMsg countRoom() { RoomNumMsg roomNumMsg = new RoomNumMsg(); roomNumMsg.roomCount = RandomKit.random(1, 100); return roomNumMsg; } } public class DemoSameRoomLogicServer extends AbstractBrokerClientStartup { @Override public BarSkeleton createBarSkeleton() { var config = new BarSkeletonBuilderParamConfig() .scanActionPackage(DemoRoomAction.class); var builder = config.createBuilder(); builder.addInOut(new DebugInOut()); return builder.build(); } @Override public BrokerClientBuilder createBrokerClientBuilder() { return null; } } ``` -------------------------------- ### Build Server Project Source: https://iohao.github.io/game/docs/examples/client/example_unity_move Compile the Java project using Maven. ```bash mvn package ``` -------------------------------- ### Register Custom EventBusListener Source: https://iohao.github.io/game/docs/communication/event_bus Configure the EventBus listener within the BarSkeletonBuilder during the application setup. ```java BarSkeletonBuilder builder = ...; builder.addRunner(new EventBusRunner() { @Override public void registerEventBus(EventBus eventBus, BarSkeleton skeleton) { eventBus.setEventBusListener(new YourEventBusListener()); } }); ``` -------------------------------- ### Docker Deployment Commands Source: https://iohao.github.io/game/docs/examples/server/example_spring_boot Commands for building, verifying, and running the game server as a Docker container. ```bash mvnd package ``` ```bash docker build -t spring-z-one-game . ``` ```bash docker images spring-z-one-game ``` ```bash docker run --name spring-z-one-game -p 10100:10100 spring-z-one-game ``` -------------------------------- ### Navigate to Server Directory Source: https://iohao.github.io/game/docs/examples/client/example_unity_move Change the current working directory to the server project folder. ```bash cd ioGame-mmo-movement ``` -------------------------------- ### Traditional Validation Pattern Source: https://iohao.github.io/game/docs/manual/assert_game_code Example of traditional if-else validation logic that leads to cluttered code. ```java public void hello() { if (gold < 500) { xxx.send(userId, new TheErrorCode(goldCode)); log.error(goldCode + "-" + userId) return; } if (level < 20) { xxx.send(userId, new TheErrorCode(levelCode)); log.error(levelCode + "-" + userId) return; } if (age < 18) { xxx.send(userId, new TheErrorCode(agelCode)); log.error(agelCode + "-" + userId) return; } } ``` -------------------------------- ### Server Console Debug Output Source: https://iohao.github.io/game/docs/quick_zero_demo Example of the debug information printed to the server console when requests are processed. ```text ┏━━━━━ Debug. [(DemoAction.java:43).here] ━━━━━ [cmd:1-0 65536] ━━━━━ [demoLogicServer] ━━━━━ [id:3977a25f-c8ad-4631-bff8-3ef07520bc1e] ┣ userId: 0 ┣ 参数: helloMessage : HelloMessage{name='1'} ┣ 响应: HelloMessage{name='1, I'm here'} ┣ 耗时: 9 ms ┗━━━━━ [ioGame:21.27] ━━━━━ [线程:User-8-8] ━━━━━ [连接方式:WebSocket] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┏━━━━━ Error. [(DemoAction.java:56).jackson] ━━━ [cmd:1-1 65537] ━━━ [demoLogicServer] ━━━ [id:3977a25f-c8ad-4631-bff8-3ef07520bc1e] ┣ userId: 0 ┣ 参数: helloMessage : HelloMessage{name='1'} ┣ 错误码: 100 ┣ 错误信息: The name must be Jackson ┣ 耗时: 0 ms ┗━━━━━ [ioGame:21.27] ━━━━━ [线程:User-8-8] ━━━━━ [连接方式:WebSocket] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┏━━━━━ Debug. [(DemoAction.java:69).list] ━━━━━ [cmd:1-2 65538] ━━━━━ [demoLogicServer] ━━━━━ [id:3977a25f-c8ad-4631-bff8-3ef07520bc1e] ┣ userId: 0 ┣ 参数: : ┣ 响应: [HelloMessage{name='data:1'}, HelloMessage{name='data:2'}, HelloMessage{name='data:3'}, HelloMessage{name='data:4'}] ┣ 耗时: 2 ms ┗━━━━━ [ioGame:21.27] ━━━━━ [线程:User-8-8] ━━━━━ [连接方式:WebSocket] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` -------------------------------- ### Defining a Data Protocol with Protobuf Source: https://iohao.github.io/game/docs/manual/action Example of a data protocol class using @ProtobufClass for client-server communication. ```java @ProtobufClass public class HelloMessage { public String name; } ``` -------------------------------- ### 使用 TaskKit 执行简单延时任务 Source: https://iohao.github.io/game/docs/kit/delay_task 通过 runOnce 方法快速执行简单的延时任务。 ```java TaskKit.runOnce(() -> log.info("2 Seconds"), 2, TimeUnit.SECONDS); TaskKit.runOnce(() -> log.info("1 Minute"), 1, TimeUnit.MINUTES) ``` -------------------------------- ### C# Action Client Implementation Source: https://iohao.github.io/game Demonstrates invoking server actions using both callback and async/await patterns in C#. ```csharp public async Task TestLoginVerify() { var loginVerifyMessage = new LoginVerifyMessage { Jwt = "10" }; // code style: callback. Advantages: simple, integrated. // cn: 编码风格:回调。 优点:简洁,一体化。 MyAction.OfLoginVerify(loginVerifyMessage, result => { var userMessage = result.GetValue(); result.Log(userMessage); }); // code style: async await. Advantages: Avoid callback hell. // cn: 编码风格:async await 机制。 优点:可避免回调地狱。 var result = await MyAction.OfAwaitLoginVerify(loginVerifyMessage); var userMessage = result.GetValue(); result.Log(userMessage); } public async Task TestIntValue() { const int value = 1; MyAction.OfIntValue(value, result => { result.Log(result.GetInt()); }); var result = await MyAction.OfAwaitIntValue(value); result.Log(result.GetInt()); } public async Task TestListString() { const string value = "hello"; MyAction.OfListString(value, result => { result.Log(result.ListString()); }); var result = await MyAction.OfAwaitListString(value); result.Log(result.ListString()); } ``` -------------------------------- ### Assertion Usage in Action Controller Source: https://iohao.github.io/game/docs/manual/assert_game_code Example of using GameCodeEnum assertions to validate business logic within an action method. ```java @ActionController(1) public class DemoAction { @ActionMethod(0) public boolean buyGoods(FlowContext flowContext) { long userId = flowContext.getUserId(); long gold = getGoldByUserId(userId); // When the assertion is true, an exception is thrown // cn: 断言是 true, 就抛出异常 GameCodeEnum.gold.assertTrueThrows(gold < 500); ... } } ``` -------------------------------- ### Initialize GM Logic Server Source: https://iohao.github.io/game/docs/manual_high/gm Saves the broker client instance reference during the logic server startup process. ```java public class GameManagerLogicServer extends AbstractBrokerClientStartup { ... @Override public void startupSuccess(BrokerClient brokerClient) { MyKit.brokerClient = brokerClient; MyKit.barSkeleton = brokerClient.getBarSkeleton(); } } ``` -------------------------------- ### Main Code Generation Configuration Source: https://iohao.github.io/game/docs/examples/code_generate The entry point for configuring the code generation process, including setting up the environment, loading logic servers, and triggering the generation of documentation and protocol files. ```java public final class GenerateTest { ... public static void main(String[] args) { // CHINA or US Locale.setDefault(Locale.CHINA); // Load the business framework of each gameLogicServer // 加载业务逻辑服 SdkApplication.listLogic().forEach(BrokerClientStartup::createBarSkeleton); /* * GameExternalServer accessAuthentication * 游戏对外服访问权限,不生成权限控制的 action */ SdkApplication.extractedAccess(); DocumentAccessAuthentication reject = ExternalGlobalConfig.accessAuthenticationHook::reject; IoGameDocumentHelper.setDocumentAccessAuthentication(reject); /* * Generate actions, broadcasts, and error codes. * cn: 生成 action、广播、错误码 */ // ----- About generating TypeScript code ----- // generateCodeVue(); // generateCocosCreator(); // ----- About generating C# code ----- // generateCodeCsharpGodot(); // generateCodeCsharpUnity(); // ----- About generating GDScript code ----- generateCodeGDScriptGodot(); // Added an enumeration error code class to generate error code related information IoGameDocumentHelper.addErrorCodeClass(SdkGameCodeEnum.class); // Generate document; IoGameDocumentHelper.generateDocument(); // Generate .proto generateProtoFile(); } static void generateProtoFile() { // By default, it will be generated in the target/proto directory // .proto 默认生成的目录为 target/proto // The package name to be scanned String packagePath = "com.ioaham.example.sdk.data"; GenerateFileKit.generate(packagePath); } } ``` -------------------------------- ### Defining an Action Controller and Methods Source: https://iohao.github.io/game/docs/manual/action Example of a standard action class using @ActionController and @ActionMethod annotations to define business logic routes. ```java @ActionController(1) public class DemoAction { @ActionMethod(0) public HelloMessage here(HelloMessage message) { message.name = message.name + ", I'm here "; return message; } @ActionMethod(1) public HelloMessage say(HelloMessage message) { message.name = message.name + ", I'm say "; return message; } } ``` -------------------------------- ### Broadcast Log Output Source: https://iohao.github.io/game/docs/communication/broadcast Example console output showing broadcast details including command info, user IDs, and message content. ```text ┏━━━━━ 广播. [(DemoBroadcastApplication.java:40)] ━━━ [cmd:7 - subCmd:0 - cmdMerge:458752] ┣ userId: 全服广播 ┣ 广播数据: DemoBroadcastMessage(msg=broadcast hello ,253) ┣ 广播时间: 2022-05-19 21:31:47.728 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┏━━━━━ 广播. [(DemoBroadcastApplication.java:40)] ━━━ [cmd:7 - subCmd:0 - cmdMerge:458752] ┣ userId: 1 ┣ 广播数据: DemoBroadcastMessage(msg=broadcast hello ,1) ┣ 广播时间: 2022-05-19 21:32:42.732 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┏━━━━━ 广播. [(TankAction.java:116)] ━━━ [cmd:2 - subCmd:7 - cmdMerge:131079] ┣ userId: [1,5,7] ┣ 广播数据: BarHelloPb(amount=7) ┣ 广播时间: 2022-07-14 18:31:02.253 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` -------------------------------- ### Configure ioGame SDK Network Source: https://iohao.github.io/game/docs/examples/example_sdk_vue Implementation of network configuration, including message callbacks, channel setup, login verification, and heartbeat synchronization. ```typescript export class MyNetConfig { public static currentTimeMillis: bigint = BigInt(Date.now()); static startNet() { // biz code init GameCode.init(); listen(); // --------- IoGameSetting --------- ioGameSetting.enableDevMode = true; // China or Us ioGameSetting.language = ioGameLanguage.CHINA; // message callback. 回调监听 ioGameSetting.listenMessageCallback = new MySimpleListenMessageCallback(); // socket ioGameSetting.url = "ws://127.0.0.1:10100/websocket"; ioGameSetting.netChannel = new MyNetChannel(); ioGameSetting.startNet() } } class MyNetChannel extends SimpleNetChannel { onOpen(event: Event) { // login const loginVerify = create(LoginVerifyMessageSchema, {jwt: "10000"}); SdkAction.ofLoginVerify(loginVerify, result => { const message = result.getValue(UserMessageSchema); result.log(message); }); // heartbeat const heartbeatMessage = toBinary(ExternalMessageSchema, create(ExternalMessageSchema, {})); setInterval(function () { // Send heartbeat to server. 发送心跳给服务器 ioGameSetting.netChannel.writeAndFlushUint8Array(heartbeatMessage); }, 8 * 1000); } } class MySimpleListenMessageCallback extends SimpleListenMessageCallback { onIdleCallback(message: NetExternalMessage) { const data = message.data; if (data === undefined || data.length === 0) return; /* * Synchronize the time of each heartbeat with that of the server. * 每次心跳与服务器的时间同步 */ const longValue = fromBinary(LongValueSchema, data); MyNetConfig.currentTimeMillis = longValue.value; } } ``` -------------------------------- ### Generate .proto via GenerateFileKit Source: https://iohao.github.io/game/docs/extension_module/jprotobuf Use the GenerateFileKit utility to scan a package and generate .proto files in the default target/proto directory. ```java void test1() { GenerateFileKit.generate("com.iohao.example.sdk.logic.data"); } ``` -------------------------------- ### Configure ioGame Network Settings Source: https://iohao.github.io/game/docs/examples/sdk_csharp Initializes the network configuration, including development mode, language settings, message callbacks, and console logging. ```csharp public abstract class YourNetConfig { public static void StartNet() { // --------- IoGameSetting --------- IoGameSetting.EnableDevMode = true; // China or Us IoGameSetting.SetLanguage(IoGameLanguage.China); // message callback. cn: 回调监听 IoGameSetting.ListenMessageCallback = new YourListenMessageCallback(); // Print. cn: 打印 IoGameSetting.GameGameConsole = new YourGameConsole(); // socket SocketInit(); IoGameSetting.StartNet(); } private static void SocketInit() { IoGameSetting.Url = "ws://127.0.0.1:10100/websocket"; // Setting up the Network Communication Implementation Class. // cn: 设置网络通信实现类。 IoGameSetting.NetChannel = new YourWebSocket(); } } ``` -------------------------------- ### 引入 Room 模块依赖 Source: https://iohao.github.io/game/docs/extension_module/room 在 Maven 项目的 pom.xml 文件中添加 light-game-room 依赖以使用房间模块功能。 ```xml com.iohao.game light-game-room ${ioGame.version} ``` -------------------------------- ### Execute tasks using virtual thread executors Source: https://iohao.github.io/game/docs/manual/flow_context Demonstrates submitting tasks to the user-associated virtual thread executor, including an example of updating attachments. ```java void executeVirtual() { flowContext.executeVirtual(() -> { // your code }); flowContext.getVirtualExecutor().execute(() -> { // your code }); // for example flowContext.executeVirtual(() -> { flowContext.updateAttachment(); }); } ``` -------------------------------- ### Generate Protocol and Documentation Source: https://iohao.github.io/game/docs/examples/server/example_spring_boot Use the TestGenerate class to generate .proto files and game documentation for frontend integration. ```java public class TestGenerate { public static void main(String[] args) { SpringGameOneApplication.listLogic().forEach(BrokerClientStartup::createBarSkeleton); IoGameDocumentHelper.addErrorCodeClass(SpringGameCodeEnum.class); IoGameDocumentHelper.generateDocument(); String packagePath = "com.iohao.game.spring.common"; GenerateFileKit.generate(packagePath); } } ``` -------------------------------- ### Broadcast Serialization Error Example Source: https://iohao.github.io/game/docs/communication/broadcast Avoid using List.of() for user lists as it causes serialization errors in the bolt RpcClient; use ArrayList instead. ```java var data = StringValue.of("biz data"); // error List userIdList = List.of(1L, 2L, 3L); broadcastContext.broadcast(cmdInfo, data, userIdList); ``` -------------------------------- ### Package and Run JAR Source: https://iohao.github.io/game/docs/examples/server/example_spring_boot Commands to package the Spring Boot application and execute the resulting JAR file. ```bash mvnd package ``` ```bash java -jar spring-z-one-game-1.0-SNAPSHOT.jar ``` -------------------------------- ### Schedule periodic tasks with TaskKit Source: https://iohao.github.io/game/docs/kit/task_kit Demonstrates basic interval scheduling using lambda expressions for simple recurring tasks. ```java public void runInterval() { TaskKit.runInterval(() -> log.info("tick 2 Seconds"), 2, TimeUnit.SECONDS); TaskKit.runInterval(() -> log.info("tick 30 Minute"), 30, TimeUnit.MINUTES); } ``` -------------------------------- ### Executing Tasks via FlowContext Source: https://iohao.github.io/game/docs/overall/thread_executor Provides examples of executing tasks using the executor retrieved from FlowContext or directly via the context's execute method. ```java Executor executor = flowContext.getExecutor(); executor.execute(() -> { // your code }); // or flowContext.execute(() -> { // your code }); ``` -------------------------------- ### Implement GM Web Controller Source: https://iohao.github.io/game/docs/manual_high/gm Demonstrates how to trigger game logic actions from a web controller using simulated user requests. ```java @Slf4j @RestController @RequestMapping("gm") public class GameManagerController { static final AtomicLong msgId = new AtomicLong(); static final long userId = 1; @GetMapping("/notice") public String notice() { long id = msgId.incrementAndGet(); String msg = "GM web message " + id; var noticeCmd = ExchangeCmd.of(ExchangeCmd.notice); RequestMessage requestMessage = BarMessageKit.createRequestMessage(noticeCmd, StringValue.of(msg)); requestMessage.getHeadMetadata().setUserId(userId); BrokerClient brokerClient = MyKit.brokerClient; brokerClient.getInvokeModuleContext().invokeModuleVoidMessage(requestMessage); return "notice: " + id; } @GetMapping("/recharge") public String recharge() { var rechargeCmd = ExchangeCmd.of(ExchangeCmd.recharge); long money = RandomKit.random(1, 1000); UserFlowContext userFlowContext = MyKit.ofUserFlowContext(userId); ResponseMessage responseMessage = userFlowContext.invokeModuleMessage(rechargeCmd, LongValue.of(money)); if (responseMessage.hasError()) { return "recharge error"; } String data = responseMessage.getString(); return "recharge: " + data; } } ``` -------------------------------- ### Defining a Basic Action Controller Source: https://iohao.github.io/game/docs/intro Demonstrates how a standard Java method serves as an action, utilizing annotations for routing and Jprotobuf for data handling. ```java @ActionController(1) public class DemoAction { @ActionMethod(1) public UserMessage jackson(LoginVerifyMessage message) { GameCode.nameChecked.assertTrue("Jackson".equals(message.jwt)); var userMessage = new UserMessage(); userMessage.name = "hello Jackson"; return userMessage; } } // GameCode. cn: 游戏错误码 public enum GameCode implements MsgExceptionInfo { /** 名字检查 */ nameChecked(100, "The name must be Jackson"); final int code; final String msg; GameCode(int code, String msg) { this.code = code; this.msg = msg; } } @ProtobufClass public class LoginVerifyMessage { public String jwt; } @ProtobufClass public class UserMessage { public String name; } ``` -------------------------------- ### Implement Matching Logic Action Source: https://iohao.github.io/game/docs/manual/binding_logic_server Handles the matching process by invoking multiple room logic servers and dynamically binding users to the server with the fewest rooms. ```java @ActionController(11) public class DemoMatchAction { ... @ActionMethod(DemoCmdForEndPointMatch.matching) public MatchResponse matching(FlowContext flowContext) { CmdInfo cmdInfo = CmdInfo.of(DemoCmdForEndPointRoom.cmd, DemoCmdForEndPointRoom.countRoom); ResponseCollectMessage responseCollectMessage = flowContext.invokeModuleCollectMessage(cmdInfo); ResponseCollectItemMessage minItemMessage = getMinItemMessage(responseCollectMessage); String logicServerId = minItemMessage.getLogicServerId(); List userIdList = new ArrayList<>(); userIdList.add(flowContext.getUserId()); EndPointLogicServerMessage endPointLogicServerMessage = new EndPointLogicServerMessage() .setUserList(userIdList) .addLogicServerId(logicServerId) .setOperation(EndPointOperationEnum.COVER_BINDING); ProcessorContext processorContext = BrokerClientHelper.getProcessorContext(); processorContext.invokeOneway(endPointLogicServerMessage); MatchResponse matchResponse = new MatchResponse(); matchResponse.matchSuccess = true; return matchResponse; } } ``` -------------------------------- ### Clone Server Source Code Source: https://iohao.github.io/game/docs/examples/client/example_unity_move Download the server-side repository from GitHub. ```bash git clone https://github.com/iohao/ioGame-mmo-movement.git ```