Passer au contenu principal
Version: bleeding-edge 🩸

Concepts essentiels

Ce guide est destiné aux débutants qui souhaitent apprendre les concepts essentiels pour commencer avec le modding et le scripting sur nanos world.

Introduction​

Bienvenue sur nanos world ! Un jeu multijoueur qui vous permet de créer vos propres mode de jeux, importer des ressources personnalisés, des maps et d'étendre complétement ses fonctionnalités avec les scripts Lua.

Avant de plonger dans le modding et le scripting, il est important de comprendre les concepts essentiels de la façon dont tout fonctionne dans nanos world. Cette page vous donnera une brève explication de tout ce que vous devez savoir et des liens pour en savoir plus sur chaque sujet !

Après avoir lu ce Guide, vous serez prêt à commencer la programmation, le modding et la création de contenu !

Packs d'Assets​

Les Packs d'Assets sont le moyen pour les modders d'importer des assets personnalisés dans le jeu, tels que les nouveaux modèles, textures, sons et plus encore. They can be created using Unreal Engine, exported and then added to the server's Assets/ directory in nanos world server as an Asset Pack!

Chaque Pack d'Asset a un fichier de configuration appelé Assets.toml. Cette configuration est utilisée pour lister tous les assets inclus dans le pack, leurs chemins, et d'autres métadonnées telles que leurs types, catégories et tags. Ce fichier est utilisé par le jeu pour charger les ressources et les rendre disponibles dans les scripts Lua via les entités.

Par le biais du Lua Scripting, certaines entités nécessitent un Asset en tant que paramètre. Par exemple, l'entité Prop demande un StaticMesh Reference dans le troisième paramètre du constructeur.

De cette façon, nous faisons apparaître un Prop comme celui-ci, en utilisant la référence de l'asset:

my-package/Server/Index.lua
-- Utiliser l'Asset Pack 'nanos-world' par défaut, qui est déjà inclus nativement dans le jeu
local my_prop = Prop(Vector(), Rotator(), "nanos-world::SM_Cube")

Les packs d'Assets sont un outil puissant pour étendre le jeu et ajouter de nouvelles fonctionnalités, et ils sont essentiels pour les modders qui veulent créer une expérience unique et passionnantes pour les joueurs. En savoir plus sur les Packs d'Assets dans notre Guide d'Assets:

Guide d'Assetscore-concepts/assets

Packages​

Les Packages sont les principaux éléments de construction de nanos world, car ils fournissent un moyen aux scripteurs de créer du contenu personnalisé et des fonctionnalités pour le jeu.

Il y a différents types de packages, chaque type avec une capacité différente, y compris l'exécution de scripts Lua, la création de modes de jeu, la définition de maps et également la création d'écrans de chargements personnalisés !

Script est le type de package le plus courant, il permet aux scripteurs d'exécuter du code Lua sur le client et le serveur qui peuvent écouter les événements, interagissez avec les classes du jeu et modifiez le comportement du jeu de différentes manières.

tip

Les packages peuvent être chargés/déchargés dynamiquement pendant que le serveur est en route avec package reload all !

Each Package is a folder under server's Packages/ directory with a configuration file Package.toml inside, on which we define the type of the package and it's relevant settings.

Les packages peuvent aussi avoir des dépendances sur d'autres packages et Packs d'Assets, ce qui permet aux scripters de réutiliser du code et des ressources sur plusieurs paquets. Cela peut aider à réduire la duplication et améliorer l'organisation, en particulier pour les scripts plus grands ou les modes de jeu.

tip

Si nous voulons qu'un package soit chargé, nous devons le définir dans le [Config.toml]de notre serveur (/docs/core-concepts/server-manual/server-configuration), nous avons une section pour chaque type de paquet (game_mode, loading_screen, map et packages), que nous devons lister les noms de paquets que nous voulons que le serveur charge !

Dans l'ensemble, les packages sont un concept essentiel dans le modding de nanos world, et ils fournissent un moyen puissant et souple de créer du contenu personnalisé et des fonctionnalités pour le jeu. En savoir plus dans notre Guide des Packages:

Guide des Packagescore-concepts/packages/packages-guide

Scripting​

Le scripting est un moyen puissant de programmer et de personnaliser nanos world. Il nous permet d'écouter les événements du jeu, d'apparaître, d'interagir et de changer les entités à volonté.

Tous les codes Lua sont exécutés par le biais de Packages, il est possible d'avoir des scripts qui s'exécute uniquement sur le serveur, sur le client ou sur les deux.

Apprentissage​

tip

Si vous débutez à la programmation, YouTube ou n'importe quel site Web de Cours sont de bons endroits pour commencer à apprendre les bases du codage dans divers langages de programmation.

Pour le scripting en Lua, le Manuel Lua officiel fournit un tutoriel complet sur les bases du langage.

Also, our documentation is a great resource for learning about everything available in nanos world. You can explore our Game-Modes and Packages category to find real examples!

The 🎓 CORE CONCEPTS section provides guides and great information whilst 👨‍💻 SCRIPTING REFERENCE provides technical details of the usage of our API!

Also, our Official Discord is an active community where you can ask questions, get help, and connect with other scripters!

Events​

In nanos world, our API is based on Events, which are similar to Hooks in other games. Everything in the API comes through events, such as when a Player spawns, a Character enters a vehicle or takes damage. You can listen to these events using Lua scripting and perform actions accordingly.

For example we can listen when a Player joins the server or an Entity is spawned:

my-package/Server/Index.lua
-- Subscribes when a Player joins the server
Player.Subscribe("Spawn", function(player)
Console.Log("The player %s has joined the server!", player:GetName())
end)

-- Subscribes when a Prop is spawned
Prop.Subscribe("Spawn", function(prop)
Console.Log("A prop just spawned!")
end)

Read more about Events in the Events Guide:

Events Guidecore-concepts/scripting/events-guide

Classes​

Classes are entities that can be spawned, interacted with, and changed as you wish. We can easily spawn entities like this:

my-package/Server/Index.lua
local my_light = Light(Vector(0, 100, 100), Rotator(), Color.RED)
local my_static_mesh = StaticMesh(Vector(0, 0, 100), Rotator(), "nanos-world::SM_Cube_VR_01")

Or even interact and change the existing ones the way we want:

my-package/Server/Index.lua
local some_prop = Prop.GetByIndex(1)
some_prop:SetMesh("nanos-world::SM_Pyramid_VR")

Read more about Classes in the Classes Guide:

Classes Guidecore-concepts/scripting/classes-guide

Classes statiques​

Besides Classes we also have the Static Classes, which are just Lua libraries with functions which can be called without needing to spawn an entity or have an instance.

For example we can send a Chat message using the Chat Static Class:

my-package/Server/Index.lua
Chat.BroadcastMessage("Hello world!")

Package Folder Structure​

The folder structure of a scripting Package includes Server/, Client/, and Shared/ folders. You can put .lua files in each folder to execute code on the server, client, or both (Shared):

my-package/
├── Server/
│ ├── Index.lua
│ └── *.lua
├── Client/
│ ├── Index.lua
│ └── *.lua
├── Shared/
│ ├── Index.lua
│ └── *.lua
└── Package.toml
tip

Only the Packages of type script, game-mode and map will have this structure, as those are the only ones which run Lua scripts.

The Package only loads the Index.lua file of each base folder (Server/, Client/ or Shared/), this file is responsible for importing other scripting files.

You can find several guides for scripting under 🎓 CORE CONCEPTS / Scripting section in the left sidebar.

Maps​

Maps (or Levels in Unreal) are the entry point of the game, this is where the world is loaded and the entities are spawned in the client side.

To configure a Map, we create a Package of type map, this type is like script, but it's Package.toml has additional settings to configure the map, e.g. we have map_asset = "my-asset-pack::MyLevel" which we need to define which Map Asset this Package will load.

We can configure which map the server will run in the Config.toml, under map = "my-map-package" setting.

tip

We provide 4 built-in Maps which can be loaded without any additional Package or Asset Pack: default-blank-map, default-empty-map, default-ocean-map and default-testing-map.

Also, in the map's Package.toml, we can configure spawn_points and custom_data, which can be accessed through scripting by any Package:

my-package/Server/Index.lua
local spawn_points = Server.GetMapSpawnPoints()
local custom_data = Server.GetMapConfig()

As you could notice, by loading a Map you are also loading a Package with scripts, so you can have custom scripts running per-map. Which can be useful to add custom behaviors such like interactable environments or doors.

Game Modes​

Game-Modes are a type of Package which behave exactly like scripts, with the exception we can just have one game-mode loaded at once, while we can have as many as scripts running as we want.

They should be used to create unique and self-contained game experiences.

Players can select and start servers easily by choosing a game-mode in the New Game section on Main Menu.

Networking​

Our client-server architecture has been designed thinking about the ease and simplicity of everything related to networking and synchronization. Leaving the scripter to worry only with the creative part!

All entities that are spawned on the server are also automatically spawned and synchronized on the client.

When calling a function on an entity in the server side, this function is also automatically called on the same entity on every client connected. Making everyone always to be synchronized with all changes!

For example, if we spawn a Character, and set it's location, all Clients will have it's location updated as well:

my-package/Server/Index.lua
-- Spawns a Character (on server side)
local my_character = Character(Vector(0, 0, 0), Rotator(), "nanos-world::SK_Male")

-- Sets it's location
my_character:SetLocation(Vector(100, 100, 100))

Some Classes can only be spawned on server, others only on client. The same for some functions of them. This way, if you spawn an entity in the client side, it will only exist for that client.

tip

Through this docs, you will find Authority tooltips telling whether a function can be called on server , on client , on both or only on the side which spawned it !

Communication Between Sides​

To be able to send information from the server to client or vice versa, we exposed some especial methods in our Events Static Class to allow that!

my-package/Client/Index.lua
-- Subscribes to a Remote Event on client side
Events.SubscribeRemote("MyClientEvent", function(my_text)
Console.Log("Event received from server! " .. my_text)
-- outputs "Event received from server! hello nanos world!"
end)
my-package/Server/Index.lua
-- Sends a remote Event to all Players in all Client Packages
Events.BroadcastRemote("MyClientEvent", "hello nanos world!")

Read more about Networked Events in our Communicating Between Packages Guide:

Communicating Between Packagescore-concepts/scripting/communicating-between-packages

Synchronized Values​

Besides sending data through Events, which is a dynamic thing, we also have the possibility to bind/set custom values to entities, or even globally in the Server/Client.

For example we can set a value on any entity, which can be accessed by any Package:

-- Sets a 'my_value' value to a Prop
my_prop:SetValue("my_value", 100)

-- Later on, get the value again
local my_value = my_prop:GetValue("my_value")

This will make my_value to be set on this entity globally in this side (client or server).

But we also have the ability to send a synchronized value on an entity (if we are on server side)! For that we just append the true parameter, telling it to be sent and synchronized to all clients too!

my-package/Server/Index.lua
-- Sets a synchronized 'my_value' value to a Prop
my_prop:SetValue("my_value", 100, true)

Those values are accessible by any Package and are a great way to synchronize custom values!

Read more about Entity Values in our Entity Values Guide:

Entity Valuescore-concepts/scripting/entity-values

UI​

User Interface is an essential aspect of the game, we provide several flexible ways to create UI!

WebUI​

The most direct way is with WebUI, which allows you to create and integrate UIs using HTML/CSS/JavaScript, having absolute freedom to create and customize as you want.

It is possible to communicate between Lua and JavaScript using events!

For more information refer to our WebUI tutorial:

Basic HUD (HTML)getting-started/tutorials-and-examples/basic-hud-html

Widget​

Another new and more advanced way to create UI is using Unreal Widget! With them you can have all access to the powerful widgets and even create your own through Unreal Engine and import them in-game, providing a seamless User Experience!

For more information refer to our Widget class page:

Widget Classscripting-reference/classes/widget

Conclusion​

In this guide, we have covered some of the essential concepts of nanos world scripting and modding. These concepts are important to understand as they form the foundation of building any game-mode or script. We hope you can now start creating content and bringing life to your ideas!

If you have any question, don't hesitate in asking questions on our Discord! Our community is amazing and very friendly, we will be glad to help you!

Now we suggest starting by our Quick Start Guide to create your first package!

Quick Startgetting-started/quick-start