Multicast
Sending one message to several hosts at one time is called multicast. Sending to just one host is called unicast.
Reliable messaging
Reliable messaging (or reliable send) guarantees that the order of sender sending and receiver receiving the message is equal. For instance, if sender sends message in order of A,B,C,D,E then receiver receives them in the same order of A,B,C,D,E without data being broken.
Reliable messaging is advantageous for its high reliability but relatively slower than Unreliable Messaging in transmitting time.
Reference: 3. Protocol type of ProudNet
Reliable Message
It is a message being sent or received by Reliable messaging.
Unreliable Messaging
Unlike reliable messaging, unreliable messaging can't guarantee the order of sending and receiving message to be same depending on the condition of network line. For instance, if message A,B,C,D,E are sent, they all get delivered but sometimes they come in repetitively for some messages (A,B,B,C,C,D,E), lose some of messages (A,B,,D) during the transmission, or arrive in random order (A,C,B,E,D) but data inside data get preserved.
Unreliable message has such weakness but it transmits messages faster than Reliable messaging.
Reference: 3. Protocol type of ProudNet
Unreliable Message
It is a message being sent or received by Unreliable Messaging.
Thread pool
The process of generating or deleting one thread requires high throughput. And if there are too many threads in operation then they would cause overload to OS. Therefore, in order to minimize the process of generating or deleting a thread as maintaining the number of threads as minimal as possible, you better make a set of specific number of threads, use the set when needed then withdraw the set if it is not needed (This process is called Thread pooling.)
Thread pool is referred to a set consisting of multiple numbers of threads.
Thread pooling
Please refer to Thread pool
Listening Port
In order for server to receive connection of client, it must have something called listening port. Listening port is made of host address and port. Host address is an internet IP address in the format of 111.222.111.222 or mycomputer,mydomain.com. Port is value between 1,000 to 65,500.
As lomg as more than two programs use the same listening port, you can appoint a listening port in any way you like.
PIDL Compiler (ProudNet IDL)
Dead Reckoning
ProudNet provides Dead Reckoning tools to smoothly render the position of game characters.
The basics of dead reckoning
Dead Reckoning works as followed.
Sends the position and speed of moving game character from host A to host B. The cycle of transmission is 2 ~ 10 times per second.
The transmission cycle should be dynamic. If a character's acceleration is huge, it is better to have shorter cycle which helps synchronizing more accurately. Huge acceleration means the status of rapid change in character's moving speed or direction when collided with an object. (Refer to the screenshot below)
Latency from host B to host A can be obtained by 14. Gaining latency (ping time) between hosts.
When host B receives the character's position and speed, it estimates the position of host A using the following formula (P: estimated position, V: received speed. T: Latency, P0: received position).
P = (V * T) + P0
The character's position can be estimated using the above formula but the character's position might get cut off here and there when just rendering the calculated result. To fix this issue, you can use Proud.CPositionFollower.
Proud.CPositionFollower repositions follower to ensure a target arrives to the position of another moving target within given time. Proud.CPositionFollower is built to track a moving target in a straight line. So it prevents other hosts' character position moving weirdly.
Now, let's move on to the next steps of using dead reckoning.
Insert the position and speed value estimated by host B into Proud.CPositionFollower object.
In order for host B to render the position of host A, obtain the position of follower of Proud.CPositionFollower object.
It is better for cycle of sending character's position from A and the time it takes for follower to reach the target to have the same time limitation.
Cycle of sending character's position varies upon situation. Here is what we recommend.
Situation | Type of sending data | Average of sending cycle | Example of rapid acceleration |
---|---|---|---|
Playable character of MMORPG | Position(xyz),Speed(xyz), Staring Direction(z) | 0.3 | Change of moving direction, stance, dot, buff of character |
Airplane or car | Position(xyz),Speed(xyz),Acceleration(xyz), Staring Direction(xyz) | 0.3 | Collided with an obstacle, rapid direction change |
Playable character of FPS game | Position(xyz), Staring Direction(xyz) | 0.03 | Sniper gun being fired immediately after character changes moving direction |
If the cycle of sending is too short, it could increase the amount of network traffic ecessively. For the case like this, we recommend you to combine 11. Traffic auto-control function (Throttling).
The sample of using Dead Reckoning is guided in 3. Character synchronization in 3D world .
Spline based follower
Proud.CPositionFollower provides follower that not only chases a target in a straight line but also in curve. This is called spline based follower in the form of 3rd function, which moves more smoothly than the linear follower. But, it doesn't always work fashionable under circumstances, thus you need to test both of them in the gameplay and choose whichever works better.
To obtain the current status of Spline based follower, you can use the listed methods in below. The rests are the same with The basics of dead reckoningg.
• Proud.CPositionFollower.GetSplineFollowerPosition
• Proud.CPositionFollower.GetSplineFollowerVelocity
Correcting the angle of follower
Proud.CPositionFollower corrects the position of target while Proud.CAngleFollowe corrects the angle of follower. How this can be used is guided in 3. Character synchronization in 3D world .
Data Quantization
When sending or receiving a relatively large value in floating point, there could be a trick to reduce the size of packet. For example, if the character's position x can be only determined between 100 and 200, and simply ignore the accuracy of value below double-digit point, then this value can be sent or received after converting it to a value under 100*100 = 10000 and this can save the value as word(2bytes) not as double(8bytes).
Such trick is called quantization.
This class supports quantization and reverse-quantization.
Proud::CQuantizer q(-10000,10000,65535); // Quantizing a value between -10000 and 10000 by dividing it equally by 65535. double a = 3423.38274f; int b = q.Quantize(a); // Quantizing double c= q.Dequantize(b); // Recover the original value from the quantization.
Fast Heap
Fast heap of ProudNet is a bit slower than Lookaside Allocator but still it is much faster than OS as allocating and releasing memory block. And unlike Lookaside Allocator, it can allocate and release memory block in various sizes.
Implementing class of Fast heap is Proud.CFastHeap. Just like Lookaside Allocation, Proud.CFastHeap also can remove Proud.CFastHeap object after destroying all memory blocks first.
You can use Fast heap as followed.
First, create a fast heap object by Proud.CFastHeap.New method.
Allocate a memory block with Proud.CFastHeap.Alloc method.
You can release the memory block by Proud.CFastHeap.Free. To re-allocate, use CFastHeap.Realloc method.
Destroy Proud.CFastHeap object after releasing all memory blocks.
More details are guided in Proud.CFastHeap.
Using The internal link is invalid. is another good way to use this module.
C++ singleton
There are differences between singleton and global variable in C++. Global variable doen't get destructed before the execution of WinMain() or main() is completed. It only gets destroyed by sub call function of WinMain() or main(). And also, the destruction order of global variable is only guaranteed by compiled result of one C++ file. Which means the order of destruction cannot be guaranteed if there are more than one C++ files.
On the other hands, C++ singleton gets called just before WinMain() or main() returns. Moreover, at the moment of approaching singleton for the first time, the generator of instance gets called and gets destroyed in reverse order of generator being called. Thus it guarantees creating/destroying policy more safely that that of global variable.
Next is an implementation example of C++ singleton.
class A { A(){} public: static A& Instance() { static A inst; return inst; } void Goo() {} }; void Foo() { A::Instance().Goo(); }
Above is well-known implementation of singleton. But, using above example as-is could be dangerous since generator can be called twice when several threads try to approach to singleton simultaneously in a short time. Thus it is recommended to use Proud.CSingleton class free from critical session load as approaching singleton.
Operating System (OS) of Game Server
OS(Operating System) of game server doesn't matters when CCU(Concurrent User) is less than 100. But when it becomes higher than 100, using OS dedicated to server as game server's OS is much beneficial in performance.
ProudNet이 지원하는 서버 전용 운영체제는 Windows 2003 Server 혹은 이후 버전입니다. Linux도 지원하며, CentOS 6, Ubuntu 12 이상에서 테스트되었습니다.