Familiar Territory

Familiar Territory

4 days ago

Steam Workshop for Games

With tonight’s update we’re releasing the first version of Steam Workshop for games. A lot of players missed the familiarity of the steam workshop, with this update we are bringing it back. Discoverability is still backed by our own workshop, it's a gradual process that we'll give developers time to adjust to. Eventually when we migrate fully to the steam workshop, games, and maps that are not yet published will not be accessible. So we encourage developers to republish. Feel free to discuss this more on our forums, where we outline any workflow changes for developers trying to publish to the workshop now.

Reward Changes

Our weekly item rewards were based on play times and games played. That's in the bin now. In the new system, every week we choose achievements from games on the platform. If you have unlocked those achievements then you get a reward. If you don't unlock them in the weekly period then you don't get a reward. I like this system a lot more. It brings people together in a certain game to get the achievement and encourages people to actually play the games instead of just sit in them. Enjoy!

Source 1 Mounts

Like Garry's Mod, games you own on Steam can be mounted in game and played with in the Sandbox mode. And now we can mount Garry's Mod and other Source 1 engine games - the mount system is engine agnostic, we've already got mounts for Goldsrc, Unreal Engine and others, these can be coded by the community too.

Non Temporal SSR

I've completely rewritten our SSR to be non-temporal, simpler, sharper and 30% faster. 😎

Light Modulators

The new `LightModulator` component filters direct light through a textured rectangle. It works with point lights, spotlights and sunlight and it affects volumetric fog.

I added this primarily to make a nice solution to add water caustic effects without any great hacks, and it does that quite well:

But this has other purposes that I think people will find over time. Clouds is an obvious one.

Fog Controls

I've consolidated our fog components to a new single `Fog` component. It adds a few more nice to have functions to tweak the look of the fog, like distance based skybox color blurring, and sun coloring. More importantly, this is refactored so it now works via a PostProcessVolume - so different parts of a map can have different fog settings, and they can be blended between.

Sprite and Particle Refraction

Sprite and particle renderers now support normal-map refraction, so they can distort the scene behind them. This provides another option for effects such as heat haze and shockwaves.

Light Temperature and Animation

Lights now have separate temperature, tint and intensity controls. Temperature uses a Kelvin slider with neutral white at 6500K, while Tint behaves like the previous light colour setting. Existing lights retain their appearance.

All light types can also animate. There are twelve built-in patterns, including the classic Quake and Half-Life styles, plus custom looping intensity curves and colour gradients. Speed, duration and time offsets let you coordinate lights or keep their flickering out of sync. The animation previews in the editor and can be recorded in movies.

Passworded Servers

Servers and lobbies can now require a password, set through the classic `sv_password` or with `LobbyConfig.Password`. This is in addition to lobbies having friends only or private invite only modes.

More Human Heads

We have added two more feminine heads and another masculine head to the human models. The avatar menu also groups the skin thumbnails into feminine and masculine options.

This is the initial release of these heads, with further adjustments to both new and existing options planned.

Outdated Shader Updates

A big limitation we had blocking improving our shaders, rendering features and performance was how scared we were to break existing UGC. Games and maps could use their own custom shaders and anything we changed had to be very meticulous in order to prevent custom shaders breaking or crashing. The only way to fix them would then be requiring the creators to update and republish their work for the new version. We now do two things:

  • When a breaking shader change is pushed and the shader version is increased, the backend recompiles and serves new shaders in place of the old ones.
  • If we can't find it on the backend yet or you're offline, we'll update the shader locally so it continues working, this can take a few seconds to a minute depending on the shader complexity, they'll be cached to disk.

We can now make more drastic changes to the renderer without worrying about the fragility of breaking UGC 💪

Runtime Shader Compilation

A bonus of doing the above is games can now procedurally create shaders at runtime outside of the editor with the `Shader.CompileAsync` API. Which unlocks some fun sandboxy stuff at runtime like this shadertoy demo.

Crashes & Stability

We've always been fixing crashes, but lately new ones were showing up faster than we could fix them. Some went unnoticed for too long because they were buried among the older ones. So we improved our crash reporting and filtering, and crash reports now collect more data. New crashes stand out as soon as a release goes out, which lets us act on it much sooner.

F11 Developer Tools

The dozens of overlays we had locked behind convars are now in a single consolidated place called dev tools. F11 now opens a dock at the bottom of the game, with an option to pop it out into a separate window, the editor also has a dock for it too.

Alongside CPU, GPU, memory and rendering information, it brings together the console, network traffic and UI inspection. You can inspect synchronized-variable traffic, peers and bandwidth, or drill into frame timings without switching between separate overlays.

Cheaper Anti-Aliasing

We've added CMAA2 as an anti aliasing graphics setting, which is also used in CS2. This is a good compromise between performance and quality from MSAA whilst still being non temporal.

We also never default to 8x MSAA anymore, and have adjusted the quality presets.

GPU Occlusion Culling

I've added GPU occlusion culling, which means skipping drawing objects behind other objects that you can't see. You're probably thinking "that wasn't already a thing?", no it wasn't, obviously we had frustum culling but occlusion culling is a tricky problem to get right, but we've landed on a great solution that works in most scenarios.

On Construct this leads to a 15-20% FPS improvement in areas with a lot of occluded geometry. Some games might get larger or smaller varying results. Occlusion culling is on by default, if you want to compare or debug it there are these convars:

  • `r_occlusion_culling` - toggle skipping objets hidden by the occlusion
  • `r_occlusion_debug` - draws occlusion culling boxes
  • `r_occlusion_freeze` - freezes the culling to the current camera position

Smoother Shadow Transitions

Our shadows had a horrible hard transition between cascades - so I've made it so that the transition is feathered.

There's no performance cost to this, it's implemented as efficiently as possible.

Faster Lighting

We rewrote part of our clustered sorting and shader traversal so lights, envmaps and decals share work across pixels, biggest gains on AMD. Light culling on steam Steam Deck fell from ~4 ms to 0.1–0.16 ms; on RX 580 forward pass was 36–52% faster in many-light tests, these are measurements of specific rendering work in test scenes, rather than a promise of the same improvement to every game.

Clustered API is also simpler for custom shadingmodels: use `ClusterForEach()` for most optimized access to any Light, Envmap or Decal in a cluster.

Less Wasted Rendering

We cut down on rendering work that doesn't contribute anything to the final image. In most games that should translate to slightly higher framerates and lower memory use.

  • Cameras that don't use post-processing no longer render buffers nobody reads.
  • Colour adjustments, colour grading and chromatic aberration are skipped when their settings don't change the image.
  • Ambient occlusion and contact shadows also got cheaper with MSAA off.

Faster Startup, Again

We have continued cutting work from the startup path. Type-library preparation and the resource database scan now begin earlier, overlapping other startup work instead of making the menu wait for them. Our average startup comparison (on my machine) went from 16.31 seconds to 10.16 seconds to launch into the menu.

Networking Performance

We went through the entire networking stack and cleaned up a lot of allocations and redundant work. Now our networking hot paths are now essentially allocation free and the reduced redundant work frees up some frame time.

Publish Only What you Use

About 30% of the assets published in the Top 50 Games are actually unused. Making users download files their game never uses is obviously a waste. We made it easier to only publish with the assets that are actually used in your game, so you can stop shipping dev assets and unreleased content.

Read more about this feature here

In order not to break existing projects this option is only on for new projects, for existing games you will have to enable it manually in the project settings. We really encourage you to enable and use it to optimize your game for size.

Faster Transforms

We're are now keeping transform buffers within cache lines and removed unnecessary locks during transform slot allocation. This means drawing a lot of objects on the screen is now a bit faster.

Community Contribution: Network Object Dormancy

Community Contribution by DeadMonstor

Open Video

Networked objects were doing work every tick even when they had nothing new to send. Each update captured, hashed and compared them again, so large scenes full of idle props were paying for state that never changed. Deadmonstor kindly contributed an automatic network dormancy system, inspired by Unreal Engine. Networked object can now go to to sleep and skip the per-tick snapshot work.

On the `community_bowling` map with 563 networked objects and 32 peers sitting idle, network time per tick dropped from 0.47 ms to 0.09 ms (-81%).

Summary

This was a big update. We tried to stick to the highlights for the blog, the changelog below has the full list of changes with a massive amount of crash fixes, bug fixes and performance updates. A lot of great work from the team and our community contributors. 💖 A lot of our work has been making s&box feel more familiar. Steam Workshop, Source 1 mounts and the Sandbox game all feed into that. We want people to be able to jump in, find things they recognise and know what to do. I know the Steam Workshop move is controversial among our developers, but it's also something players have consistently asked for and we need to strike a balance between what's convenient for developers and what is appealing for players. Neither side can work without the other. The tooling around performance and stability is well established now, our crash rate is below 1%, the dev tools make it much easier to diagnose performance problems and the shader compatibility removes a huge roadblock for improvements. I feel like we're still sometimes chasing our tails making benchmarks faster rather than making the games and maps people actually play run better on the hardware people actually use. But we're making progress. Lots more to come still, so please keep with us. 🤝

Changelog

🎁 Added

Rendering & Shaders

  • CMAA2 - added post-process anti-aliasing, with optional combined MSAA, alongside clearer anti-aliasing/upscaler controls facepunch/sbox PR #6155 by @xezno
  • Light modulators - filter point lights, spotlights and sunlight through textured rectangles or infinite planes, affecting surfaces and volumetric fog facepunch/sbox PR #6193 by @garrynewman
  • Light modulation effects - added scroll, caustics, cloud shadows, rotation, kaleidoscope, chromatic split, ripple and pulse effects, with world-sized UVs and appearance controls facepunch/sbox PR #6193 by @garrynewman
  • Fog - added independent distance and height layers, fixed or sky-derived colours, camera targeting and post-process volume blending facepunch/sbox PR #6185 by @garrynewman
  • Sprite refraction - added normal-map refraction to SpriteRenderer and ParticleSpriteRenderer facepunch/sbox PR #6190 by @garrynewman
  • Camera depth targets - render camera and command-list views into caller-owned depth textures; view/reflection/refraction draws return ViewHandle projection, viewport and depth metadata facepunch/sbox PR #6154 by @garrynewman
  • Render-pass dependencies - added declared resource inputs/outputs and async-compute scheduling for independent GPU passes; managed overlap is automatic when supported, native SSR/GTAO overlap is opt-in facepunch/sbox PR #6071 by @antopilo
  • Depth/normals requests - custom material consumers can request the prepass output through NeedsDepthNormals facepunch/sbox PR #6166 by @antopilo
  • GPU memory warning - warn when GPU memory exceeds its budget facepunch/sbox PR #6151 by @antopilo

Content Mounting

  • Source 1 mounting - ship engine support for Source 1 models, ragdolls, materials, textures, decals, sounds and surfaces facepunch/sbox PR #6114 by @aylaylay
  • Imported lighting - allow mounts to supply ambient probe textures, constant/linear light attenuation, baked-light indices, mixed shadows and static shadow-caster settings facepunch/sbox PR #6159 by @aylaylay

Gameplay & Effects

Editor & Diagnostics

Networking

  • Password-protected games - add sv_password, LobbyConfig.Password, setup/password prompts, protected-server indicators and host-migration support; quickplay skips protected games facepunch/sbox PR #6248 by @handsomematt

Rendering & Gameplay

Creator Tools

Developer Tools

Rendering & Characters

Networking & Gameplay

Creator APIs & Tools

Lighting & Creator APIs

🧼 Improved

Rendering & Shaders

Startup & Packages

  • Startup - remove the old Vulkan splash-rendering path and continue reducing startup waits facepunch/sbox PR #6125 by @xezno
  • Startup preparation - prepare type libraries and scan the resource database earlier, overlap work and retain the software splash until rendering is ready facepunch/sbox PR #6150 by @xezno
  • Startup telemetry - record time to startup window and menu initialization facepunch/sbox PR #6150 by @xezno
  • Package code - request backend-compiled DLLs for the current engine version, cache successful responses and fall back to local code archives when available facepunch/sbox@72ed059 by @handsomematt

Networking

Physics & Movement

Editor & Workshop

Stability & Diagnostics

Engine Development

Shaders & Publishing

Rendering & Physics

Startup & Resources

Publishing & Resources

Networking & Menu

Diagnostics & Engine Development

Rewards & Graphics

  • Achievement rewards - show weekly achievement objectives, progress and links to their games in the rewards menu, replacing playtime/game-count goals facepunch/sbox PR #6390 by @garrynewman
  • Light inspector - organize colour, influence, beam, shadows, fog and animation controls; allow manually entered values beyond slider limits facepunch/sbox PR #6387 by @garrynewman
  • Shader compile parallelism - restore one shader-combination worker per core instead of capping by free memory; ShaderCompiler -j remains available facepunch/sbox PR #6397 by @handsomematt

🪛 Fixed

Rendering & GPU Stability

Physics & Gameplay

Audio & UI

Editor & Resources

Workshop & Mounting

Linux

Rendering

  • SSR editor crashes - propagate the main camera depth/normals requirement to the editor camera, guard missing roughness input, size indirect tracing storage per view and fix non-MSAA normal sampling facepunch/sbox PR #6229 by @sampavlovic
  • Shader compatibility - restore DoAtmospherics as an obsolete wrapper over Fog::Apply and Fog::Transmittance facepunch/sbox PR #6236 by @handsomematt
  • Nested skyboxes - validate skybox content before enabling it and reject nested Skybox3D scenes before their callbacks run facepunch/sbox PR #6226 by @aylaylay

Networking & Tools

  • Connection retries - do not silently abort retrying on temporary Server closed responses during map-change/rejoin flows; report final failure after retries facepunch/sbox PR #6242 by @solwllms
  • Standalone engine path - exported games no longer overwrite the user-level FACEPUNCH_ENGINE environment variable facepunch/sbox PR #6233 by @metapyziks
  • Retail solution generation - stop native error-reporting workers before unloading DLLs to avoid exit crashes with -generatesolution facepunch/sbox PR #6238 by @handsomematt

Networking & Loading

Rendering & Lighting

PatchBot
s&box

PatchBot will keep your Discord channel up-to-date on all the latest s&box patch notes.