The Game Jam is 19 days in and we've had over 200 entries. I think we're all pretty stunned by the quality of some of these entries.. and it's really obvious that we should have done a Jam 6 months ago. We'll definitely be making this a regular thing from now on.This is the first run of this nomination and vote system, so we're dealing with things in the background and fixing it on the road. There are always going to be little things that pop up and we are being as reactive as we can.
Nominations will close this Sunday and the most nominated games will enter the voting phase. At that point it's a knockout every day. The community will vote on each game, and the one with the lowest vote count will be eliminated. The votes will be reset, and we'll vote on the remaining bunch. Until there is one winner.
It might be a total disaster but I'm looking forward to seeing how it goes.
Some smaller improvements on the menu this week. Rewards now open in a compact popup instead of a whole page, game previews are snappier, and we've fixed an issue with the menu being way too small at higher resolutions (1440p+), as well as smaller style improvements across a majority of the pages.We fixed another issue with the loading screen, where you'd have two loading screens stacked at once.
We now support parties with up to 16 people, up from 8. We've also made a visibility pass, so it's more obvious what's going on when your party leader is joining a game. You can cancel joining without leaving the party, or retry if something goes wrong. We have also fixed problems with following the leader between games, duplicate invites and Steam connection cleanup, with clearer errors when a connection fails.
We're giving assets a stable identity, so you can freely move or rename files without breaking references.
Each asset will now have a GUID stored alongside it in a .meta file, and any references to that resource will store this ID alongside the path. On load, we'll try to resolve the resource by this ID first, and fall-back to the last known path if needed.
It's important you include these .metas in your source control. If you don't, everyone on your repo will end up with different IDs for the same asset, and that's not what you want.This is the first part of the work, covering the core infrastructure and references from GameResource types, including most of the Scene system and Prefabs. References from Valve formats (such as materials referenced inside a model) are still to-do.
We'll keep expanding support until everything uses this new system, but just be mindful for now, and probably don't go rearranging your whole project just yet. We'll get there.
TLDR: Assets now have permanent IDs, so moving or renaming files won't break things that point at them. Just make sure the .meta files travel with your assets and go into source control.
I added a scripting system. This is like a c# version of Lua. This is experimental and I'll be iterating on it. It's not its final form but feel free to have a play with it. It comes with a syntax highlighted ScriptControl for editing the script.. it's a panel based control so it can be used in game.The idea is to add something that can run in place scripts. It'll become part of Doo, and make the transition from ActionGraph easier for a bunch of people. I also want to integrate it into the material editor so it'll allow dynamic expressions on properties.
TLDR: Scripting is here. You write in a built-in code editor and changes run live as you type, so instant feedback instead of building/rebuilding the whole project. It's also a text-based alternative to the visual node graphs (ActionGraph) people have been using.
The Panel system now has a built in docking system.. if you want that. You can use this in your games. You can do the usual stuff, resize the panels, drag from one section to the other. Works just like every other docking system made in the last 10 years.We'll be using this when the editor switches from Qt to Panels.
We have moved ownership of game and panel windows into C#. Window creation, resizing and presentation now sit alongside the managed PanelWindow code, with SDL event routing, cursors and controller connections handled there too.
Key bindings, console configuration and config-script execution have moved with them. This brings more of the application layer into the same codebase as the panel-based editor work and removes a substantial amount of duplicated native window and input code.
TLDR: Windows and input handling have been moved out of the old native code, cutting a load of duplicated code and putting more of the engine in one place
You can now pilot a camera directly from the scene view. Select a camera and click Pilot in its preview window to move it around with the usual viewport controls. The view uses that camera's settings, with a 16:9 frame and rule-of-thirds guides to help line up your shot.This is especially useful for recording camera movement in Movie Maker. Press Alt+F8 to start or stop recording while you fly, then use the Smoothen tool to tidy up any sudden movements. Press Escape when you are done piloting.
In-game demo recording (using the movie command) now more accurately captures your scene. We've added support for fog and skybox related components, and various bugs with first-person view models are fixed.
Video exporting has also been improved, for when you've finished editing your demos in Movie Maker. The encoder should now never skip frames, giving you perfectly smooth motion.
Painter can now draw animated sprites. A new SpriteInstance keeps track of playback independently of the sprite asset itself. This allows you to draw sprites in your panels and on your HUD without needing to do anything special.
When creating a model from context menu in asset browser, you can use Try generating materials to automatically set up materials for your model.
Editor will scan the model folder (and its subfolders) for matching texture sets, create a new material based on chosen shader, and put all found textures into appropriate slots.
Your textures in a set must follow a specific pattern.
Their file name must end with a suffix, like _color, _normal, _rough etc... These suffixes must match what is expected by the shader, you can check that from Material Editor.
Textures must start with a name that matches material slot name in the model. So if you assigned a material slot to your model in Blender with a name my_cool_material, then texture set for this slot must start with this name too. For example, my_cool_material_color.
Editor supports any amount of material slots, it will generate a material for each slot as long as model has all necessary texture sets provided.
This should work with all shaders, including custom ones, as long as your shader properly declares expected suffix name inside texture input slots. (see docs for shader attributes)
This feature isn't a replacement for anything, it's just an alternative workflow that you can use for fast model+material setup.
Custom shaders can now access a model's third and fourth UV channels through the LowPrecisionUv2 and LowPrecisionUv3 vertex-input semantics.
They are not available in your shader out of the box, you need to add them into your VertexInput struct in the shader first. Here's how you can add UV2/UV3 on top of the standard vertex input:
VS
{
// Adding fields for UV2/UV3 channels on top of standard vertex input
#include "common/vertexinput.hlsl"
float2 vTexCoord3 : TEXCOORD4 < Semantic( LowPrecisionUv2 ); >;
float2 vTexCoord4 : TEXCOORD5 < Semantic( LowPrecisionUv3 ); >;
}
I've drastically reduced the size and compile times of shaders by implementing Vulkan Specialization Constants and flagging various static combos (shader variants) as them. This let's us remove repeated work and shader variant code from the shader compilation, it'll still have the same amount of pipelines at runtime.
When applied to complex, the amount of PS compile jobs drops from 5728 to 856, skin drops from 512 to 128. That means substantially less shader compilation work dropping from 6 minute compiles to 1 minute compiles. This is pretty far from when complex.shader used to take 20 hours to compile.
As well as the combo reduction, compiled shaders now store shared modules once per shader program, rather than repeating the same bytecode across combinations. Modules and reflection data are compressed together in groups, and each combination keeps a reference to the code it uses.
All of this together gives us a massive reduction from 129.88MB to 10.80MB for our shipped shaders.
TLDR: Shader features that only change behaviour (not inputs) can now share compiled code instead of each combination needing its own build, cutting the complex shader from 5,728 compile jobs down to 856, which is a huge reduction in shader compilation time.
Fixed the blocky, speckled artifacts some people were seeing around environment probes, shadows and other stuff particularly on AMD RX 6000-series cards. The GPU was being allowed to treat a texture index as uniform when different pixels could actually be asking for different textures.Bindless lets a shader pick a texture by its index in a big array. GPUs run shader invocations together in groups called waves. If that index varies across a wave, the lookup needs to be marked NonUniformResourceIndex. Miss that annotation and the GPU can sample the wrong texture. It can look fine on your machine and turn into the mess above on someone else's.
Our Bindless API now applies these annotations automatically in every shader stage.
The default is safety first. But if you're really sure the index is the same across the wave, you can opt into the uniform path fast path. It's not a guaranteed speedup by any means.
cbuffer DrawConstants
{
uint g_nTextureIndex;
};
// This index is shared by the draw, so use the uniform path.
Texture2D texture = Bindless::GetTexture2D( UniformIndex( g_nTextureIndex ) );
For the longest time we had nearly all terrain splat sampling code stuck in the standard terrain shader. Now it's been moved out to the rest of our terrain API, and you can use it in almost any shader, not just terrain.
To use it in your shader, include terrain/TerrainCommon.hlslin pixel shader section (PS)and simply use Terrain::Sample( float3 WorldPosition, bool bUseGeometricNormals ). It will return a Material struct that contains blended terran material with all textures - albedo, roughness, normal, ambient occlusion, etc...
Second argument decides whether it should copy terrain's baked geometry normals or not - it is false by default. This function will output terrain splat that is visually identical to what you see on the terrain mesh itself, fully reflecting all terrain and material settings as well. This is what main terrain shader uses now too!
I also wrote a pretty big documentation page covering most of our terrain backend - it is probably fair to warn that it is not a final API, and things may change, but this should be sufficient if you'd like to write custom terrain shaders, or do something more complex.
Standalone got some love this week. We fixed not being able to launch exported games that had custom icons. We also embed the s&box project file and other metadata in the .exe, to clean the assets folder up.Exports now include the compiled game assemblies without the accompanying CLL source archives or XML documentation.
Standalone game data also uses the data root directly, avoiding an extra per-game subfolder. Thanks to boxrocket6803 for the data-folder fix.
We got some great shadow fixes from the community this week, covering both how directional shadows look and some distracting rendering bugs.
Soft shadows that actually stay soft
The Shadow Hardness setting could stop making a difference in distant directional-shadow cascades. Even with hardness set to zero, the result could look almost the same as the hardest setting. PolEpie fixed the clamping so the softness control works at a distance too.Drag the divider to compare the same view at Shadow Hardness 0, before and after the fix.
Smoother hard-shadow edges
Another change from PolEpie reduces the repeated teeth along hard directional-shadow edges at the highest shadow-filter quality. The filter transitions as hardness increases, keeping the original soft appearance at hardness zero and using the same maximum of 16 comparison samples.These before/after captures both include the cascade-hardness fix above, so they show the additional filtering improvement. Lower shadow-filter qualities and local lights keep their existing filtering.
No more moving dark lines
Scenes with multiple shadow-casting local lights could show dark lines across surfaces that crawled around as the camera moved. CorentArts tracked this down to calculating the shadow receiver normal inside a light loop, where neighbouring pixels could take different paths.We now calculate that normal before the loop and pass it through the shadow code. Custom shaders can do the same with the new explicit-normal overloads on Light::From, Light::Init and Light::Shadows. Thanks to CorentArts for the fix and everyone who supplied examples in the original report.
Orthographic views
Sam also fixed skewed screen-space shadows in orthographic views. That technique assumes a perspective camera, so we now skip its shadow mask for orthographic cameras.
Thank you for finally fixing the dark lines, because of that awful issue I had to bake the map in Hammer. A separate like for Scripting, that’s really cool. If it can be used directly inside the game and not only in the engine, meaning adding modding support for your own games, that would be amazing.
Good devblog, well done.
A really well rounded update , congratulations.