I am currently working on a project to learn more about networking, specifically authoritative network architecture.
In most authoritative systems you capture a player’s input, queue them up, then send them to the server after a certain count or time has passed. The input is “copied” to the local(client) loop and run as prediction while it waits for the server to return the authoritative state back to the local(client) for correction. The states are also sent to all connected players to recreate the observed behavior of remote players.
This system works well for things like player movement and shooting(raycasts). This gets more complicated as we start to integrate UI and player skill/ability bars. In most MOBA or MMO games there is UI that can also create “input”. In these cases there isn’t a truely 100% right way to accomplish the goal of networking these pieces. You wouldn’t need or want the UI to be run on the server in most cases.
I have come up with a few concepts of sending the input for these to the server and would like to know if I am close to conventions that are used in professional system or if I am even thinking about it in the right way.
Case 1: Mapped config agreement
In this model the player can assign abilities to a skill bar that is both clickable and correspond to the number keys on the keyboard. This “mapping” of abilities to bar slots is stored in a player config and is sent to the server. When the player presses a number key or clicks on an icon an input is generated and added to the input sent to the server that looks something like this:
[BarId:1,BarIndex:1,KeyId:1]
When this is received by the server the server looks up the player UI config that was sent to the server and see what abilityId was stored on that place in the bar, check if it is a valid move then update the server state.
Case 2: Server Command
In this case the player class has a UseAbility(abilityId,target) method that can be called from the client player instance but is executed on the server instance, this bypasses the normal input gathering loop by executing the command on the server immediately so incorporating this into the client/server step systems isn’t clean.
Borrowing the use-case from Case 1: The player presses the button on the keyboard or clicks the UI button. This is “mapped” locally to a specific skill. The button/keypress calls UseAbility(0x00012,self) and is run on the client and server immediately it is checked for validity and then a state is sent to all connected players.
Those are the two cases I have right now. One works well with how input is gathered and sent to the server for processing. The other makes more sense in that the code can be more explicit but it appears to break the server authoritative structure. Would you guys please tell me what you think and maybe we can have a conversation about best practices.
Thanks for reading my post.