Difference between revisions of "Engine/Structure"

From Minetest Developer Wiki
Jump to navigation Jump to search
(Created page with "== The base (NMPR) == Everything is built on a small core, that was the original network multiplayer release of Minetest (call it NMPR). Being around 8000 lines of code, it co...")
 
(rename Minetest to Luanti)
 
(32 intermediate revisions by 9 users not shown)
Line 1: Line 1:
== The base (NMPR) ==
+
[[File:minetest-0.3-dfd-visio.png|500px|thumb|right|0.3 data flow diagram - still mostly accurate.]]
Everything is built on a small core, that was the original network multiplayer release of Minetest (call it NMPR). Being around 8000 lines of code, it contains:
+
== General architecture ==
* The map, including simple voxel lighting and rendering code
 
* The client + server logic
 
* The main loop, invoking the client, the server and the rendering.
 
* A bunch of wrappers for OS-dependent things, and utilities.
 
  
As the current code still largely bases on the NMPR, it is useful to look at how it works.
+
Luanti consists of 3 main "components":
  
=== Map (the voxels) ===
+
* Server - runs server-side logic, updating things for connected players.
-
+
* Client - graphics, controls, and logic for a single player.
 +
* Mainmenu - The main menu, before joining a game.
  
=== Network protocol ===
+
Each of these "components" consists of some C++ code and a Lua API for scripting.
The high-level network protocol of NMPR is delightfully simple. There are three commands for the server, and three commands for the client:
 
  
==== Server -> Client ====
+
When playing a game, there must always be a server. A singleplayer game will consist of a client and a server running in the same process but on different threads.
{| class="wikitable"
+
A multiple remote game will consist of a client running locally, and a server running remotely.
|TOCLIENT_BLOCKDATA
 
|v3s16 p, MapBlock data
 
|Send the content of a block (16x16x16 nodes)
 
|-
 
|TOCLIENT_ADDNODE
 
|v3s16 p, MapNode node
 
|Add a node
 
|-
 
|TOCLIENT_REMOVENODE
 
|v3s16 p, MapNode node
 
|Remove a node
 
|}
 
  
==== Client -> Server ====
+
=== Environment ===
{| class="wikitable"
 
|TOSERVER_GETBLOCK
 
|v3s16 p
 
|Ask the server to send the data of a block
 
|-
 
|TOSERVER_ADDNODE
 
|v3s16 p, MapNode node
 
|Inform the server of a placed node
 
|-
 
|TOSERVER_REMOVENODE
 
|v3s16 p, MapNode node
 
|Inform the server of a removed node
 
|}
 
  
Minetest uses it's own reliability layer on top of UDP. It isn't well documented at the moment, and thorough understanding of it isn't that important, so let's skip it as of now.
+
Both the server and the client have an Environment. An environment contains the map, any nodes, players, [[Engine/Objects|objects]], and various other things.
 +
The environment is "stepped" by an interval called a dtime, updating the world and running Lua callbacks.
  
=== Rendering ===
+
The map is a container of MapBlocks. A MapBlock contains 16x16x16 nodes, any  [[Engine/Objects|static objects]], and meta data.
-
 
  
== Programming style ==
+
=== Server ===
Minetest is designed in a fairly basic C++ object oriented way: Almost everything is contained within some kind of a class, with inheritance and interfaces being used sparingly in obvious ways.
+
 
 +
The Server class is the main class for the server. It hosts the update loop, and owns the lifecycle of all other server components.
 +
Whilst there will always need to be a main class to host the update loop, this class may be considered a god class as it contains a lot of other responsibility.
 +
 
 +
In singleplayer or local server mode, the server class is started on a thread
 +
 
 +
=== Client / MainMenu ===
 +
 
 +
The ClientLauncher is used to initialise the window, contains the main menu loop, and is used to determine how the client should be launched.
 +
 
 +
The Game class is the main class for the client. It hosts the clear-draw-display-update loop, and owns the lifecycle of all other client components.
 +
 
 +
== Threads ==
 +
 
 +
=== Stand-alone server ===
 +
* main
 +
:* Doesn't do much
 +
* ServerThread (Server)
 +
:* Runs the server
 +
* EmergeThread (Server)
 +
:* Fetches and generates world
 +
 
 +
=== Client-only ===
 +
* main
 +
:* Runs almost everything in main game loop
 +
* MeshUpdateThread (Client)
 +
:* Does mesh updates in the background
 +
 
 +
=== Singleplayer ===
 +
* main
 +
:* Runs almost everything except server in main game loop
 +
* MeshUpdateThread (Client)
 +
:* Does mesh updates in the background
 +
* ServerThread (Server)
 +
:* Runs the server
 +
* EmergeThread (Server)
 +
:* Fetches and generates world
 +
 
 +
== Classes ==
 +
 
 +
=== IGameDef ===
 +
An interface for fetching pointers to the managers of things. It is passed to almost everything.
 +
 
 +
It is implemented by Client and Server. Neither implements all interfaces.
 +
 
 +
Generally these can be accessed by referring to IGameDef:
 +
* TextureSource
 +
* ItemDefManager
 +
* NodeDefManager
 +
* SoundManager
 +
* MtEventManager
 +
 
 +
This is the main difference between 0.3 and 0.4. In 0.3 this does not exist, because all content is defined in static tables in source code.
 +
 
 +
gamedef.{h,cpp}
 +
 
 +
=== TextureSource ===
 +
Fetches, generates and caches textures.
 +
 
 +
tile.{h,cpp}
 +
 
 +
=== ItemDefManager ===
 +
Stores the definitions of items, by item name. Content is set up at server startup, and transferred from server to client at beginning of connection.
 +
 
 +
itemdef.{h,cpp}
 +
 
 +
=== NodeDefManager ===
 +
Stores the definitions of nodes and the mapping between node ids and names. Content is set up at server startup, and transferred from server to client at beginning of connection.
 +
 
 +
nodedef.{h,cpp}
 +
 
 +
=== SoundManager ===
 +
Stores and plays sounds on the client.
 +
 
 +
sound.{h,cpp}; sound_openal.{h,cpp}
 +
 
 +
=== MtEventManager ===
 +
A minimal event manager currently only used for triggering sounds on the client.
 +
 
 +
event.{h,cpp}
 +
 
 +
=== Client ===
 +
Contains a lot of stuff. Most considerable members are listed here.
 +
* TextureSource
 +
* ItemDefManager
 +
* NodeDefManager
 +
* SoundManager
 +
* MtEventManager
 +
* MeshUpdateThread
 +
* ClientEnvironment
 +
:* ClientMap
 +
:* Players
 +
:* ClientActiveObjects (CAOs)
 +
* Connection
 +
 
 +
Implements IGameDef.
 +
 
 +
client.{h,cpp}
 +
 
 +
=== Server ===
 +
Contains a lot of stuff. Most considerable members are listed here.
 +
* ServerEnvironment
 +
:* ServerMap
 +
:* Players
 +
:* ServerActiveObjects (SAOs)
 +
* Connection
 +
* BanManager
 +
* Lua State
 +
* ItemDefManager
 +
* NodeDefManager
 +
* CraftDefManager
 +
* ServerThread
 +
* EmergeThread
 +
 
 +
Implements IGameDef.
 +
 
 +
server.{h,cpp}
 +
 
 +
=== [[Script Engine]] ===
 +
script/*
 +
 
 +
The script engine contains "core to script"- as well as "script to core"-interface implementation.
 +
 
 +
=== Connection ===
 +
Connection (client->server or server->clients)
 +
 
 +
=== ClientEnvironment (Environment) ===
 +
Contains most of the actual game environment (players, objects, map...)
 +
 
 +
* ClientMap
 +
* Players
 +
* ClientActiveObjects (CAOs)
 +
 
 +
environment.{h,cpp}
 +
 
 +
=== ServerEnvironment (Environment) ===
 +
Contains the actual game environment (players, objects, map, time of day, ...)
 +
 
 +
* ServerMap
 +
* Players
 +
* ServerActiveObjects (SAOs)
 +
 
 +
environment.{h,cpp}
 +
 
 +
=== ClientMap (Map) ===
 +
 
 +
map.{h,cpp}, clientmap.{h,cpp}
 +
 
 +
=== ServerMap (Map) ===
 +
 
 +
map.{h,cpp}
 +
 
 +
[[Category:Core Engine]]

Latest revision as of 22:03, 22 October 2024

0.3 data flow diagram - still mostly accurate.

General architecture

Luanti consists of 3 main "components":

  • Server - runs server-side logic, updating things for connected players.
  • Client - graphics, controls, and logic for a single player.
  • Mainmenu - The main menu, before joining a game.

Each of these "components" consists of some C++ code and a Lua API for scripting.

When playing a game, there must always be a server. A singleplayer game will consist of a client and a server running in the same process but on different threads. A multiple remote game will consist of a client running locally, and a server running remotely.

Environment

Both the server and the client have an Environment. An environment contains the map, any nodes, players, objects, and various other things. The environment is "stepped" by an interval called a dtime, updating the world and running Lua callbacks.

The map is a container of MapBlocks. A MapBlock contains 16x16x16 nodes, any static objects, and meta data.

Server

The Server class is the main class for the server. It hosts the update loop, and owns the lifecycle of all other server components. Whilst there will always need to be a main class to host the update loop, this class may be considered a god class as it contains a lot of other responsibility.

In singleplayer or local server mode, the server class is started on a thread

Client / MainMenu

The ClientLauncher is used to initialise the window, contains the main menu loop, and is used to determine how the client should be launched.

The Game class is the main class for the client. It hosts the clear-draw-display-update loop, and owns the lifecycle of all other client components.

Threads

Stand-alone server

  • main
  • Doesn't do much
  • ServerThread (Server)
  • Runs the server
  • EmergeThread (Server)
  • Fetches and generates world

Client-only

  • main
  • Runs almost everything in main game loop
  • MeshUpdateThread (Client)
  • Does mesh updates in the background

Singleplayer

  • main
  • Runs almost everything except server in main game loop
  • MeshUpdateThread (Client)
  • Does mesh updates in the background
  • ServerThread (Server)
  • Runs the server
  • EmergeThread (Server)
  • Fetches and generates world

Classes

IGameDef

An interface for fetching pointers to the managers of things. It is passed to almost everything.

It is implemented by Client and Server. Neither implements all interfaces.

Generally these can be accessed by referring to IGameDef:

  • TextureSource
  • ItemDefManager
  • NodeDefManager
  • SoundManager
  • MtEventManager

This is the main difference between 0.3 and 0.4. In 0.3 this does not exist, because all content is defined in static tables in source code.

gamedef.{h,cpp}

TextureSource

Fetches, generates and caches textures.

tile.{h,cpp}

ItemDefManager

Stores the definitions of items, by item name. Content is set up at server startup, and transferred from server to client at beginning of connection.

itemdef.{h,cpp}

NodeDefManager

Stores the definitions of nodes and the mapping between node ids and names. Content is set up at server startup, and transferred from server to client at beginning of connection.

nodedef.{h,cpp}

SoundManager

Stores and plays sounds on the client.

sound.{h,cpp}; sound_openal.{h,cpp}

MtEventManager

A minimal event manager currently only used for triggering sounds on the client.

event.{h,cpp}

Client

Contains a lot of stuff. Most considerable members are listed here.

  • TextureSource
  • ItemDefManager
  • NodeDefManager
  • SoundManager
  • MtEventManager
  • MeshUpdateThread
  • ClientEnvironment
  • ClientMap
  • Players
  • ClientActiveObjects (CAOs)
  • Connection

Implements IGameDef.

client.{h,cpp}

Server

Contains a lot of stuff. Most considerable members are listed here.

  • ServerEnvironment
  • ServerMap
  • Players
  • ServerActiveObjects (SAOs)
  • Connection
  • BanManager
  • Lua State
  • ItemDefManager
  • NodeDefManager
  • CraftDefManager
  • ServerThread
  • EmergeThread

Implements IGameDef.

server.{h,cpp}

Script Engine

script/*

The script engine contains "core to script"- as well as "script to core"-interface implementation.

Connection

Connection (client->server or server->clients)

ClientEnvironment (Environment)

Contains most of the actual game environment (players, objects, map...)

  • ClientMap
  • Players
  • ClientActiveObjects (CAOs)

environment.{h,cpp}

ServerEnvironment (Environment)

Contains the actual game environment (players, objects, map, time of day, ...)

  • ServerMap
  • Players
  • ServerActiveObjects (SAOs)

environment.{h,cpp}

ClientMap (Map)

map.{h,cpp}, clientmap.{h,cpp}

ServerMap (Map)

map.{h,cpp}