Sep: Dimensions!
Dimensions!
Dimensions 🌌
J'annonce fièrement l'ajout d'une des fonctions les plus demandées à être intégrées dans nanos world: les dimensions ! 🥳
Dans cette version initiale, des bugs, des désynchronisations et des choses étranges peuvent arriver, merci de me le faire savoir immédiatement !
Les dimensions sont des mondes séparés dans le côté client, où les joueurs et les acteurs sont séparés. Par défaut, tous les joueurs et entités sont dans la dimension 1
. En déplaçant un Joueur vers une autre dimension, toutes les entités qui ne sont pas de cette dimension seront détruites à ce joueur, et toutes les entités de la nouvelle dimension apparaîtront pour lui.
Cette API est vraiment simple:
actor:SetDimension(nombre)
En envoyant une entité, leurs "enfants" bougeront aussi, exemples :
- Lors de l'envoi d'un Acteur, tous les autres Acteurs attachés se déplaceront également.
- Lors de l'envoi d'un Joueur, le personnage se déplacera.
- Lors de l'envoi d'un Personnage, le Joueur n'est pas déplacé avec. Les armes ou props (et attachées) se déplaceront.
- Lors de l'envoi d'un véhicule, tous les passagers seront également envoyés.
J'ai également ajouté une nouvelle méthode pour faciliter l'utilisation d'événements:
Events.BroadcastRemoteDimension(dimension, event_name, params...)
Cet événement sera envoyé à tous les joueurs de cette dimension.
Si vous envoyez une entité par le biais d'événements distants qui ne sont pas dans la même dimension que le Joueur, l'argument sera remplacé par nil
et une alerte s'affichera.
Nouvelles animations du bloc de ciblage
J'ai retravaillé la façon dont les armes sont bloquées quand elles sont confrontées à des obstacles. Avant, le passage entre la visée et non causait un effet vraiment mauvais et déplaçait le crosshair.
Maintenant, l'arme se pliera de manière procédurale et la visée ne changera pas améliorant beaucoup le game-play !
Valeurs de synchronisation du serveur
Il est maintenant possible d'avoir des valeurs globales synchronisées entre le serveur et le client en utilisant le serveur . méthode etValue()
, avec un nouveau paramètre bool sync_on_clients
. Ces valeurs existeront sur tous les clients via Client.GetValue()
comme d'habitude.
Amélioration des scripts
Nos fonctionnalités de Plan ont été améliorées !
Répartiteurs d'événement
Il est maintenant possible de se lier aux Opérateurs d'Événements de Lua! Rendre la communication du Plan à Lua maintenant possible !
-- Spawns the Blueprint
local blueprint = Blueprint(Vector(), Rotator(), "my-asset-pack::BP_AwesomeBlueprint",)
-- Subscribes to a Blueprint Event Dispatcher
blueprint:BindBlueprintEventDispatcher("GorgeousDispatcher", function(self, arg1, arg2)
-- arg1 is a string and arg2 is an integer
Console.Log("Called from Blueprint!", arg1, arg2)
end)
Vous pouvez trouver plus d'exemples sur notre nouvelle page de documentation : Plan de communication!
Valeurs de retour de fonction
Il est maintenant également possible de récupérer des valeurs de retour dans Lua à partir des fonctions de Plan !
Passing Actors through
And we can pass actors through parameters into and from Blueprints calls, they will be properly parsed into the correct entity when receiving or sending from Lua! E.g. You can create a Blueprint event which receives a Character
or Actor
as parameter, and pass it through Lua, it will be automatically parsed and marshalled to the correct Blueprint variable type!
Scripting Events Variables
Now our internal variables use 8 bytes for passing floats and integers, allowing higher values from being passed through events (network ones too)!
Tick Performance Boost
I managed to improve a lot the performance when having thousands of entities spawned (most were caused by Level StaticMeshes. I implemented smart algorithms to improve when they will perform Tick calculations for certain entities based on distance and real need to tick an entity.
This improved the CPU usage in almost 10x in some cases!
Client Side Network Authority
An experimental feature which has been added is the ability to allow methods of being called in the client-side if the player is the network authority of that entity.
For example now it is possible to call TranslateTo
, RotateTo
, SetForce
, AddImpulse
, SetWeaponAimMode
and SetViewMode
from client side! Which can improve a lot of Sandbox Physics Gun behavior for example!
WebUI Native Tables
Now you don't need to JSON.stringify()
tables to pass to WebUI events anymore! You can pass them directly as the arguments and it will be natively parsed, which means much more performance when passing big tables around, and also you don't need to worry about stringifying or parsing them anymore as they already come as native table as the parameter!
File JSON Parser
Our File entity got a new method to natively load a JSON file and get it's table into Lua:
File.ReadJSONAsync()
File.ReadJSON()
And we've got a big performance improvement compared to reading it as raw string and using the Lua JSON library:
Benchmark comparison loadinga big JSON file (9.5 MB)
Parsing it with Lua JSON library: took 9964ms.
Parsing it with Native JSON parser: took 1057ms.
CEF Improvements
Écran de chargement
I finished integrating CEF into the Loading Screen and now Ultralight has been completely removed from nanos world.
Also we got a new feature for Loading Screen: the ability to stop the Main Menu music! For that you need to call an event from JS:
Events.Call("StopMenuMusic");
Better Error Handling
The error handling has been improved as well, before we didn't get feedback of errors when loading invalid files and now we have.
Character Blend Spaces
Now it is possible to import custom Locomotion Blend Spaces to your Characters. You can override Standing, Crouching and Proning animations. And also set the transition animation between them!
We've got new API methods for that:
Character.SetAnimationIdleWalkRunStanding(anim_path, enable_tip)
Character.SetAnimationIdleWalkRunCrouching(anim_path, enable_tip)
Character.SetAnimationIdleWalkRunProning(anim_path)
Character.SetAnimationsTransitionStandingCrouching(anim_standing_to_crouching, anim_crouching_to_standing)
Character.SetAnimationsTransitionCrouchingProning(anim_crouching_to_proning, anim_proning_to_crouching)
You can find more examples at our new documentation page: Character Locomotion Animations!
Precaching Assets
Now it is possible to precache assets to make them load in Loading Screen (avoiding FPS spikes during game), for that you can just call:
Assets.Precache(asset_path)
All Assets are already precached automatically once referenced, so this new method is useful when you need to precache Assets which will be used in the future or loaded dynamically.
Better Wallbang
Our firing wallbangs were not working properly and I decided to rework it. Now wallbanging water reaches 10x further and causes more damage (before it was not possible to penetrate Water with bullets).
We've also got a new Debug settings to draw Weapon's bullet traces in the world, very useful for debugging:
Menu Improvements
Framerate
Our Main Menu got some improvements, we FPS limit has been hardcoded increased to 120 (was 60) and during loading to 60 (was 30), it is still not great as I want to limit it to monitor refresh rate automatically.
Labels
Our tabs got new labels to improve the User Experience, mainly when creating a New Game. Now it is possible to know how many dependencies you have selected without needing to enter that menus:
New Game
Also in the New Game menu, now all configuration (including dependencies) are loaded from disk's Config.toml file. So we don't need to keep reconfiguring it every time when starting a server!
Debug Settings
We got 3 new debug settings:
Visualize Bullet Traces
Visualize Vehicle Doors
Visualize Character Capsule
Miscellaneous Improvements
Some other improvements and small new features we've got during this month:
- Vehicle now receives
TakeDamage
event! - It is now possible to toggle a bunch of SceneCapture rendering features with
SetShowFlags()
new method. - Our console got several improvements on client side.
- It is now possible to draw Materials, WebUI and SceneCapture into
Canvas
(experimental)! - I implemented in the scripting API a way to have multiple return values, so some methods will start getting that!
- Now Databases will return an error parameter if anything failed.
- All Character interaction (grab Prop, pickup Weapons, enter vehicles) were reworked, and now the traces are 100% precise when interacting with big objects. Also I striped the extra components needed for that, which will improve performance with too many interactable objects spawned.
Conclusion
We had many significant advances this month! Blueprint improvements were a great achievement for me because I had to do a monstrous reverse engineering on Unreal and several memory magic to intercept events.
The addition of dimensions was a very much requested feature and greatly expands the limits for game creation!
Performance improvements are always very welcome and I love to make them, we still have a lot of room for further improvements!
Furthermore, I devoted some time to work on some big refactoring internally, some parts of the code were starting to get dumped and messy, and they are not using the most modern C++20 techniques. Sometimes these refactoring are great to take the control back over our own code. 😄
In the next updates, I plan to reorganize the API (as discussed in our last #poll), we added methods which started accumulating in Static Classes without much cohesion between them. I intend to separate them and create new static classes for each, making the understanding and search for methods in the API much easier.
Another improvement I started to implement is the possibility of multiple constructors for entities. Which will allow we to have smaller ways to spawn the entities. This will be very useful if we want to spawn a Sound 2D or 3D for example (2D sound does not need the location parameter).
This is all this month, I see you next month with many more improvements and news! Thank you so much! 💖