# Glossary

## :books: Burst Time

Burst time is broadly divided into <mark style="color:orange;">CPU burst time</mark> and <mark style="color:orange;">Device burst time.</mark>

### **- CPU burst time**

The amount of time that only the CPU is computing to execute a particular routine. The CPU core occupancy of a thread during <mark style="color:orange;">CPU burst time</mark> can be seen as 100.

### **- Device burst time**

The amount of time the CPU waits for other processing to complete while executing a particular routine. The CPU core occupancy of a thread during <mark style="color:orange;">Device burst time</mark> is zero.\
Typical cases where the CPU is waiting for other processing to complete are reading/writing files, running DB queries, and waiting for service responses from other hosts.

## :books: C++ Singleton

In the C++ language, there is a difference between a singleton and a global variable. Global variables are not destroyed immediately before termination when <mark style="color:orange;">WinMain()</mark> or <mark style="color:orange;">main()</mark> is executed; they are destroyed in the calling function. The order of destruction of global variables is only guaranteed in the compilation output of a single C++ file; the order of destruction between compilation outputs of different C++ files is not guaranteed.<br>

However, a C++ singleton is called just before <mark style="color:orange;">WinMain()</mark> or <mark style="color:orange;">main()</mark> returns. Moreover, the moment a singleton is accessed for the first time, the instance's constructor is called, and the order in which it is destroyed is the reverse order in which the constructor was called. This ensures safer creation/destruction rules than global variables.<br>

Here is an example implementation of a C++ singleton.

<details>

<summary><span data-gb-custom-inline data-tag="emoji" data-code="27a1">➡️</span> example implementation of a C++ singleton</summary>

```cpp
class A
{
    A(){}
public:
    static A& Instance()
    {
        static A inst;
        return inst;
    }
    void Goo() {}
};
 
 
 
void Foo()
{
    A::Instance().Goo();
}
```

</details>

{% hint style="warning" %}
The risk with the above implementation is that if the singleton is accessed by multiple threads at the same time in a short period of time, the constructor may be called more than once.

We recommend using the class <mark style="color:orange;">Proud.CSingleton</mark>, which solves these problems but does not have a critical section load for singleton access.
{% endhint %}

## :books: DB Constraints

This refers to preventing a field from entering if it does not meet a particular condition.

Primary Key Unique Index, etc. ( >, <, =, != ) Constraint is implemented as Unique Index, Trigger, etc.

## :books: Fast Heap

ProudNet's Fast heap is slightly slower than the [**Lookaside allocator**](/proudnet.eng/proudnet/pn_utility.md#lookaside-allocator)**,** but much faster than the rate at which memory is allocated/released in the OS environment. And unlike the Lookaside allocator, it can allocate/release blocks of memory of different sizes.

The implementation class of FastHeap of ProudNet is <mark style="color:orange;">Proud.CFastHeap</mark>. <mark style="color:orange;">Proud.CFastHeap</mark> like the  <mark style="color:orange;">Lookaside allocator</mark>, can only remove the <mark style="color:orange;">Proud.CFastHeap</mark> object after all memory blocks have been destroyed.

Here is how to use Fast heap.

> * First, create a fast heap object with the <mark style="color:orange;">Proud.CFastHeap.New</mark> method. You can also create it as a global object.
> * Allocate a block of memory with the <mark style="color:orange;">Proud.CFastHeap.Alloc</mark> method.
> * Release is done with <mark style="color:orange;">Proud.CFastHeap.Free</mark>. Memory blocks can be reallocated with <mark style="color:orange;">CFastHeap.Realloc</mark>.
> * Destroy the <mark style="color:orange;">Proud.CFastHeap</mark> object after releasing all memory blocks.

## :books: P2P group

If two clients A and B want to peer-to-peer communicate with each other, they must be members of at least one peer-to-peer group. Multiple people can chat with each other in a single chat window, and multiple chats can be created by creating multiple chat windows. However, you can't chat in a chat room you're not in.

ProudNet is like an internet messenger, where each chat window corresponds to a peer-to-peer group.

The difference is that only the server has permission to create or join other chat rooms. P2P group identifiers are also of type <mark style="color:orange;">Proud.HostID</mark>.

## :books: PIDL

PIDL is a homegrown compiler for RMI.

When you define and set a Protocol for a specific file, it will automatically create the file with the object.\
Since the objects created are used by both server and client, it is convenient to create and manage a Common Project.

## :books: Reliable Messaging

Reliable messaging (or reliable send) means that the content and order of messages sent by the sender is always received by the receiver in the same order. For example, if you send messages A,B,C,D,E, the receiver will receive them in the order A,B,C,D,E without any data loss.

It has the advantage of reliability, but can sometimes be slower to receive than [**Unreliable messaging**](#unreliable).

## :books: RMI

<mark style="color:orange;">RMI(Remote Method Invocation)</mark> refers to calling a function on a different network or in a different process, and it serves to simplify the programming tasks that make life difficult for developers (defining message structures, writing sending and receiving functions, and sending and receiving routines) in the form of function calls by having a machine do the coding work instead of a human.

When you send a message, the side that calls the RMI function is called the Proxy, and the side that receives the call is called the Stub.

<figure><img src="/files/ICNmLYQBghM7CNE65E3e" alt=""><figcaption><p>RMI Concept</p></figcaption></figure>

<figure><img src="/files/RKSBo94YNVznHXsquKBz" alt=""><figcaption><p>RMI Concept2</p></figcaption></figure>

### - When RMI is not used

```cpp
// Message header ID definitions
#define Message_Knight_Move_ID 12
#define Message_Knight_Attack_ID 13
 
// Message format definitions
struct Message
{
    int m_msgID;
};
struct Message_Knight_Move:public Message
{
    int m_id;
    float m_x,m_y,m_z;
};
struct Message_Knight_Attack:public Message
{
    int m_id;
    int m_target;
    int m_damage;
};
 
// A function which send a formatted message
void Knight_Move(int id,float x,float y,float z)
{
    Message_Knight_Move msg;
    msg.m_msgID=Message_Knight_Move_ID;
 
    msg.m_id=id;
    msg.m_x=x;
    msg.m_y=y;
    msg.m_z=z;
 
    Send(msg);
}
 
// A function which send a formatted message
void Knight_Attack(int id,int target,int damage)
{
    Message_Knight_Attack msg;
    msg.m_msgID=Message_Knight_Attack_ID;
 
    msg.m_id=id;
    msg.m_target=target;
    msg.m_damage=damage;
 
    Send(msg);
}
 
// Identified a received message 
// and call an appropriate function for message handling
void DoReceivedMessage(Message* msg)
{
    switch(msg->m_msgID)
    {
    case Message_Knight_Move_ID:
    {
        Message_Knight_Move* msg2=
            (Message_Knight_Move*)msg;
 
        Do_Knight_Move(
            msg2->m_id,
            msg2->m_x,
            msg2->m_y,
            msg2->m_z);
    }
    break;
    // ... cases for other message types
    case Message_Knight_Attack_ID:
    {
        Message_Knight_Attack* msg2=
            (Message_Knight_Attack*)msg;
 
        Do_Knight_Attack(
            msg2->m_id,
            msg2->m_target,
            msg2->m_damage);
    }
    break;
    // ... cases for other message types
    }
}c
```

However, if you use RMI, you can organize it into a short code as shown below.

```cpp
Knight_Move([in] int id,[in] float x,[in] float y,[in] float z);
Knight_Attack([in] int id,[in] int target,[in] int damage);
```

The above format is an <mark style="color:orange;">IDL(Interface Description Language)</mark> type language, which when compiled produces C++ or C# source. The generated source file consists of message structure declarations, send functions, receive processing functions, and so on; the PIDL compiler automatically generates the network processing routines without the developer having to create them.

Of the files created, the module that turns function calls into messages and sends them to the network is called a proxy, and the module that analyzes the messages received over the network and calls user functions is called a stub.

When Host A calls an RMI function X, it actually calls X's proxy, which turns it into a network message and sends it to Host B. Host B receives the message and sends it to a stub, which analyzes it and calls the function X you wrote.

<figure><img src="/files/a9aCsDMgFH9co1VZ57I9" alt=""><figcaption><p>RMI processing order</p></figcaption></figure>

It looks a lot like calling a function on Host A from Host B, hence the name <mark style="color:orange;background-color:yellow;">R</mark><mark style="color:orange;">emote Method Invocation</mark>.

## :books: Stored Procedure

A <mark style="color:orange;">Stored Procedure</mark> is a program function written in SQL syntax that can be put into the DBMS itself. \
When accessing a database, the query syntax string is created and thrown by the application, but if possible, it is more efficient for performance and reliability (e.g., database locking policies) to create and store the query syntax routine as a <mark style="color:orange;">Stored Procedure</mark>, and the application calls the <mark style="color:orange;">Stored Procedure</mark> directly.

<br>

## :books: **Unreliable** Messaging

<mark style="color:orange;">Unreliable messaging</mark> (or unreliable send) means that the content and order of messages sent by the sender may be received differently depending on the length and condition of the communication line.

For example, if you send messages A,B,C,D,E, the recipient may receive A,B,C,D,E, but they may receive the same message twice (A,B,B,C,C,D,E), the message may be lost in the middle (A,B,D), or the messages may arrive in a different order (A,C,B,E,D).

However, the data inside the message is not broken. Unreliable messaging has this drawback, but it is delivered faster than [**Reliable messaging**](#reliable).

## :books: UUID or GUID

A unique or global universal identifier (<mark style="color:orange;">UUID</mark> or <mark style="color:orange;">GUID</mark>) is a 16-byte block of data, which means that the GUID you generate is probabilistically unique in the world.

The ProudNet DB assigns a UUID to each Gamer, Hero, and WorldObject. Although UUIDs are 16 bytes, which can be considered large, they are useful in a few important cases because they have the advantage of being the only duplicate UUID on the planet. The main ones are server closures, gamer account moves, and gamer ID changes.

{% hint style="success" %}
**Reference**\
[**Globally unique identifier**](https://ko.wikipedia.org/wiki/%EC%A0%84%EC%97%AD_%EA%B3%A0%EC%9C%A0_%EC%8B%9D%EB%B3%84%EC%9E%90)&#x20;
{% endhint %}

## :books: Race Condition

In engineering, a <mark style="color:orange;">race condition</mark> is a state in which two or more inputs or manipulations occur simultaneously. In such a state, there is a risk that the normal outcome will not occur, which is known as <mark style="color:orange;">race risk</mark>.

In computing, a <mark style="color:orange;">race condition</mark> is when multiple processes attempt to access a shared resource at the same time, and their simultaneous access can result in inconsistent data. To avoid this, process cooperation techniques are needed.

{% hint style="success" %}
**Reference**

[**Race condition from Wiki**](https://ko.wikipedia.org/wiki/%EA%B2%BD%EC%9F%81_%EC%83%81%ED%83%9C)&#x20;
{% endhint %}

## :books: Data quantization

When sending large, floating-point values to and from the network, there are situations where tricks are possible to reduce the amount of packets.\
For example, if the value of character position x is only determined between 100 and 200, and the precision to two decimal places is negligible, this value can be converted to and from a value of 100 \* 100 = 10000 or less, saving a double (8 bytes) to a word (2 bytes).

This trick is called <mark style="color:orange;">quantization</mark>.

This class provides quantization and the inverse of quantization.

```cpp
Proud::CQuantizer q(-10000,10000,65535); // Ability to quantize values between -10000 and 10000 to a precision of 65535 equivalents
double a = 3423.38274f;
int b = q.Quantize(a);      // Quantization
double c= q.Dequantize(b);  // Restoring real values from quantized values
```

## :books: Listening Port

It consists of a <mark style="color:orange;">host address</mark> and a <mark style="color:orange;">port</mark>, and the server must have a <mark style="color:orange;">listening port</mark> in order to receive connections from clients.

A <mark style="color:orange;">host address</mark> is an address on the Internet, organized in the form of 111.222.111.222 or mycomputer.mydomain.com. A <mark style="color:orange;">port</mark> is a value between 1,000 and 65,500.\
This can be any number, as long as no more than two programs are using the same <mark style="color:orange;">listening port</mark>.

## :books: Marshaling

Converting an RMI call into a message or extracting the values for calling RMI from a message is called <mark style="color:orange;">marshaling</mark>.\
ProudNet provides marshaling for basic types like int and float.

<br>

## :books: Multicast

Delivering a single message to many hosts at once is called <mark style="color:orange;">multicast</mark>, \
delivering a message to only one host is called <mark style="color:orange;">unicast</mark>.

<figure><img src="/files/2L2z0IwDOQl38bEiG9a2" alt=""><figcaption></figcaption></figure>

## :books: Thread Pool

Creating and removing a single thread is a lot of processing, so if you have a lot of threads running, it can overload the operating system.

Therefore, we need to keep as few threads as possible and minimize the process of removing and creating threads, which can be done by having a single set of a certain number of threads that are only taken when needed and returned to the set when not needed. This process is called a <mark style="color:orange;">thread pool</mark>.

In other words, a <mark style="color:orange;">thread pool</mark> refers to <mark style="color:orange;">a set of threads</mark> in which <mark style="color:orange;">several threads</mark> <mark style="color:orange;">are prepared in advance</mark>.

### - Example

> Clients A, B, and C are admitted to the server and are waiting in a queue within <mark style="color:orange;">Proud.CNetServer</mark> due to RMI or an event, respectively.<br>
>
> A1,A2,A3 -> Events or RMI for Client A\
> B1,B2,B3 -> There are a total of two threads in the event or RMI thread pool for Client B.\
> \
> \
> At that point, the rule will execute as follows.<br>
>
> * A1,A2,A3 will not run at the same time.
> * B1,B2,B3 and C1,C2,C3 are also not executed at the same time.
> * One of A1,A2,A3 and one of B1,B2,B3 and one of C1,C2,C3 can be executed at the same time.
> * Since there are only two threads in the thread pool, two of A, B, and C are selected and called, but the thread whose callback routine completes first performs the RMI or event callback for the unselected client.

<figure><img src="/files/rLQZfMlBtGDkQTETE1Kc" alt=""><figcaption><p>Example of running a thread pool</p></figcaption></figure>

## :books: Dead reckoning

ProudNet provides tools for <mark style="color:orange;">dead reckoning</mark> for smooth position representation of game characters.

<mark style="color:orange;">Dead reckoning</mark> works roughly like this.

> * Host A sends the position and velocity of the moving character to Host B. The transmission frequency is between 2 and 10 times per second.
> * It is recommended that the transfer interval be dynamic. Shortening the transfer period only when the character has a large acceleration will result in more accurate movement synchronization. Large accelerations are when the character's speed changes rapidly, or when the direction of movement changes rapidly as the character hits another object. (See the table below.)
> * Host B obtains the time it takes for a message to arrive from Host A (latency) by pinging it.
> * When Host B receives the character's position and velocity information, use the following formula to predict the actual position of the character on Host A.\
>   \
>   **P:** Predicted locatio&#x6E;**, V:** Received spee&#x64;**, T:** Latenc&#x79;**, P0:** Received location\ <mark style="color:orange;">**P = (V \* T) + P0**</mark>

Up to this point, the character's position is predictable, but when we render the calculated position value, the character's position jumps around.\
To solve this problem, we use <mark style="color:orange;">Proud.CPositionFollower</mark>.

\ <mark style="color:orange;">Proud.CPositionFollower</mark> is responsible for moving a follower to reach the location of a moving target within a time limit. It is specifically designed to track the location of a moving target in a straight line, which reduces the bouncing of character positions from other hosts.

Let's describe the remaining steps to implement <mark style="color:orange;">dead reckoning</mark>.

> * Enter the predicted position and velocity values from Host B into the <mark style="color:orange;">Proud.CPositionFollower</mark> object. Enter them as the target's position and velocity.
> * To render the position of the character on Host A, Host B gets the position of the follower of the <mark style="color:orange;">Proud.CPositionFollower</mark> object.

<figure><img src="/files/FazfuOAYIAKoo2xwxwrU" alt=""><figcaption></figcaption></figure>

### - Dead reckoning example

P(t=0,1,2) is the predicted point and the red line is the character position corrected by <mark style="color:orange;">Proud.CPositionFollower</mark>.\
As a general rule of thumb, you'll want to set the same timeout between sending the character's location from Host A and the time for the tracker to reach the target's location in <mark style="color:orange;">Proud.CPositionFollower</mark>, and the frequency of sending the character's location will vary from situation to situation.

Recommended examples

<table data-full-width="false"><thead><tr><th width="257">Situation</th><th>Types of data to send</th><th width="104" align="center">Average sending frequency</th><th>Rapidly increasing acceleration example</th></tr></thead><tbody><tr><td>Player character in a massively multiplayer role-playing game (MMORPG)</td><td>Position (xyz), velocity (xyz), facing direction (z)</td><td align="center">0.3</td><td>Character movement direction, stance, dots, and buffs</td></tr><tr><td>Airplane or vehicle</td><td>Position (xyz), velocity (xyz), acceleration (xyz), facing direction (xyz)</td><td align="center">0.3</td><td>Obstacle Collisions, Sharp Turns</td></tr><tr><td>Player character in a first-person shooter (FPS) game</td><td>Location (xyz), facing direction (xyz)</td><td align="center">0.03</td><td>Immediately after the character changes direction of movement, the sniper rifle is fired.</td></tr></tbody></table>

{% hint style="info" %}
If you have short sending intervals, we recommend that you also enable [**Throttling**](/proudnet.eng/proudnet/using_pn/communication-messages.md#throttling) to avoid the risk of sending too much.
{% endhint %}

### - Spline based follower

<mark style="color:orange;">Proud.CPositionFollower</mark> provides a follower that not only follows the target in a straight line, but also in a curve. This is a <mark style="color:orange;">spline based follower</mark> in the form of a cubic function. This provides a smoother trajectory than a straight line follower. However, it doesn't always look as smooth, so it's best to test it out in gameplay before choosing.<br>

To get a <mark style="color:orange;">spline based follower</mark>, use the methods below.

> * Proud.CPositionFollower.GetSplineFollowerPosition
> * Proud.CPositionFollower.GetSplineFollowerVelocity

Corrections for angles are handled using the methods below.

> * <mark style="color:orange;">Proud.CPositionFollower</mark>: Role of compensation for location
> * <mark style="color:orange;">Proud.CAngleFollower</mark>: Role of compensation for angles

## :books: Hole Punching

As a router also has the characteristics of a router, it means that for the purpose of peer-to-peer communication to create a routing table, packets are exchanged with the other party in advance to create a routing table on each router. The exact name is <mark style="color:orange;">STUN (Simple Traversal of User Datagram Protocol Through Network Address Translators)</mark>.

Here's how the hole punching works

* Full Cone NAT
* Restricted Cone
* Port Restricted Cone
* Symmetric Cone


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.proudnet.com/proudnet.eng/proudnet-note/dictionary.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
