DEV Community

Aceld
Aceld

Posted on • Updated on

16. Online Location Information Synchronization

[Zinx]

<1.Building Basic Services with Zinx Framework>
<2. Zinx-V0.2 Simple Connection Encapsulation and Binding with Business>
<3.Design and Implementation of the Zinx Framework's Routing Module>
<4.Zinx Global Configuration>
<5.Zinx Message Encapsulation Module Design and Implementation>
<6.Design and Implementation of Zinx Multi-Router Mode>
<7. Building Zinx's Read-Write Separation Model>
<8.Zinx Message Queue and Task Worker Pool Design and Implementation>
<9. Zinx Connection Management and Property Setting>

[Zinx Application - MMO Game Case Study]

<10. Application Case Study using the Zinx Framework>
<11. MMO Online Game AOI Algorithm>
<12.Data Transmission Protocol: Protocol Buffers>
<13. MMO Game Server Application Protocol>
<14. Building the Project and User Login>
<15. World Chat System Implementation>
<16. Online Location Information Synchronization>
<17. Moving position and non-crossing grid AOI broadcasting>
<18. Player Logout>
<19. Movement and AOI Broadcast Across Grids>


MMO-GAME Source Code

https://github.com/aceld/zinx/tree/master/zinx_app_demo/mmo_game


Online location information synchronization means that when a new user logs into the server, the current location information of the new player should be synchronized to other players who are online within a certain range. This information will be displayed on the clients of other players, showing the current location of the newly logged-in player, and so on. At the same time, the location information of all players in the vicinity should also be synchronized to the newly logged-in player, allowing them to see the location information of other online players within their field of view. The specific process is illustrated in Figure 16.1.

Figure 16.1

Figure 16.1

The above process involves MsgID 202 with the protocol SyncPlayers. To incorporate this into the Proto file, two new messages should be added in the msg.proto data protocol, as shown below:

//mmo_game/pb/msg.proto

// Player information
message Player {
    int32 Pid = 1;
    Position P = 2;
}

// Synchronize player display data
message SyncPlayers {
    repeated Player ps = 1;
}
Enter fullscreen mode Exit fullscreen mode

Once defined, execute the pre-edited build.sh script to generate the new msg.proto.go file. Next, provide a method SyncSurrounding() for the Player to synchronize their position. The idea is to broadcast their own location information to surrounding players so that those players can display them. The specific method implementation is as follows:

//mmo_game/core/player.go

// Broadcast one's own location to players in the surrounding (nine-grid) area to make them visible
func (p *Player) SyncSurrounding() {
    // 1. Get the player PIDs within the nine-grid area based on one's own position
    pids := WorldMgrObj.AoiMgr.GetPidsByPos(p.X, p.Z)

    // 2. Get all player objects based on PIDs
    players := make([]*Player, 0, len(pids))

    // 3. Send MsgID:200 messages to these players to make oneself appear in their field of view
    for _, pid := range pids {
        players = append(players, WorldMgrObj.GetPlayerByPid(int32(pid)))
    }

    // 3.1. Build MsgId200 protobuf data
    msg := &pb.BroadCast{
        Pid: p.Pid,
        Tp:  2, // TP2 represents broadcasting coordinates
        Data: &pb.BroadCast_P{
            P: &pb.Position{
                X: p.X,
                Y: p.Y,
                Z: p.Z,
                V: p.V,
            },
        },
    }

    // 3.2. Send the 200 message to each player's respective client to display the character
    for _, player := range players {
        player.SendMsg(200, msg)
    }

    // 4. Make players within the nine-grid area appear in one's own field of view
    // 4.1. Create Message SyncPlayers data
    playersData := make([]*pb.Player, 0, len(players))
    for _, player := range players {
        p := &pb.Player{
            Pid: player.Pid,
            P: &pb.Position{
                X: player.X,
                Y: player.Y,
                Z: player.Z,
                V: player.V,
            },
        }
        playersData = append(playersData, p)
    }

    // 4.2. Encapsulate SyncPlayer protobuf data
    SyncPlayersMsg := &pb.SyncPlayers{
        Ps: playersData[:],
    }

    // 4.3. Send all player data that needs to be displayed in the vicinity to the current player
    p.SendMsg(202, SyncPlayersMsg)
}
Enter fullscreen mode Exit fullscreen mode

The provided code contains two crucial processes: one is sending one's own coordinate information to players within the AOI (Area of Interest) range, and the other is sending the coordinate information of surrounding players to one's own client. Finally, when a user logs in, the synchronization of coordinate information is triggered. The relevant place to call the SyncSurrounding() function is in the OnConnecionAdd() implementation, as shown below:

//mmo_game/server.go

// Hook function when a client establishes a connection
func OnConnecionAdd(conn ziface.IConnection) {
    // Create a player
    player := core.NewPlayer(conn)

    // Synchronize the current PlayerID to the client, using MsgID:1 message
    player.SyncPid()

    // Synchronize the initial coordinate information of the current player to the client, using MsgID:200 message
    player.BroadCastStartPosition()

    // Add the newly logged-in player to the World Manager
    core.WorldMgrObj.AddPlayer(player)

    // Bind the "pid" property to this connection
    conn.SetProperty("pid", player.Pid)

    // New: Synchronize the online information of surrounding players and display the information of surrounding players
    player.SyncSurrounding()

    fmt.Println("=====> Player with pidId = ", player.Pid, " has arrived ====")
}
Enter fullscreen mode Exit fullscreen mode

Finally, run the program for a simple test. To start the server, execute the following command:

$ go run server.go
Enter fullscreen mode Exit fullscreen mode

Then start three clients separately and observe if they can see each other's location information, as shown in Figure 16.2-16.4.

Figure 16.2-16.4

Figure 16.2

Figure 16.3

Figure 16.4

From the interface shown in Figure 16.2-16.4, it can be observed that Player_4 can see other players who are online, and Player_5 can also see Player_4 and other surrounding online players.


MMO-GAME Source Code

https://github.com/aceld/zinx/tree/master/zinx_app_demo/mmo_game


[Zinx]

<1.Building Basic Services with Zinx Framework>
<2. Zinx-V0.2 Simple Connection Encapsulation and Binding with Business>
<3.Design and Implementation of the Zinx Framework's Routing Module>
<4.Zinx Global Configuration>
<5.Zinx Message Encapsulation Module Design and Implementation>
<6.Design and Implementation of Zinx Multi-Router Mode>
<7. Building Zinx's Read-Write Separation Model>
<8.Zinx Message Queue and Task Worker Pool Design and Implementation>
<9. Zinx Connection Management and Property Setting>

[Zinx Application - MMO Game Case Study]

<10. Application Case Study using the Zinx Framework>
<11. MMO Online Game AOI Algorithm>
<12.Data Transmission Protocol: Protocol Buffers>
<13. MMO Game Server Application Protocol>
<14. Building the Project and User Login>
<15. World Chat System Implementation>
<16. Online Location Information Synchronization>
<17. Moving position and non-crossing grid AOI broadcasting>
<18. Player Logout>
<19. Movement and AOI Broadcast Across Grids>


Author:
discord: https://discord.gg/xQ8Xxfyfcz
zinx: https://github.com/aceld/zinx
github: https://github.com/aceld
aceld's home: https://yuque.com/aceld

Top comments (0)