English Stranded III Dev. Blog

106 replies
Goto Page
To the start Previous 1 2 3 4 5 6 Next To the start
11.07.21 09:23:11 pm
Up
DC
Admin
Offline Off
Particle Effects
I've worked on particle effects. Not only the particles themselves but also systems around them. You can now define effects which consist of particles and sounds (both optional - it can also be just sounds or just particles) in Stranded III. These effects can either be specified in other places e.g. the effect that is played if someone steps on or hits a specific material or they can be spawned at will via Lua scripts. The system uses pooling so effects don't have to be re-instantiated all the time (= better performance).

I've also drawn my own particle sprite sheet. The advantage of having multiple sprites in one single texture is that you only need one material for all your particle effects. This reduces rendering overhead if multiple particle effects are visible at the same time. Okay, well.. in reality I need glowing and non-glowing sprites etc. so I have to use different shaders and therefore it's not just one material. Using the sheet improves performance nevertheless.

That's what the sheet looks like right now. There's still enough room for additional effects!
IMG:https://stuff.unrealsoftware.de/pics/s3dev/particlesheet_pre.jpg

> Click for bigger version


I was quite scepticale when I started using Unity's particle system. Before that I was used to entirely programming particle effects on my own. That's how I did it in all my previous games. The advantage of programming particle effects is that you can do whatever you want. There are absolutely no limitations.

Coming from this approach with unlimited possibilities I was sure that the Unity particle system, which uses a (big) set of settings, would limit me and my creativity a lot. Luckily I did not spot any major limitations yet. Kudos Unity! That particle stuff is actually quite nice and allows to create complex effects. The best part is that you can instantly see your changes which massively reduces iteration times. When I programmed particle effects I had to recompile my projects all the time to see what my adjustments look like.

Here are some of the effects I made. Note that these are just first attempts and that I may (or may not) improve them later.
IMG:https://stuff.unrealsoftware.de/pics/s3dev/fire_pre.gif

> Click for bigger version

If you look carefully you can see that the're even bouncing fire sparks with collision (just one visible in this gif)!

IMG:https://stuff.unrealsoftware.de/pics/s3dev/bubbles_pre.gif

> Click for bigger version


Resarch & Recommendation: Subnautica
I started (and finished) playing Subnautica. Of course primarily for research purposes
It has two major things in common with Stranded III:
1. it's a 3D first person survival game
2. it's made with Unity

If you didn't play Subnautica yet I can highly recommend to give it a try. I got it for free on Epic store some time ago but it's also worth the money. It's super fun to explore the world and it doesn't get boring because events and new crafting abilities keep you entertained.
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
19.09.21 08:26:26 pm
Up
DC
Admin
Offline Off
Responsive Website
Stranded3.com is now responsive and works better on mobile phones. This is something I planned to do for all my pages this year. It's not 100% finished though and I may change a few things in future.

Equipment Icons
I've drawn new equipment icons which better match the building category icons. That means: doodle style stuff.
IMG:https://stuff.unrealsoftware.de/pics/s3dev/ui/equipment_pre.jpg

> Click for bigger version


Automatically Generated Icons
Items in the game can either use images as icons for the inventory or the game can automatically render icons from the 3D models. Automatic rendering can be adjusted with some definition settings to make the items look better. I now made a simple hacky dialog which helps to find the right definition values:
IMG:https://stuff.unrealsoftware.de/pics/s3dev/ui/iconmenu_pre.jpg

> Click for bigger version


Technical Stuff: IDs & Lua
Stranded III is using string identifiers to make things more mod- and script-friendly. Internally however it's working with integer identifiers and references/pointers because they consume less memory and are processed much faster.
When writing Lua scripts you can now benefit from the best of both of these worlds. You can use string identifiers (which will automatically be converted to the internal identifiers) or you can use the internal identifiers.

This script will get the internal identifier for the "log" entity definition:
Code:
1
log = entityDefinition.get("log")

Retrieving the identifier once and using it multiple times in subsequent script parts will be slightly faster than using the string identifier all the time. That's because each time you're using the string identifier, Stranded III will have to do a hash map lookup (it's actually a C# dictionary). If you get the identifier once and reuse it, there will be only one lookup.

Simple, unoptimized approach (100 hash map lookups):
Code:
1
2
3
for i=1,100 do
     entity.spawnOnGround("log", math.random(-50,50), math.random(-50,50))
end


Optimized approach with cached identifier (1 hash map lookup):
Code:
1
2
3
4
logId = entityDefinition.get("log")
for i=1,100 do
     entity.spawnOnGround(logId, math.random(-50,50), math.random(-50,50))
end


This is a micro optimization though and in allmost all cases it's probably easier to just stick with strings. It's just nice to have the possibility to use less of these slow and nasty strings.
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
28.11.21 10:14:17 pm
Up
DC
Admin
Offline Off
Advent
Advent is coming! First candle is on! Hooray!
IMG:https://stuff.unrealsoftware.de/pics/s3dev/advent1.png

Wow! I even painted 2D candles on that 3D lifebuoy! That looks... uh. Whatever! Christmas! Santa! Hey!
Okay.. now prepare for some technical stuff! Fun Fun Fun!

Technical Stuff: Dithering
Dithering is a technique which "fakes" color detail by smartly painting pixels in only few different colors.
One common use case is image compression which works with color palettes. The advantage of palettes is that you don't have to save red, green and blue (and possibly alpha) color information per pixel. Instead you just create a palette with all colors used in the image and then you just save the palette index pointing to that color for each pixel.
In best case this requires much less memory per pixel.
To make that approach efficient the palette must be as small as possible though.
Firstly because the palette itself needs to be saved as well and secondly because the data required for each pixel grows with the size of colors in the palette.
Dithering can be used to reduce the amount of colors in the image. You can for instance create a fake orange by making every even pixel yellow and every odd pixel red. With more sophisticated patterns you can even fake color gradients using just 2 colors.

Fake Transparency With Dithering
A different use case for dithering is faking transparency. It basically works the same way. If you want an image to look transparent you just skip some pixels using a pattern. The more transparent the image is the more pixels are skipped when rendering it.

But Why?
Why would you want to do that though? I mean dithering is visible and looks worse than using more colors / mixing pixels to calculate proper transparency.
The answer is simple: Speed!
When rendering 3D scenes real transparency is quite expensive and costs a lot of performance. The reason for this is they way a 3D scene is rendered. The GPU creates a Z-Buffer which calculates the depth of 3D objects in the scene and is used to determine what to render and in which order. That way the GPU can quickly skip rendering of pixels of objects which are occluded by other objects in front of them. Transparent objects however don't work with that approach because their color has to be mixed with objects behind them. They kind of break the Z-Buffer rendering approach. In Unity transparency can also have a negative impact on batching which can also decrease performance. Fake transparency with dithering dodges these problem because there are no semitransparent pixels anymore which need to be mixed.

Can I Dither In Unity?
Because of the stuff explained above I want to use dithering for transparency! Especially for showing/hiding objects which are far away. I want these to fade in/out smoothly instead of suddenly popping in and out.
Unity supports dithering but there is no proper documentation for that feature and I had to search a lot to make it work. Unity can use dithering for LOD crossfading but all used shaders need to be properly adjusted to support it. At the bottom of the "LOD Group" documentation page we see the variable which controls the transparency: unity_LODFade. So we don't have to use the "LOD Group"-component to make it work (and I don't want to use it for some reasons). We just have to set the unity_LODFade value in all used shaders/renderers to control their fading/transparency value.
Luckily I found this forum post which explains how to do it. Hooray!
Code:
1
2
3
4
5
6
7
8
9
10
//Call inside Start()
rend.sharedMaterial.EnableKeyword("LOD_FADE_CROSSFADE");
 
// Coroutine/Lerp this
Vector4 fadeOutVec = new Vector4(tFadeOut, tFadeOut);
block.SetVector("unity_LODFade", fadeOutVec);
rend.SetPropertyBlock(block); // Blocks can be pooled
 
// Call this one frame after tFadeOut == 0, this will cause static batching to work again
rend.SetPropertyBlock(null);

(code taken from the posted linked above. Posted by sewy. Thanks for that!)

That post also mentions how shaders need to be adjusted for that dither crossfade fun but the explanation isn't very detailed. A better explanation for shader adjustment can be found in this post. Furthermore in that post there's a link to a simple shader which supports dithered transparency / crossfading. It's great for reference and to get started and helped me to adjust other existing shaders to also support dithered transparency.

Optimizations
The code snippet above says in a comment that the ProperyBlocks can be pooled.
In fact you don't even need real pooling there. You can just create one PropertyBlock for each transparency level and use those as often as you want to. This is also what the documentation suggests:
Quote:
The block passed to Graphics.DrawMesh or Renderer.SetPropertyBlock is copied, so the most efficient way of using it is to create one block and reuse it for all DrawMesh calls.

Actually they even suggest to only use one PropertyBlock for everything. I want to skip the overhead of changing the fade value however so I guess my approach is fine too.
I somewhere read that Unity's dither pattern has 16 levels so I prepared my PropertyBlocks this way:
Code:
1
2
3
4
5
6
7
8
9
readonly int LodFadeNameID = Shader.PropertyToID("unity_LODFade");
var propBlocks = new MaterialPropertyBlock[16];
for (int i = 0; i < 16; i++)
{
     propBlocks[i] = new MaterialPropertyBlock();
     float fadeValue = (i + 1) / 16f;
     Vector4 fade = new Vector4(fadeValue, fadeValue);
     propBlocks[i].SetVector(LodFadeNameID, fade);
}

Also note that I used Shader.PropertyToID because using strings is always bad. (okay... it doesn't really matter in a loop with only 16 iterations which is just called once but whatever)

Now to set the transparency of an object the following needs to be done:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Enable crossfade keyword, only needs to be done once
// (Maybe this doesn't need to be done at runtime at all? Further research required!)
var renderers = GetComponentsInChildren<Renderer>(true);
foreach (var renderer in renderers)
{
     renderer.sharedMaterial.EnableKeyword("LOD_FADE_CROSSFADE");
}

// Set transparency (assuming that transparency is a float from 0.0 to 1.0)
int index = Mathf.Clamp(Mathf.RoundToInt(transparency * 15f), 0, 15);
foreach (var renderer in renderers)
{
     renderer.SetPropertyBlock(propBlocks[index]);
}

All this code is just an example. It's not 1:1 the code I'm using in Stranded III. The renderers for instance should be cached because GetComponentsInChildren isn't very fast.

Also when the transparency is back to 1 (fully opaque) the PropertyBlock should be unset. That's because using a different material block breaks Unity's batching and therefore can have a negative impact on rendering performance.
Code:
1
2
3
4
foreach (var renderer in renderers)
{
     renderer.SetPropertyBlock(null);
}


Whew! That was a long one!

Not sure if this is helpful to anyone but I think it's a very important and useful thing which is why I wanted to write it down.

Here's what it looks like (in the big version you can even see the dither pattern):
IMG:https://stuff.unrealsoftware.de/pics/s3dev/ditherfade_pre.gif

> Click for bigger version (2.6 mb)


btw: The compression of that gif is probably one of the best examples for color palettes and dithering!

btw²: Dithering can be seen in a lot of games. So now you know why. It's all about performance (oh and sometimes it also prevents some ugly rendering/sorting issues which can occur with real transparency)
edited 1×, last 28.11.21 10:30:49 pm
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
05.12.21 09:39:57 pm
Up
DC
Admin
Offline Off
Advent II
Advent is here! Second candle is on fire!
IMG:https://stuff.unrealsoftware.de/pics/s3dev/advent2.png


Monstera
Let's welcome a new plant to the Stranded III family: The Monstera! Monsteras are pretty easy to recognize because of their funny leaves which can have holes and slits. That unique look also makes it a sought-after house plant.
IMG:https://stuff.unrealsoftware.de/pics/s3dev/models/monstera_pre.jpg

> Click for bigger version


I plan to make a climbing plant version later which can not only grow on the ground but also on trees, rocks etc.
Monsteras can actually yield edible fruits but I'm not sure yet if this will make it into the game.

... and that's it for today. Sorry. I had to make a post for the second candle and that's all I have to show right now
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
Up
DC
Admin
Offline Off
Advent IV
Three candles! Wait! No, it's four already! Looks like someone totally didn't manage to write a blog post in time! Oops!
IMG:https://stuff.unrealsoftware.de/pics/s3dev/advent4.png


Procedual Map Generation: Clusters
In real landscapes you often see clusters of plants. That's why I thought it would be nice to support clusters in the procedual map generation for Stranded III as well.
This is how you define stuff which should be spawned inside a biome:
Code:
1
2
3
4
entitySpawner {
     entityPattern = ^fern
     block = 1
}

entityPattern defines a regular expression which is used to find matching entities. In this case all entities with IDs starting with (that's what the ^ stands for) "fern" will be included. You can also manually define single or multiple entities for an entitySpawner. block says that the field (1x1 meter = 1m²) the entity is spawned on will be blocked and not be used to spawn any other entities. Higher values than 1 can be used to also block surrounding fields.
This is just a single entitySpawner. You can have as many of these as you want (per biome) and they also have many more settings like weights/ratios, terrain height and steepness etc.

A couple of additional new settings comes with the cluster feature I now implemented. Of course these only have to be set if you want to use the cluster system. Here is a cluster example. It's the above fern stuff with extra cluster settings:
Code:
1
2
3
4
5
6
7
entitySpawner {
     entityPattern = ^fern
     block = 1
     clusterCount = 4,5
     clusterRadius = 3,4
     clusterMinDistance = 0.75
}

clusterCount is a random range which says how many ferns the game should try to spawn per cluster. In this example it will always be 4 to 5 as opposed to the previous example where it will always be one solitary fern. In some cases the clusters may have less ferns e.g. if there is not enough space.
clusterRadius is also a random range. It defines the radius of the cluster. In this case 3 to 4 meters. So here 4 to 5 ferns will be spawned within a radius of 3 to 4 meters.
clusterMinDistance defines the minimum distance between objects. All ferns within this cluster will have a distance of at least 0.75 meters to each other. In general the Stranded III procedual map generation uses a 1x1 meter grid and the above mentioned blocking system. So there's only max 1 entity per m² (if block = 1 is used). Clusters allow more dense placement and this is why there is this min distance setting. It helps to reduce ugly overlapping of entities within clusters. Note however that this entitySpawner also has block set to 1. So all 1x1 meter fields which contain a fern will be blocked for other entities. The blocking will only be applied AFTER spawning all cluster entities so they don't block each other. Otherwise it would not be possible to have higher densities in clusters while also using the blocking system.

Shader: Wind Sway
One of my goals in Stranded III is to have a fast and simple asset creation pipeline. Otherwise content creation would simply take too long. One example for this is that foliage of plants should sway in the wind. I don't want to invest additional time for each 3D model to make that work. Therefore I'm using a shader which uses the UV-coordinates for wind sway effects. On the bottom of the texture there's no swaying. On the top there's maximum swaying. So when creating new textures you only have to care about proper orientation and placement of shaking things in thex texture. When creating new models you only have to choose the right shader to make shaking work properly! Hooray
This is what textures using this shader commonly look like:
IMG:https://stuff.unrealsoftware.de/pics/s3dev/swayshader_y_pre.jpg

> Texture with swaying based on Y-coordinate. Click for bigger version


In many cases however I want to store a lot of swaying stuff in a single texture. Using the Y-coordinate for swaying intensity limits me a lot when arranging stuff inside the texture. Therefore I made an additional shader. It comes with a second texture which contains the sway intensity. It's a bit more work to create textures for this shader because I need that additional texture with sway intensities. It allows me to optmize stuff better and to make better use of texture space though. Here's an example of a texture and the sway intensity texture:
IMG:https://stuff.unrealsoftware.de/pics/s3dev/swayshader_tex_pre.png

> Texture & matching sway intensity texture. Click for bigger version


To make that shader work I had to access the sway texture inside the vertex shader. I didn't know that this was possible but luckily it is (unless you're using an old shader model). I found this thread which describes how to do it in Unity. At first it seemed like it didn't work properly because some of my leaves didn't sway as expected. Turned out that I had to set the "wrap mode" to "clamp" for the sway intensity texture. That fixed my issues!
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
13.02.22 06:54:34 pm
Up
DC
Admin
Offline Off
UI Changes
Making the UI user-friendly is quite a challenging task. Therefore I'm changing it a lot to find a layout that works well.

Originally I wanted the buttons for different in-game menus (backpack, crafting, construction, diary, ...) to be on the left. I now decided to move them to the top. That allows me to show in-game messages on the left side on the screen and they are even visible and easily readable while a menu is open.

I also realized that putting information texts above the crosshair is a really bad idea because a lot of the view is obstructed that way. Therefore I now moved all crosshair context information (such as the name of the thing you're pointing at and possible actions) below the crosshair.

Optimized Map "Files"
I decided to no longer save maps (and savegames) in a single file. Instead each map and savegame will be a folder with several files: A header file with general information about the map, a preview image file and one file for each chunk. This allows me to make saving much faster. This is especially important for quicksaves which should be as fast as possible. When you overwrite an existing save, only the header, the preview image (a screenshot of the current scene) and the MODIFIED chunks will be written. Chunks which did not change at all since the last save won't be touched.

This optimization comes with two downsides:
× It's more annoying to share maps and savegames because you have to share a complete folder and not just a single file
× The operating system has to access many files when loading/saving maps

The first downside is not a big one in my opinion. There might be more room for mistakes this way but once you know how it works it should be fine.
The second one can actually have negative impact on performance. Accessing files comes with some operating system overhead. Moreover the files might be stored in different memory sectors in chaotic order which leads to slower access times. This can make quite a difference on HDDs but if you store stuff on SSDs the impact isn't that big. Overall the benefits outweigh the downsides and most importantly this can significantly reduce load and save times on large maps.

Jumping Chicken
This (Attention: 8mb gif!) is what you get when your raycast and movement code doesn't work as expected. Fun. I only wanted them to move on the ground. Making them jitter like crazy wasn't part of the plan.

Research: Subnautica Below Zero
Another "research" project: Subnautica Below Zero! I already mentioned the predecessor in July last year (Dev Blog 101). Below Zero is a great game as well. Get it and play it if you like survival and exploration stuff!
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
20.03.22 09:47:40 pm
Up
DC
Admin
Offline Off
Bread
I made a new bread model because I never liked the one I made quite a while ago.
Here's the old one:
IMG:https://stuff.unrealsoftware.de/pics/s3dev/models/bread_pre.jpg

> old ugly bread model


And this is the new one:
IMG:https://stuff.unrealsoftware.de/pics/s3dev/models/bread_new.jpg

> amazing new bread model @ Sketchfab

Some UVs/normals look a bit broken on Sketchfab for some reason but no worries - it looks fine in-game!


Ground Foliage
I worked a lot on ground foliage which is automatically rendered by the game on the terrain depending on texture and altitude (and your settings - you can disable most of it for better performance). There's now underwater plant stuff for instance:
IMG:https://stuff.unrealsoftware.de/pics/s3dev/terrain/groundfoliage_underwater_pre.jpg

> Underwater ground foliage. Click for bigger version


Fallen leaves have been added to the jungle foliage. Moreover there are some new plant models (which are not part of the automatically rendered ground foliage but need to be placed either manually or by the procedual map generator).
IMG:https://stuff.unrealsoftware.de/pics/s3dev/terrain/groundfoliage_jungle_pre.jpg

> Jungle ground foliage. Click for bigger version


I still need to add more mossy stuff and trees with more lianas and climbing plants to make the jungle biome feel more like jungle.

Category Tabs
This is just a tiny detail but I'm now graying out item category tabs in the backpack (and other containers) if there are no items of that categeory. This can save the player a pointless click.
IMG:https://stuff.unrealsoftware.de/pics/s3dev/ui/category_tab_grayout.jpg

(the first tab is the "show all categories"-tab)
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
To the start Previous 1 2 3 4 5 6 Next To the start