First, the preface
"Code God Alliance" is a technology for people to do open source feelings of the game, each programming language is a hero. Both the client and the server use C # development, the client uses the Unity3d engine, and the database uses MySQL. This Moba class game is the author in the study time and the client art plan's small partner to do together the game, the author mainly is responsible for the game service side development, the client also participates in the part, simultaneously also is this project's initiation and the person in charge. This is the main share of the game's server-related design and implementation, from the overall architecture design, to the bottom of the network communication servers, communication protocols, model customization, and then to the game logic of the layered architecture implementation. At the same time, this blog also precipitated the author in the game company practice five months after the game structure and design review and thinking.
The game since the completion of the last year, the author has several times to write a blog to share, has repeatedly stopped pen, only because the total feel that the inspiration is not enough accumulation is not enough to think, now finally can cross this step and share with you, hope can bring the dry goods and sincerity is full. As there are so few introductory articles about the game server, and a few are also standing in the game server development history and architecture of the point of view to share, rarely involved in specific implementation, this article I will try to more from the level of implementation to be introduced, the attached code are detailed comments, length, You can focus on the collection and see it again. Learning time to do projects may not reach the industrial level, referring to the GitHub on the open source of the C # Network framework, the author in and small partners to do this game when the pesticide is not so fire. :) second, server architecture
The graph above is the server architecture and the main logic flowchart of this game, the author divides the code realization of the game into three main modules: Protocol communication protocol, Netframe Server network communication infrastructure and Lolserver game's concrete logical layered architecture realization, The following is a separate description for each module. III. Communication Protocols
Starting with the simplest and most basic communication Protocols section, we can see that this part of the code is divided into Xxxprotocol, Xxxdto and Xxxmodel, and xxxdata four types, let's take a look at their role. 1.Protocol Protocol
Lolserver\protocol\protocol.cs
Using system;using system.collections.generic;using system.text;namespace gameprotocol{public class Protocol {public const byte Type_login = 0;//Login module public const BYTE Type_user = 1;//user module public const byte type_m Atch = 2;//Combat Matching module public const BYTE Type_select = 3;//Combat Select module public const BYTE Type_fight = 4;//combat Module }}
As you can see from the above code, in the Protocol Protocol section, we mainly define some constants for module communication, in which we define user protocols, login protocols, battle matching protocols, battle-selection protocols, and combat protocols. 2.DTO Data Transfer Object
A DTO is a data transfer object, and the presentation layer interacts with the application layer through a data transfer object (DTO), and it needs to be understood that the data transfer object DTO itself is not a business object. Data transfer objects are designed based on the requirements of the UI, not the domain object. For example, the user domain object might contain information such as name, level, exp, email, and so on. However, if the UI does not intend to display email information, then userdto does not need to include this email data.
In short, model-oriented business, we are through the business to define model. The DTO is an interface-oriented UI and is defined by the requirements of the UI. Through the DTO we achieve the performance layer and model decoupling, presentation layer does not reference model, if the development process of our model changes, and the interface has not changed, we just need to change the model and do not need to change the performance layer of things.
Using system;using system.collections.generic;using system.text;namespace gameprotocol.dto{ [Serializable] Public class Userdto {public int id;//player ID unique primary key public string name;//player nickname public int level;//player level public int exp;//player Experience Public int wincount;//Victory game public int losecount;//failure game public int rancount;//escape Games public int[] herolist;//player-owned List of heroes public Userdto () {} public Userdto (string name, int id, int level, int win, int lose, int Ran,int[] herolist) { this.id = ID; this.name = name; This.wincount = win; This.losecount = lose; This.rancount = ran; This.level = level; This.herolist = herolist; } }
3.Data Property Configuration Table
This part of the implementation is mainly to the program function and attribute configuration separation, the following can be configured by the planning of this part of the Guide table tool to automatically generate a table, thereby reducing the development workload of the program, expanding the game's function.
Using system;using system.collections.generic;using system.text;namespace gameprotocol.constans{///<summary> Hero attribute Configuration Table///</summary> public class Herodata {public static readonly Dictionary<int, Herodat amodel> Heromap = new Dictionary<int, herodatamodel> (); <summary>///static construction automatically calls///</summary> static herodata () {Create (1, "West Ka [C + +] ", 5, 2, 1, 0.5f, 200,200, 1, 2, 3, 4); Create (2, "Patrick [Python]", 5, 2,, 1, 0.5f, 200, 200, 1, 2, 3, 4); Create (3, "Zawa [Java]", M, 5, 2, 1, 0.5f, 200, 200, 6, 2, 3, 4); Create (4, "Beatrice Inspector [PHP]", M, M, 5, 2, M, 1, 0.5f, 200, 200, 3, 2, 3, 4); ///<summary>///Create the model and add it to the dictionary///</summary>///<param name= "code" ></param& Gt <param name= "name" ></param>///<param name= "atkbase" ></param>///<param name= "defbase" ></param>///<param name= "HpBa" Se "></param>///<param name=" mpbase "></param>///<param name=" Atkarr "></param& Gt <param name= "Defarr" ></param>///<param name= "Hparr" ></param>///<param name= "Mparr" ></param>///<param name= "Speed" ></param>///<param name= "Aspeed" ></par am>///<param name= "range" ></param>///<param name= "Eyerange" ></param>/// <param name= "skills" ></param> private static void Create (int code, string name, int atkbase, int defbase, int hpbase, int mpbase, int atkarr, int DefA RR, int hparr, int mparr, float speed, float aspeed, float range, Float EYErange, params int[] skills) {Herodatamodel model = new Herodatamodel (); Model.code = code; Model.name = name; Model.atkbase = Atkbase; Model.defbase = Defbase; Model.hpbase = Hpbase; Model.mpbase = Mpbase; Model.atkarr = Atkarr; Model.defarr = Defarr; Model.hparr = Hparr; Model.mparr = Mparr; Model.speed = speed; Model.aspeed = Aspeed; Model.range = range; Model.eyerange = Eyerange; Model.skills = skills; Heromap.add (code, model); Partial class Herodatamodel {public int code;//scheme defined unique number public string name ;//Hero name public int atkbase;//initial (base) attack damage public int defbase;//Initial defense public int hpbase;//initial blood volume public int mpbase;//initial blue public int atkarr;//attack intoLong public int defarr;//Defense growth public int hparr;//blood volume growth public int mparr;//Blue growth public F Loat speed;//Move Speed public float aspeed;//attack Speed public float range;//attack distance public float Eyerange ;//field of view Range public int[] skills;//own Skills}}
four, the server communication bottom build up
This part is the server's network communication low-level implementation, is also the core content of the game server, the following will be combined with specific code and code comments one by one to introduce the bottom of the implementation, may involve some C # network programming knowledge, not familiar with the C # language, the author of C # is only used in the use of the stage, just through C #这门简单易懂的语言来窥探整个服务器通信底层搭建起来的过程, come to our Netframe network communication framework, which is a lot of dry goods, I will use complete code and detailed comments to illustrate its meaning.
1. Four-layer socket model
The Socketmodel is divided into four levels, respectively:
(1) Type: The first level protocol is used to differentiate the owning module, such as user module
(2) Area: Level Two protocol is used to distinguish the subordinate modules under the module, such as the module of user modules for Prop Module 1, Equipment Module 2, Skill Module 3, etc.
(3) Command: Level Three protocol is used to differentiate the current processing logic functions, such as the logic function of the prop module has "use (application/result), discard, obtain", and so on, the logic function of the skill module has "study, upgrade, forget" and so on;
(4) Message: The body data that the body currently needs to process, such as a skill book
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; namespace netframe.auto{public class Socketmodel { ///<summary> ///First-level protocol is used to differentiate the owning module /// </summary> public byte type {get;set;} <summary> ///Level Two protocol is used to differentiate the subordinate module ///</summary> public int area {get; set;} <summary> ///Level Three protocol is used to differentiate between current processing logic functions ///</summary> Public int command {get; set;} <summary> ///The body data that the message body currently needs to handle ///</summary> public object message {get; set;} Public Socketmodel () {} public Socketmodel (byte t,int a,int c,object o) { this.type = t; This.area = A; This.command = C; This.message = o; } Public T getmessage<t> () {return (T) message; }}}
Also encapsulates a method of message encapsulation, the process of receiving a message is as shown in the figure:
2. Object serialization and deserialization to Objects
Serialization: The process of converting a data structure or object into a binary string.
Deserialization: The process of converting binary strings generated during serialization into data structures or objects.
Using system;using system.collections.generic;using system.io;using system.linq;using System.runtime.serialization.formatters.binary;using system.text;using System.threading.tasks;namespace NetFrame{ public class Serializeutil {///<summary>///object serialization///</summary>///<param N Ame= "value" ></param>///<returns></returns> public static byte[] Encode (object value) { MemoryStream ms = new MemoryStream ()//create encoded decoded memory Stream object BinaryFormatter bw = new BinaryFormatter ();//binary stream sequence Serialization of objects//The Obj object is serialized into binary data written to the memory stream bw. Serialize (MS, value); Byte[] Result=new byte[ms. Length]; Copy stream data to the result array buffer.blockcopy (MS. GetBuffer (), 0, result, 0, (int) Ms. Length); Ms. Close (); return result; ///<summary>///deserialized to object///</summary>///<param name= "value" ></param> ; <returns></returns> public static object decode (byte[] Value {MemoryStream ms = new MemoryStream (value);//create encoded decoded memory stream pair Like and write the data that needs to be deserialized into it binaryformatter bw = new BinaryFormatter ()//binary Stream serialization object//Stream data counter