Skip to main content

Jan: Sandbox 3.0, Constraints, ToolTips & API++!

· 13 min read
Gabriel • SyedMuhammad
lead developer™

Sandbox 3.0, Cable Physics Constraints, Interaction ToolTips, Docs Improvements, Scripting API++!

Welcome to our roundup of the latest updates from the last month!

Sandbox 3.0

We're happy to announce the latest Sandbox update!

Sandbox Cover

This update brings lots of improvements to the Sandbox game mode: new features, entities, tools, and a big polish pass on the UI and existing systems. It's heavily focused on improving the user experience and making it more fun (and easier) to create content, entities, and tools.

Spawn Menu

Our Spawn Menu was drastically improved. It now displays all items in a Unified List, separated by categories. The Category is highlighted when visible on the screen. And there's a new Search Bar!

Sandbox game-mode Spawn Menu

Context Menu

The Context Menu was the biggest change in this update!

Selecting Entities

You can now Select and Modify Entities by clicking on them while the Context Menu is open.

Sandbox game-mode Context Menu selecting entities

Each entity has its own set of properties that can be modified through the Context Menu. You can configure it programmatically in your custom class by defining the selected_context_menu_items property.

Now a new "preview mesh" will appear when using spawner Tool Guns, showing a ghost preview of the entity you're about to spawn:

Sandbox game-mode customizing Thrusters

Adding a property to Thruster Entity

For example, the Thruster custom particle can be set like this to display on Context Menu:

Client/Thruster.lua
Thruster.selected_context_menu_items = {
{
id = "thruster_particle_asset",
type = "select",
label = "particle",
options = Thruster.assets_list,
callback = function(value)
ContextMenu.selected_entity:CallRemoteEvent("SetParticleAsset", value)
end,
value = function()
return ContextMenu.selected_entity:GetValue("Particle")
end,
},
...
}

Entity Blame

We also added a new feature that shows who spawned/edited an entity when hovering the entity, useful for moderating and knowing who created what.

Entity Blame label showing who spawned/edited an entity

Tutorials

The Tutorials UI has been upgraded and now displays a short description of the tool, and all the keys used by the ToolGun.

Sandbox Tutorials improved UI displaying description and keys

Adding Description and Tutorials to a Tool

You can add custom description and tutorials easily like this, it is automatically picked up by the Tutorials system:

Client/ColorGun.lua
-- Tool Description
ColorGun.description = "Paint props and objects with a selected color"

-- Tool Tutorials
ColorGun.tutorials = {
{ key = "LeftClick", text = "paint object" },
{ key = "ContextMenu", text = "color gun settings" },
}

New Entities

We added a bunch of fun new entities to Sandbox, and there's more on the way!

Retro Camera

The RetroCamera is a polaroid instant camera that lets you take photos in real time.

Sandbox game-mode new Retro Camera Entity

It uses a SceneCapture and outputs a base64 image which is printed immediately onto a photo film, that is synchronized and persistent in the server!

Button & Wire

The Button is a new entity that's pressable, activating and deactivating other entities:

Sandbox game-mode new Button Entity and Wire Tool Gun

You can connect the button to other entities using the new Wire Tool Gun.

Sandbox game-mode new Button Entity activating several devices

It works by keeping a list of "connected" entities and calling :Activate() and :Deactivate() on them, if they implement those methods.

Since some Sandbox entities already implement those methods, you can wire the button to them and create cool integrations.

You can create your own entities and implement these two methods to make it work:

Server/MyEntity.lua
function MyEntity:Activate()
-- Turns on!
end

function MyEntity:Deactivate()
-- Turns off!
end

Photo Frame

The PhotoFrame is a new entity that can display custom images. It supports both Base64 and URLs.

Sandbox game-mode Selecting Entities and new Photo Frame Entity

Sign & FloatingText

We created two new entities, Sign and FloatingText. Both use the new TextRender class to render text in the world, and the text can be customized through the Context Menu.

Sandbox game-mode new Text Entities

New Tools

Besides the new Wire Gun tool, we're also adding more tools in the next updates, such as a Ball Socket Gun, Spring Gun and an Elastic Gun for constraining two ends with different physics constraints.

Elastic Tool Gun Contraption

Refactored APIs

Now, all Sandbox systems are consolidated and exported into a single global variable: Sandbox. You can access all Sandbox systems and methods through it from your scripts, for example Sandbox.ContextMenu or Sandbox.SpawnMenu.

We also created and exposed several new subsystems such as Tutorials, Notifications, SpawnHistory, and even exposed the WebUI as Sandbox.WebUI.

Updated Docs Pages

We have updated all Sandbox docs pages on how to use and integrate the new systems, take a look:

Sandbox game-modeexplore/sandbox-game-mode/

Upcoming

This is just the beginning of our Sandbox 3.0 update, we're still working on many new features and improvements, including more entities, tools, and systems.

One missing system we want to add is an "Input System", so we can interact with entities pressing keys.

A sneak peek of another tool we're experimenting with:

Experimental Wheel ToolGun

Interaction ToolTips

We added a brand new Interaction ToolTip system for Prop, Weapon (Base Pickable), and Base Vehicle. A tooltip (text + image) appears on screen when you look at those interactable objects:

Tooltips on screen when hovering interactable objects

For Props, you can now change the tooltip text using Prop:SetInteractionToolTipText(). This lets you set custom messages like "Open", "Close", or "Press" for interact-only Props.

You can disable this system with the new static method Viewport.SetInteractionToolTipEnabled().

Scripting & API

New Class: TextRender

We already had a TextRender class, but it was actually a Text3D component (from the Unreal Text3D Plugin).

We then decided to create a new class TextRender and rename the old TextRender to Text3D. This gives us a new lightweight class for rendering simple 2D text with a font, while keeping Text3D separate with its own methods (as before).

This new TextRender class also supports custom fonts via TextRender:SetFont().

For this upgrade, we introduced a new Compatibility Version 1.103 so we don't break any existing scripts using the old TextRender class.

Texture Parameters

Texture parameters got a big flexibility boost: any texture parameter now supports loading Base64, URL images (experimental), and cooked texture assets.

Custom Web Images loaded as textures in runtime

You can directly set the URL/Base64 to materials using the Paintable:SetMaterialTextureParameter()!

Cables & Constraints

Cable was heavily improved. "Locked" constraints will no longer be created with an automatically calculated offset. A new parameter was added to Cable.AttachEndTo(), constraint_offset, so you can customize the offset through scripting and have more control over constraints.

We also added a bunch of new methods to customize physics constraint and motor settings, such as :SetLinearMotorPositionSettings() and :SetAngularMotorSLERPOrientationSettings(). See them all in the next blog section.

The Cables spawn performance was also improved: if you use an All-Free constraint, the Physics Constraint now stays deactivated (great when you only want visuals). We also made small improvements to stabilize physics jitter.

New & Improved Methods

We implemented a bunch of new scripting methods this month:

Angular Impulse/Force

You can now add and set Angular Impulse/Force on any actor:

Override Props Mass

Cables Motor & Physics Constraint

Paintable Getters

Actor Render Cull Distance

You can set the render cull distance of any actor now, the distance at which the actor will stop rendering:

Actor Shadows

You can enable/disable shadows on any actor now:

Other New Methods

Improved Methods

Hit Event other_actor Parameter

Now the Hit Event contains a new other_actor parameter, which is the other actor that caused the Hit.

Docs

We've got several improvements to the Docs.

Efficiency Label

We added a new efficiency label to all methods:

Efficiency Label/Popup on all methods

For example, if you hover HTTP.Request(), you will see a "blocking" label in the top right, meaning it's a blocking operation and will freeze the main thread.

All method and event anchor links are now fixed: you can hover and copy the link from any API page. And when clicking an anchor, the page now scrolls with the correct offset.

Improved Search Results

We've also improved the docs search, now it returns more precise results.

Docs Search returning precise results

Docker Tutorial

We got a new community-created tutorial on how to use Docker with nanos world servers, check it out on the Docker Installation page.

Quality of Life Improvements

WebUI Inputs

Besides the new WebUI:HasNodeFocus() method, now pressing Escape while a WebUI node has focus, causes the node to unfocus (instead of opening the escape menu).

Also, while a WebUI node has focus, all game input is ignored. This makes in-game forms and text inputs feel much more "normal", and avoids those annoying cases where the player types into a UI and also triggers gameplay binds.

File Transfer Speeds

We iterated again on the download system, and file transfer speeds are now improved for high-ping players, making joining servers feel smoother in worse network conditions.

VOIP Network Usage

On VOIP, data is now only transmitted to players within ~30 meters (when using local channel), reducing unnecessary bandwidth usage.

Drop Input

Pressing the Drop input (G) now drops the grabbed prop as well.

New Default Assets

We added several new assets to the Default Asset Pack, including new Static Meshes (SM_RetroCamera, SM_PhotoFrame, SM_LightSwitch, SM_PushButton), Sound Effects (button, switches, and thruster sounds), and the full Rocket Thruster Exhaust Particles pack from Fab.

We also improved the Vehicles Skidding particles, fixing some flickering and improving their visuals.

Not to mention several assets collisions were improved, fixing their physics behavior.

First Time Benchmark

Popup asking to find the best settings when launching for the first time

We added a new popup asking to run a First Time Benchmark when starting the game for the first time (it will not run automatically anymore).

Dependencies

Updated dependencies:

  • Unreal Engine has been updated to 5.7.3.
  • CEF has been updated to 144.
  • Sentry has been updated to 1.6.

Conclusion

The Sandbox game-mode is finally taking the shape I wanted for it, becoming really next to my inspiration Garry's Mod version of it. I will have some work to do and expand, but we are much closer than before.

My goal with the Sandbox is for it to become a fun game-mode, that can be an easy source of new integrations and entities. But also a source of good examples of how to implement custom entities, tools and systems for nanos world.

It's always great when I dedicate time to writing scripts and game-modes, besides it being hell of fun, I always find missing methods, problems and I end up integrating and fixing stuff during this period.

I'm all the time focused on improving what we already have and fixing chronic problems, and this month it was possible to add many cool features to the game and the scripting API!

As always, thank you for testing, reporting bugs, and scripting! Stay tuned that there are more to come! See you in the next update! 💙