Sandbox Logo
29 January 2021

January 2021

This month we fleshed out the API with things like ragdolls, particles, model data access, physics constraints, ui, hitboxes and a ton of other stuff.

In Source1 ragdolls are created using a special prop_ragdoll entity. In GMod the spawnmenu has to know which entity to spawn to create it as a ragdoll. 

That isn't the case here. You spawn a ModelEntity and set the model.. if the model is a ragdoll it'll just work. This makes a ton of things a bunch easier.

The way the ragdolls move feels really good and meaty.
We started playing with a Sandbox Mode which is based on the GMod sandbox mode. We're not really doing it seriously just yet, but using it as a way to stretch the modding capabilities, to make sure these things are possible.

I started porting gmod sandbox tools so we can see how everything holds up. We have some ideas to improve on the original gmod tools but for now we just want to replicate what we already have in gmod and make sure it all works.

The biggest thing for me is how well the physics get networked in multiplayer, everything just seems to work exactly like it does in a local game. I'm loving Source2 the more I use it.

Balloons are super easy, you can just apply a negative gravity to them and everything works as you'd expect.

Wheels

thrusters

remover

Balloons

You'd think a scoreboard is easy to do. Just get the list of players, draw their names and scores, right? Nope. The problem is that your client might not be aware of the player because it's somewhere else on the map and isn't being networked to you. 

We need to send specific statistics in a way that isn't linked to the player entity. And since we're awesome, we want a way that can be extended by addons and gamemodes without having to alter the original code.

We call this PlayerInfo. The player class has functions to Set and Get it. You can implement it in a property like this.
So then you can use Deaths as a regular variable.

On the client UI side, you interact with PlayerInfo via the PlayerInfo class.
This class, with its Added/Updated/Removed hooks lets you make a scoreboard really easily.
When thinking about what we need to do to start testing, one of the big things is making it easy for people to join each other's games. This month I added support for Lobbies + Matchmaking. 

This lets us see when people are playing games and thanks to Steam Networking, if I create a game then people can join it without revealing my IP or messing with firewall settings.

This ease of joining active games has started a meme in team s&box where you join someone's server while they're alt tabbed from the game and put a box on their head.
Although I worked on the out game console for a good while, and some of the stuff it does is genuinely useful, I'm finding that it's not a replacement for an in game console. And I can imagine that a lot of people will feel the same on release.

A good argument for an in game console is that if our UI system isn't dog shit then it should be more than possible to make a working console system, and it should force us to address any shortcomings with the UI system if we're forced to use it.

Now when I say console, I don't mean just a text box to enter console commands and a scroll box with console output. I imagine it as a bit more than that.

It's a bit rough and empty right now, but we'll work on making it more useful and usable over time.
With the new UI system approaching usable state it's time to start cleaning up and creating the basic HUD elements. These will serve as defaults and examples for people to create their own replacement UI systems.

Models can hold a bunch of KeyValue data. One way this data is used is for things like breakables, which describe how the model should break when it's damaged.

I figured it'd be useful to get that data in game, not just for breakables, but for everything else. So I added a function.
You can use this with any struct, but I'm including the built in stuff by default. I'm trying to avoid re-defining these default structures so we can retain some level of compatibility with other Source 2 assets.
I'm adding extension methods to the Model object for the default stuff. This way the code is all in addon code (so it can be used as reference or adapted).
The TLDR is that when you break a prop in s&box, the gibs are created in C#.
You're 70% made out of water, even your bones are watery, by the end of last month I worked on the water but I didn't had time to write about it.
The plan is to iterate on the water workflow people are familiar with and remove the shortcomings people have with that flow to make things efficient, water systems are divided into two modules that share the same core: Water Volumes and Ocean.
  • Water Volumes work as traditional water bodies you're familiar with in Hammer, you define an area to have a pool and it's filled with H²O, this is tailored for finite bodies.
  • Ocean on the other hand is a point entity and will fill the horizon with such a body, made to ease the creation and iteration of expanse scenes without the need to fake a big water volume.
For your map specific water material you can tweak a number of parameters very easily, and since all the calculation is done analytically, they will eventually even replicate to the simulation, so waves will affect physics simulation.
There's still some work to do on this, right now this is showcasing the cheap-to-render variant of the water material, I am very confident in the whole rendering pipeline of Source 2 now and I should be able to showcase the expensive one soon.
This month I've started working on an extense time of day system, there's still work to be done on it but it's starting to look good, Skyboxes are just a collection of object layers now and are fully scriptable.


If you go up enough you can even see the curvature of the tiny planet and watch the stars:
As with our shaders, they're open to be iterated upon from community developers to their taste, you could use this as a base to add planet specific atmosphere scatter in a space game you'd want to make.

You can still use this on static scenes as well, and the atmospherics will conform to the lighting on the scene, should help in getting the look of your map right without hunting for skybox textures if you choose (Traditional Skyboxes are still supported).
VRAD3 will bake extra information that includes what I'm calling Sky Coverage which works as sort of a directional occlusion for the sky, meaning indirect light from the atmosphere itself will not have constant flat appearance or that such light would bleed while you are in a subway, but if you see a grate leading to the surface, the atmosphere light should gradient through as you'd expect and not interfere with any baked indoor lighting.

I'd want to have sun shadows that would extend to near infinity, I think there's a case to be made with the demand people have for big maps that retain fidelity no matter how far you go or what time of day it is, traditionally such techniques would be very taxing on perfomance, so VRAD will also bake SDF information about the geometry that allows us to trace far shadows for far away geometry very efficiently, among some really interesting effects that I want to expand upon on a later post.

While it's interesting to talk about the technalities, Artists and Mappers will not even have to worry about what's behind this, it should just work.
A skybox scene object doesn't have to be just the infinite sky, but can really be anything and you can easily add it as a layer, I want to improve on the atmospheres later on adding a cloud system.
On the side I've worked on some small graphical changes that I believe benefit greatly the quality of life of the game.

Remember that cool thing from CS:GO where your hands and carrying weapon are self shadowed? I wrote our version of that this month, it's very cheap and will just work with anything you throw at it, there's no longer shadow disparity on your world playermodel and what's on your hand.

I've iterated on the proxy AO pass to have better fidelity and work better for simulating diffuse shadows, the result approximates close to the ground truth reference and it's still cheaper than any SSAO, the calculation is done entirely analytically.

I'd like to avoid screen space depth effects as much as possible, they're often expensive and don't look that great compared to solutions like these.


We're using Forward Shading, while it makes things really perfomant, the way things are set up right now can take a while to iterate on complex effects, we'll probably be doing a pass of cleaning up a lot of these shaders soon, I've already deleted a lot of rendering code that was not relevant for what we are building and it's been helping me to move forward faster.

As a bonus, remember last post where we mentioned shader authoring workflow? Shaders now also just automatically hot compile on save similar like C# code and are compiled on it's own exclusive thread while so.
The Source Particle Editor has always been prohibitively complicated for me. That's why in Garry's Mod I made our own particle system.

I don't really want to have to do that again if I don't have to so I've been looking at how we can make the existing particle system work for us. How can I dumb it down so I can use it but retain all the cool functionality.

Here's what I came up with
  • Deleting redundant functions
  • Naming things more helpfully
  • Naming things so they group naturally
  • Filling in the help + tooltips
  • Putting rarely used options in an Advanced section
  • Making the "Base Properties" button more obvious
  • Start a new particle with a working particle system
  • Switch to "Velocity" instead of "Position Previous"
  • Don't always restart system on property change
There's more stuff we can do I'm sure, but I think this will make a good start. It's already dumbed down to a level where I can use it.
On the code side particle systems have got pretty easy to work with. You can do this clientside or serverside.
You can store the ParticleSystem and update it or destroy it whenever you want.
Setting up hitboxes in ModelDoc kicks ass.
This month I set it up so you can tell traces to hit hitboxes.
You can find out which hitbox it hit in the returned TraceResult.
I had a bit of fun doing this, because clientside hitboxes weren't working.. so I made a raytracing gun to debug it.


When you get stuck in an object, Source 1's player movement detects that and unsticks you as best it can. To do this it tests a bunch of positions around your current position to see if they're in stuff or not. If they're not then it moves there.
My method is more random than the default. I'm just testing random points but it gets the job done for now and we can refine it over time.
I'm having tons of fun developing in relative isolation but I'm also keen to get more people playing with s&box as soon as possible. I'm putting thought into working out the best way to get there and what needs to be done before then.

We haven't done a decent internal test. We've had 3-4 people in a game and messed about, but that doesn't really count. Doing that feels feasible now so that's going to be my aim over the next couple of weeks.

There hasn't been a ton of thought on what it's like to develop without the engine source, or getting people to join your game when they don't have the gamemode. 

This is the stuff I feel I need to address before we can invite people in. But it's also something that we won't get really right until people are using it, so it might be better to give access sooner rather than later.