Passer au contenu principal

2022 Dec: One VM to Rule Them All!

· 9 minutes de lecture
Gabriel T. Nardy
nanos world developer (SyedMuhammad)

Une machine virtuelle Lua à la tête de tous !

Une Seule Machine Virtuelle

Après beaucoup d'analyse, d'étude et de refactorisation. Je suis heureux de vous présenter la nouvelle façon dont les paquets fonctionneront ! Cela était fortement motivé par le manque de possibilité de créer des extensions ou des éléments personnalisés de manière simple.

En plus de la dernière nouvelle mise à jour du système d'entités, ce changement va fortement ajouter aux possibilités de modding & capacités de script à nanos world !

info

Ces changements sont censés avoir le moins d'impact possible et de changements cassés. Tous les tests que j'ai faits jusqu'à présent ont assuré que Tous est toujours rétrocompatible !

Jusqu'à présent, nous avons eu une VM (Machine Virtuelle - ou lua_State) créée par paquet. Cela a fait que chaque paquet est complètement isolé les uns des autres. Il était donc nécessaire de créer des mécanismes de communication entre les Paquets, tels que Événements et Paquetage. xport/Package.Call méthodes, ce qui permettait (dans une manière limitée) aux paquets de communiquer entre eux.

Mais comme cela a été mentionné, cela a entraîné de nombreuses limitations, comme il n'était pas possible pour les paquets d'accéder à des variables ou d'appeler des fonctions directement à partir d'autres paquets, ou encore pire (qui devient plus évidente depuis la dernière mise à jour de Entity System): Il n'était pas possible de partager des classes personnalisées entre les paquets !

Cependant maintenant tout cela sera résolu ! J'ai retravaillé l'ensemble du système de script interne, et maintenant au lieu d'avoir une nouvelle machine virtuelle par paquet, nous aurons un environnement virtuel en bac à sable (en utilisant la fonctionnalité _ENV de l'environnement Lua), en séparant la portée de chaque paquet, mais en leur permettant d'accéder à un environnement global partagé !

Cela permettra aux Paquets de définir des classes, d'exposer des fonctions et de partager des bibliothèques globalement ! Pour que tout le monde puisse l'utiliser sans avoir besoin de mécanismes de contournement pour le faire!

Maintenant, par exemple, vous pouvez simplement charger des scripts supplémentaires ensemble le mode de jeu sandbox qui charge des classes personnalisées d'outils ou d'armes, et ceux-ci apparaîtront automatiquement dans le menu d'apparition, plus besoin de les ajouter manuellement !

Chaque paquet aura toujours son propre environnement sous-global, donc la définition de variables ou de fonctions globales ne les rendra pas disponibles immédiatement pour les autres paquets.

Call & Export

Package.Call et Package.Export ne sont plus nécessaires de la manière traditionnelle. Comme maintenant, nous pouvons partager l'environnement global, nous pouvons définir des méthodes et les exposer à être appelées directement, sans avoir besoin de les Package.Call.

Le Package.Export existera toujours et fonctionnera de la même façon. Mais maintenant il sera possible de "exposer" n'importe quelle valeur à la portée mondiale ! Exemple :

local my_table = { 123, 456 }

function DoSomething(var1)
return var1 + 123
end

Package.Export("MyTable", my_table)
Package.Export("DoSomething", DoSomething)
Console.Log(MyTable[1])
-- 123

Console.Log(DoSomething(456))
-- 579

Classes Héritées

Maintenant, toutes les classes héritées seront disponibles pour tous les paquets, car elles seront créées et exposées au périmètre global automatiquement.

Le premier paramètre sera maintenant utilisé comme nom de variable pour définir la classe dans la portée globale. De plus, il vient juste d'avoir un nouveau paramètre optionnel pour définir une table personnalisée contenant des valeurs à définir dans la table de classe avant sa création :

-- Notez que nous assignons le retour de Inherit à une variable appelée
-- MyPropClassLocal, mais aussi MyPropClass sera défini globalement
-- comme étant notre classe, les deux variables pointent vers la même table de classes
MyPropClassLocal = Prop.Inherit("MyPropClass", {
"my_custom_value" = 123,
"my_another_value" = "hello"
})

local val = MyPropClass.my_custom_value
-- val == 123

Nous avons également ajouté un nouvel événement statique pour obtenir quand une nouvelle classe héritée est enregistrée: ClassRegister:

Prop.Subscribe("ClassRegister", function(class)
-- Faire quelque chose avec la nouvelle classe
end)

Library Package Type

Avec cette nouvelle façon de travailler sur les paquets, les library ne sont plus nécessaires. Comme maintenant, nous pouvons communiquer directement avec d'autres paquets avec des méthodes globales exposées, nous pouvons simplement définir les méthodes à exporter avec le paquet Package.Export et les utiliser quand nous le voulons.

De cette façon, nous n'aurons seulement deux types de "lua script" Packages: game-mode et script. Tous les paquets library existants seront automatiquement convertis en script lorsqu'ils seront chargés.

RequirePackage

Par conséquent, Package.RequirePackage deviendra également inutile. Comme nous pouvons maintenant réutiliser le même script globalement, cette méthode sera dépréciée en faveur de l'ajout de votre paquet dans la liste package_dependencies de votre Package.toml.

Le paquet nécessitant le nanos-world-vehicles et nanos-world-weapons par défaut les chargera comme un paquet autonome, comme maintenant ils exportent les tables NanosWorldWeapons et NanosWorldVehicles globalement.

Paramètres de GameMode

Nous introduisons le concept de paramètres personnalisés pour les modes de jeu! Ces paramètres peuvent être définis dans Package.toml comme ça:

# game-mode custom settings configurations
[custom_settings]
my_toggle = { label = "enable PVP", type = "boolean", description = "whether to enable PVP or not", default = true }
my_text_input = { label = "type anything", type = "text", description = "custom text!", default = "hello world!" }

Ces paramètres peuvent être configurés à travers les arguments du serveur --custom_settings "my_toggle = true, my_text_input = 'awesome text!', . .", ou à travers l'écran Nouveau jeu, qui analyse et affiche la configuration de façon dynamique lors de la création d'un nouveau jeu:

Les valeurs définies sont accessibles via la nouvelle méthode Server.GetCustomSettings().

Veuillez vous référer à la page de documentation mise à jour pour plus d'informations.

Configuration Files

Comme annoncé sur les blogs précédents, le format des fichiers de configuration change dans la prochaine mise à jour !

tip

Tous les Package.toml et Assets.toml dans l'ancien format s'auto-convertira automatiquement au nouveau format dès qu'ils se chargeront pour la première fois.

Meta Block

Maintenant nous avons un nouvel en-tête commun parmi tous les Assets.toml et Package.toml: [meta].

Il aura le format suivant, qui sera utilisé pour définir les configurations générales principalement utilisées par le magasin :

https://github.com/nanos-world/nanos-world-server/blob/main/_meta.toml

Package

Pour les paquets, nous aurons un nouveau format pour différencier leurs types. Chaque type de paquet aura un bloc de configuration indépendant et différent. Maintenant le type de paquet sera déterminé en définissant un bloc [game_mode], [script] ou [loading-screen].

Voici à quoi ressemblera un Package.toml de gamemode :

https://github.com/nanos-world/nanos-world-server/blob/main/_game_mode.toml

Configuration d'Images

Comme vous l'avez peut-être remarqué, il n'y a plus de réglage image sur le Package.toml, il en va de même pour Assets.toml et pour l'image du serveur dans le Config.toml.

Maintenant, les images doivent être placées physiquement à côté du fichier .toml avec le nom Package.jpg, Assets.jpg ou Server.jpg.

Il s'agit d'une standardisation pour résoudre l'incohérence de l'image entre le magasin et le fichier de configuration, ainsi que pour éviter que des liens externes et malveillants soient placés là-bas. Mais cela apporte l'inconvénient que seuls les serveurs dédiés peuvent désormais afficher une image sur la Liste des Serveurs.

Nouvelles classes statiques

Enfin, nous sommes en train de sortir la mise à jour avec toutes les refactorisations de la classe statique ! Cela nous donnera une excellente nouvelle organisation pour trouver des choses dans la documentation, car maintenant des méthodes spécifiques seront regroupées en classes avec des noms qui ont du sens !

Liste de toutes les nouvelles classes statiques:

Aussi, 🕹️ Entry a reçu un tas de nouvelles méthodes et d'événements de la part du client.

Beaucoup des méthodes de ⌨️ Client et l'ancien 🌍 Monde ont été migrés vers ces classes ! Consultez leurs pages pour obtenir des informations précises !

Événements renommés

En raison de notre dernier sondage, nous commençons à changer tous les noms d'événements qui avaient des noms erronés. Nous les normalisons au niveau actuel, de sorte que des événements comme CharacterEntered seront renommés en CharacterEnter par exemple.

Toutes les modifications maintiendront l'ancien événement fonctionnant comme obsolète. Veuillez faire attention aux nouveaux avertissements pour les mettre à jour vers la nouvelle version !

Assets Plugin Content

Maintenant, il est possible de créer des Asset Packs à partir du Plugin content, ce sera la meilleur façon pour créer des contents à partir de maintenant car il empêche les chemins des assets d'entrer en collision avec les autres.

Pour cela, nous avons ajouté un nouveau paramètre dans Assets.toml pour définir si le Pack d'actifs est un contenu de plugin : is_plugin_content.

Veuillez vous référer à la page de documentation mise à jour pour plus d'informations.

Améliorations du magasin

Le mois dernier, MegaThorx a lancé une mise à jour du magasin, qui améliore considérablement le flux de téléchargement de nouvelles versions. Maintenant nous avons une barre de progression, ainsi que des scripts spéciaux pour vérifier les erreurs de syntaxe et les problèmes potentiels. D'autres fonctionnalités seront également ajoutées dans le futur !

Conclusion

Je n'étais pas très satisfait de la façon dont nanos monde gérait les possibilités de modding et de scripting. Il se sentait très limité et non naturel la façon dont les scripteurs devaient faire pour faire des paquets pour communiquer entre eux. Il ne permettait pas beaucoup de personnalisation ou d'extensibilité.

Avec le système d'entités du mois dernier et maintenant avec cette modification de la façon dont les paquets fonctionnent, J'ai le sentiment qu'une grande porte de possibilités vient de s'ouvrir encore davantage, ce qui donnera une bonne inspiration aux nouvelles choses à ajouter!

Un excellent exemple de ce qui est maintenant possible est de créer un paquet de script vide avec une Arme spéciale personnalisée héritée et il suffit de charger le mode de jeu Sandbox avec votre script pour le faire apparaître dans le menu Apparition, sans besoin d'aucun appel spécial ou de contournement ! Ceci est énorme et lie tous les nœuds restants! 🥳

Ce changement à une seule VM a été un grand changement, au début, je pensais que cela ne fonctionnait pas. mais après avoir terminé et effectué des tests j'ai été très surpris et heureux des résultats! Maintenant nous devons affiner et l'améliorer encore plus!

Le modding va brrr!! Merci pour le soutien ! See you next month! 💪💪