Skip to content

Commit d95ed4f

Browse files
committed
chore(engine): updating docs
1 parent e7f7178 commit d95ed4f

File tree

13 files changed

+453
-1
lines changed

13 files changed

+453
-1
lines changed

engine/.gh-include

Whitespace-only changes.

engine/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Doxyfile

engine/documentation.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Documentation
2+
=============
3+
4+
The documentation for the engine is seperated between the different libraries of the engine.
5+
Then everything is packed up and put into this site. The documentation is handled on the engine repository and then automatically pushed.
6+
7+
This documentation is written in restructured text in order for it to be easier to operate with. We use sphinx to generate the relevant generated documentation.

engine/how_to_use.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Introduction to using the Engine
2+
================================
3+
4+
Whether you work on this engine as a devlopper or you wanna use this
5+
engine you gonna want to have a test project. This is a walkthrough on
6+
how to setup a basic project
7+
8+
As a devlopper on the engine
9+
----------------------------
10+
11+
As a devlopper you want to be able to use your changes in your project.
12+
Therefore it is recommended to use the provided `cli <https://github.com/NanoForge-dev/CLI>`__
13+
14+
As a user
15+
---------
16+
17+
As a user you can either use the template and change the dependencies
18+
location. Or you can create a project and add the nanoforge
19+
dependencies. Note that it is recommended to use bun as a package
20+
manager.

engine/index.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
Engine
22
======
33

4-
The nanoforge engine is the core
4+
.. toctree::
5+
:maxdepth: 2
6+
7+
registry
8+
documentation.rst
9+
how_to_use.rst
10+
11+
In this doc you will find both the how to use and why use this engine as well as its library.
12+
To understand how to use this engine please refer to :doc:`/how_to_use`

engine/network/index.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Network Overview
2+
================
3+
4+
This page describes the global design and rationale for the engine's networking
5+
libraries: the `network-server` and `network-client` TypeScript packages. These
6+
libraries provide a small, pragmatic networking layer used by the example
7+
`pong-network` game and designed to be easy to understand and integrate.
8+
9+
Goals
10+
-----
11+
12+
- Minimal, predictable protocol for multiplayer games.
13+
- Use well-understood transports: TCP for reliable control messages and UDP
14+
for low-latency, best-effort state updates.
15+
- Provide clear validation hooks (magic value, versioning) to avoid processing
16+
```restructuredtext
17+
Network Overview
18+
================
19+
20+
This page explains how the engine's TypeScript networking packages actually
21+
work and the rationale behind important implementation choices. The two
22+
packages are `network-server` and `network-client` and are used by the
23+
`example/pong-network` project.
24+
25+
Design summary
26+
--------------
27+
28+
- Two logical transports are provided: a reliable, ordered channel (called
29+
"TCP" in the packages) and an unreliable, unordered channel (called
30+
"UDP"). Important: these names refer to channel semantics in the library,
31+
not to raw OS sockets. Implementation details:
32+
- The reliable channel is implemented over WebSocket (node `ws` and
33+
browser `WebSocket`) to provide an ordered, byte-stream-like channel.
34+
- The unreliable channel is implemented as a WebRTC `RTCDataChannel`
35+
created with `ordered: false, maxRetransmits: 0`. WebSocket is used for
36+
signaling/ICE exchange between client and server.
37+
38+
- For packet framing and terminator semantics see the dedicated note:
39+
`docs/network/packet-framing.rst`.
40+
41+
Why these choices
42+
------------------
43+
44+
- WebSocket for reliable messages: WebSocket is universally available in
45+
browsers and easy to host in Node.js. Using it for the "TCP" channel avoids
46+
needing a separate TCP server and simplifies browser + native client parity.
47+
48+
- WebRTC DataChannel for unreliable messages: Browsers cannot open raw UDP
49+
sockets; WebRTC provides a browser-friendly unreliable datagram channel
50+
with low latency. The repository uses WebSocket for ICE signaling and
51+
negotiates a `RTCDataChannel` for actual game-state messages.
52+
53+
- Terminator (magic value) appended at packet end: appending a terminator is
54+
robust against fragmented transport frames. Because WebSocket and RTC
55+
DataChannels can split or aggregate application messages, a terminator
56+
allows the receiver to detect full logical packets regardless of chunking.
57+
58+
- Configurable `magicValue`: The default (`PACKET_END`) is a human-readable
59+
sentinel that makes debugging easier; it is configurable via the server or
60+
client config objects if you prefer a shorter or binary marker.
61+
62+
Serialization and extensibility
63+
-------------------------------
64+
65+
- Example code uses JSON payloads for clarity (easy to inspect and debug).
66+
The transport layer operates on `Uint8Array` buffers, so you can replace
67+
JSON with any binary encoding for
68+
production.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
TCPClient
2+
~~~~~~~~~
3+
4+
**connect** ()
5+
Initiate a WebSocket connection to the server (e.g. `ws://<ip>:<port>`).
6+
7+
:return: Promise<void>
8+
9+
**isConnected** ()
10+
Return `true` when the underlying WebSocket is open.
11+
12+
:return: boolean
13+
14+
**sendData** (*data*)
15+
Send a payload to the server.
16+
17+
:param data: Uint8Array — raw payload bytes.
18+
:return: void
19+
20+
**getReceivedPackets** ()
21+
Return an array of complete packets that were reassembled from received chunks.
22+
23+
:return: Uint8Array[] — array of packet buffers.
24+
25+
26+
UDPClient
27+
~~~~~~~~~
28+
29+
**connect** ()
30+
Open a WebSocket for signaling, create an RTCPeerConnection and initiate an SDP offer.
31+
32+
:return: Promise<void>
33+
34+
**isConnected** ()
35+
Return `true` when the RTCDataChannel is open.
36+
37+
:return: boolean
38+
39+
**sendData** (*data*)
40+
Send a payload on the data channel.
41+
42+
:param data: Uint8Array — raw payload bytes.
43+
:return: void
44+
45+
**getReceivedPackets** ()
46+
Return an array of complete packets reassembled from received data-channel chunks.
47+
48+
:return: Uint8Array[] — array of packet buffers.
49+

engine/network/network-client.rst

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Client Networking (network-client)
2+
==================================
3+
4+
This document describes how the `network-client` package actually connects
5+
to a `NetworkServerLibrary` instance and the concrete APIs you will use from
6+
client-side code.
7+
8+
Overview
9+
--------
10+
11+
A client connects to a single server instance (one TCP/WebSocket control
12+
channel and optionally a single WebRTC data channel for unreliable traffic).
13+
Client responsibilities in a game are typically:
14+
15+
- Initiate a TCP connection and send control commands (join/play/input).
16+
- Optionally negotiate a WebRTC data channel for receiving server snapshots
17+
or sending low-latency updates.
18+
19+
Example
20+
--------------------------------------------------
21+
22+
It works exactly the same with UDP
23+
24+
.. code-block:: javascript
25+
26+
// Wait for connection to be established
27+
async function waitForConnection(): Promise<void> {
28+
if (network.tcp?.isConnected()) return;
29+
30+
return new Promise((resolve) => {
31+
const check = () => {
32+
if (network.tcp.isConnected()) {
33+
resolve();
34+
} else {
35+
setTimeout(check, 50);
36+
}
37+
};
38+
check();
39+
});
40+
}
41+
await waitForConnection();
42+
43+
// Send a json encoded packet
44+
network.tcp.sendData(new TextEncoder().encode(JSON.stringify({ hello: 'world' })));
45+
46+
// Receive raw server packets
47+
const latestsPackets = getReceivedPackets();
48+
49+
// Decode packets if encoded in json
50+
const decodedPackets = latestsPackets.map((packet) => {
51+
return JSON.parse(new TextDecoder().decode(packet));
52+
});
53+
54+
Notes
55+
-----
56+
57+
- See `docs/network/network-client-api.rst` for the exact list available functions.
58+
- For packet framing/terminator semantics see `docs/network/packet-framing.rst`.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
TCPServer
2+
~~~~~~~~~
3+
4+
**listen** ()
5+
Start the WebSocket server and begin accepting clients.
6+
7+
:return: void
8+
9+
**getConnectedClients** ()
10+
Return a snapshot array of numeric client IDs currently connected.
11+
12+
:return: number[] — an array of client IDs.
13+
14+
**sendToEverybody** (*data*)
15+
Send a payload to every connected client.
16+
17+
:param data: Uint8Array — raw payload bytes.
18+
:return: void
19+
:throws: none (errors are logged, not thrown)
20+
21+
**sendToClient** (*clientId, data*)
22+
Send a payload to the client identified by `clientId`.
23+
24+
:param clientId: number — numeric client identifier.
25+
:param data: Uint8Array — payload bytes.
26+
:return: void
27+
:throws: none (logs if client unknown)
28+
29+
**getReceivedPackets** ()
30+
Parse and return complete packets received from each client. Each packet is a `Uint8Array` buffer.
31+
32+
:return: Map<number, Uint8Array[]> — mapping client ID to array of packets.
33+
34+
35+
UDPServer
36+
~~~~~~~~~
37+
38+
**listen** ()
39+
Start the signaling WebSocket and accept incoming client offers (SDP/ICE).
40+
41+
:return: void
42+
43+
**getConnectedClients** ()
44+
Return a snapshot array of client IDs with active data channels.
45+
46+
:return: number[] — list of client IDs.
47+
48+
**sendToEverybody** (*data*)
49+
Send a payload to every connected data channel.
50+
51+
:param data: Uint8Array — raw payload bytes.
52+
:return: void
53+
54+
**sendToClient** (*clientId, data*)
55+
Send a payload to a single client data channel.
56+
57+
:param clientId: number
58+
:param data: Uint8Array
59+
:return: void
60+
61+
**getReceivedPackets** ()
62+
Parse incoming channel chunks and return a map of complete packets per client.
63+
64+
:return: Map<number, Uint8Array[]> — mapping client ID to array of packets.

engine/network/network-server.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
Server Networking (network-server)
2+
==================================
3+
4+
This document explains the actual `network-server` package implementation and
5+
the APIs you will use from server-side code.
6+
7+
Overview
8+
--------
9+
10+
The server listens on configured ports and accepts client connections.
11+
A single server process can accept many clients; typical server responsibilities
12+
in a game are:
13+
14+
- Accept reliable control messages from clients over the TCP (WebSocket) channel.
15+
- Optionally establish `RTCPeerConnection`s (via WebSocket signaling) to receive
16+
unreliable, unordered data channels for low-latency state updates.
17+
18+
Example
19+
--------------------------------------------------
20+
21+
It works exactly the same with UDP
22+
23+
.. code-block:: javascript
24+
// Send everybody a json encoded packet
25+
network.tcp.sendToEverybody(
26+
new TextEncoder().encode(JSON.stringify(
27+
{ type: "are you here" }
28+
))
29+
);
30+
31+
// Check connected clients
32+
const connectedClients = getConnectedClients();
33+
34+
// Receive all packets
35+
const allPackets = network.tcp.getReceivedPackets();
36+
37+
// Get first client packets
38+
const firstClientPackets = map.get(connectedClients[0]);
39+
40+
// Decode packets if encoded in json
41+
const decodedPackets = firstClientPackets.map((packet) => {
42+
return JSON.parse(new TextDecoder().decode(packet));
43+
});
44+
45+
Notes
46+
-----
47+
48+
- See `docs/network/network-server-api.rst` for the exact list available functions.
49+
- For packet framing and terminator semantics see `docs/network/packet-framing.rst`.

0 commit comments

Comments
 (0)