Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you may not be able to execute some actions.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Image editing tools, such as:
Map editing tools, such as:
On the 30th of September, 2020 the Ozonex editors renders water differently than in the game. Thus it is not representative to what you would see while playing. On the contrary, the GPG editor utilizes the exact same procedures as the game does and is therefore representative. If this is no longer the case when you read this - do notify me and I'll remove this paragraph .
For this article I assume that you have extracted all the textures the game has to offer. If you have not done so and / or do not know how to extract all the texture, I advise you to check the FAQ in the overview article. There is entry explicitly on how to do this properly to allow the GPG editor to generate the correct relative paths to the textures.
Normal map A normal map is commonly used in older rendering engines in order to create detail that cannot be represented by the geometry of a shape. This is quite a sentence and I encourage you to look at the following article:
Water map A water map is a lot like the common normal map, but with a different interpretation of the alpha channel. And because of this difference I do not just call them normal maps, but water maps because the alpha channel is only taken into account when it is used to render water. This article describes the exact interpretation in depth.
It is important to understand the goal of this article. Personally I like to work backwards: we start looking at the end result along with the context and then try to understand how this is accomplished.
A visual comparison between different types of wave normal maps
For more context on what this all means I encourage you to open up the GPG editor and import the following water settings:
You can either download the file or create a new file with a .lua extension. Once inside the GPG editor you can import the configuration via File -> Import -> Water.
For this article we'll look into how the waves on the water surface take shape. This is accomplished by combining various water maps. We'll discuss where we can find the assets regarding to water that the game provides, how we can interpret these assets and how we can make our own.
The game provides a bundle of water maps by default. These are used throughout the default skirmish and campaign maps. Assuming that you have extracted the textures correctly previously, you can find them at:
%InstallationFolder%/textures/engine/
Once inside you'll find a bunch of water maps: waves.dds (no foam channel)
waves000.dds (no foam channel)
waves7.dds (completely white foam channel)
waves001.dds (with foam channel)
waves6.dds (with foam channel)
For each image, the normal map is in the top left and the alpha channel is in the bottom right part.
You are not limited to using these - any repeating normal map can be used! You can think of normal maps that are generally used as strata textures. This can create all kinds of interesting effects. A typical normal map will have an opaque alpha channel - this may cause the water surface to become completely white. When this happens, read the next section carefully: not all normal maps are fit as a water map out of the box.
A water map is the typical purple-looking normal map one would expect, including an interesting interpretation of the alpha channel.
The latter indicates whether or not there is foam on the water. Foam is generated when the total foam value after combining the various water maps is larger than 1.0 (more than white). This effect is generally not visible because the majority of the wave maps provided to us have a black alpha channel. The only reasonable assets that generate the effect is waves001.dds and waves6.dds.
Water of the map Paradise, with foam on the top left and without foam on the bottom right
When you open up the standard map Paradise (scmp_035) you can see one of those water maps among the water properties, in turn generating a small foam effect.
Enable the Water layer (F9) and click on 'Water Properties' in the toolbar of the editor. The tool window will respond and change into a 'Water Properties' window. For this article we're interested in the very last properties: the texture, direction, speed and frequency of the water maps.
Showing the properties in which we're interested in for this article
Assuming that you have extracted the textures correctly previously, click on the '(...)' button and navigate towards the location where they should be stored:
Choose any of the water maps and start experimenting with them.
Other interesting properties are the direction of a normal map, its speed and how often it is repeated on the water surface. You can change these live in the GPG editor:
Direction: Water starts movingtoward top/north. Increasing the number will rotate the effect clockwise.
Speed: The speed in which the water moves, the lower the value the slower the water moves.
Frequency: The size of the texture on the surface. Lowering the value causes the texture to be tiled more on the water surface.
Toying around with the water maps and these settings can create all sorts of interesting effects. From here on the journey is yours. Feel free to share your findings in the comments below!
A visual comparison after changing some of the wave normal maps
You can store water maps inside your map folder. For stratum textures and decal textures there is a specific location where these should be stored. For water there is no hierarchy that you need to use in order for the game to find the files. It is good practice to store them inside the env folder that the other textures require in order to function - this keeps it organized.
As an example, you can store them in: %MapName%/env/
For this tutorial we'll use the following normal map:
You will need an account to be able to download the normal map. The website is free and you will get 15 points for free each day allowing you to download seamless textures. If you are aware how hard it is to make these kind of textures then you know we are practically robbing them via their own freemium model. Do take note of the license on the textures - as an example we cannot share them without explicitly using them and you need to mention the source in the description of the map.
Any normal map texture from the internet will likely have a fully opaque alpha channel. We just learned that this is used to generate foam on the surface therefore you may want to make it black or give it some interesting shape. Save the texture in the .dds format. You can do so by opening it in your favorite image manipulation program that supports the .dds format, such as Gimp or Adobe Photoshop. Use BC3 / DXT5 as your compression algorithm.
A visual example of water that appears to have really large waves in it
When you upload the map to the vault the name of the folder of your map is changed. The path to your custom textures is not adjusted accordingly, in turn the game cannot find the corresponding textures.
To approach this you can use the Ozonex editor to bump your map version which creates a new folder with the correct version and in turn you can use the GPG editor to set the corresponding paths to the new folder structure. When uploading the name of the folder of the map no longer needs adjusting and everything will be good.
With Supreme Commander we are in a unique position in which we can not only toy around with the graphical assets, we can also see how these assets are used in the rendering pipeline of the game. The (HLSL) shaders can be found at:
%InstallationFolder%/gamedata/effects.scd
To strengthen our understanding of this article it is nice to see how the assets are used in the rendering pipeline. For this article, the following bit of code inside the water2.fx file is particularly interesting.
float4 HighFidelityPS(...){ // (...) // calculate the normal we will be using for the water surface float4 W0 = tex2D( NormalSampler0, inV.mLayer0 ); float4 W1 = tex2D( NormalSampler1, inV.mLayer1 ); float4 W2 = tex2D( NormalSampler2, inV.mLayer2 ); float4 W3 = tex2D( NormalSampler3, inV.mLayer3 ); float4 sum = W0 + W1 + W2 + W3; float waveCrest = saturate( sum.a - waveCrestThreshold ); // average, scale, bias and normalize float3 N = 2.0 * sum.xyz - 4.0; // flatness N = normalize(N.xzy); float3 up = float3(0,1,0); N = lerp(up, N, waterTexture.r); // (...) }
The waves that makes the water appear so alive is nothing more than a summation of a bunch of normal maps, each at a different position to simulate the idea of movement.
The values mLayer0 up to mLayer4 are computed in the vertex shader, at an earlier stage of the pipeline. In turn these values are used to get pixel information from a texture using tex2D along with the according texture samplers that describe how certain situations should be taken care of and the coordinates that we wish to sample.
After which the various normal maps summed together, resulting in a single vector. The vector is first used to compute the wave crests values that in turn are used later as part of generating the white foam on the surface water. Take note that the foam value solely uses the alpha channel! The normal is adjusted accordingly to match the fact that we added four normal maps together. It is then used for lighting, reflection, refraction and speculation computations down the road.
The flatness that we can define in the editor is applied as a linear interpolation between the up vector and the normal computed at the surface of the water. The more we flatten the water, the less of the computed water normal will be used and therefore the water will appear to be more uniform.
For more information on the operators used:
You' are using water maps that have (completely) white alpha channels. The alpha channel is interpreted as foam. If you want to use those water maps, change their alpha channels to black (no foam) or some other pattern to introduce foam in a more natural manner.
For the first normal map that has a white alpha channel this doesn't have an effect. Foam is rendered on the water surface when its value is larger than 1.0. In other words: when the combined normal maps have an alpha channel that is more white than white itself.
Two examples of problems with foam
When you upload the map to the vault the name of the folder of your map is changed. As an example,
from: %MapName%/ to: %MapName%.v0001/.
The path to your textures is not adjusted accordingly and in turn the game cannot find the corresponding textures when you download the map from the vault.
To approach this you can use the Ozonex editor to bump your map version and then use the GPG editor to set the corresponding paths. The Ozonex editor already prepares the correct name of the folder of the map. When you upload the map no adjustments are required and therefore no renaming happens.
For more information on normal maps in general:
For more textures that you can use in your projects:
If you have interesting sources, approaches, opinions or ideas that are not listed yet but may be valuable to the article: feel free to leave a message down below or contact me on Discord. The idea is to create a bunch of resources to share our knowledge surrounding development in Supreme Commander.
If you've used this resource for one of your maps feel free to make a post below: I would love to know about it!
Special thanks to @keyser for providing feedback on the article.
I was wondering if it would be possible to have read-only sections of the forum where only a specific number of people (from a given group, for example) can write to.
Specifically I am referring to the balance team having this option. Not because I don't think they are doing a great job but because I think their discussions can provide a great deal of insight to (new) players.
If this would be possible, the balance team has a clear section in which they can discuss everything without interference. And the community can read this and make new topics to ask questions and / or make suggestions in the 'general balance section'. The original section that is 'read-only' for anyone but the balance team remains concise.
An example of why I think this is relevant:
I'm not 100% confident if these are guaranteed balance changes or not, but if it would be, people are generally unaware (beforehand) unless they stumble upon it accidentally. And then you can ask 'why', which is not explained in the pull requests. I bet there has been a discussion about this somewhere that reveals all kinds of insight but I can't find it and I'm confident that a lot of other members are unable to find it too.
And again: without judging whether the change is good or bad: I think the discussions can provide insight to (new) players. And those insights are key to the game and I feel they should be on the forum. But, if and only if it can be protected by the suggestion mentioned earlier. Otherwise I can see myself (accidentally) diving into a topic with a context that I'm clearly not aware of, or ask questions that have been answered months ago and cluttering up the whole (original) discussion.
As a visual example:
Where the 'internal' balance discussions can only be written to by members that are part of the balance group (as there is a 'council of setons' group, 'moderator' group, etc)
edit: I do not speak for the balance team - this post is the result of a discussion I had with another member. I hope someone from the balance team can come on in and share their tale.
A survival unlike any other - fight with up to two additional friends in a race against the clock. The map is designed such one needs to expand in order to survive. Due to the behavior of the AI having only point defenses will not take you far - it will try and evade threats while it is on its way towards the artillery stations.
The goal is to keep two artillery installations alive while they make it rain in another operation off-site. Hence, they are nicknamed the Rainmakers. The enemies will be fierce and they'll try to out smart you whenever they can. There are various difficulty settings available in order to tune the map to your rating. By default the map is a fair fit for a team with an average rating of 1100 (ladder).
Other relevant information:
Link with more information:
Trailers:
A map made in collaboration with @archsimkat . The map is designed to have clear primary and secondary expansions and therefore providing a variety of opportunities for other players to raid. It has been in ladder in October 2020 and hope to see it played more competitively .
Links with more information:
A map made with naval play in mind. The map is designed to have clear primary expansions in the center and the outskirts of the map to assist people in expanding and making map control more worth it. The map is reduced in size to about 26x17. Players start off with relative little mass the further they are from the center to discourage rushing tech 3 air.
The map was made to bring in more attention to the fact that islands are slowly disappearing throughout the globe due to the raising sea levels.
A map made with land play in mind. The map is designed to have clear primary expansions along with various paths one can take to harass the other player. The back-side plateau is an example which is key to protect to prevent your base from being shelled from above.
The map as made to bring in more attention to the fact that in some parts of the world nature is lost to a phenomena called 'desertification', where parts of nature that are near deserts are slowly converted to more desert due to climate change.
The map has all kinds of little tweaks, including but not limited to:
A map made for the SC:TA mapping tournament. The idea was to replicate the TA map 'Long Lakes'. In practice the map doesn't quite look like its target.
A map made in collaboration with @Eo_Empiran. The idea was to create an alternative map for 'Ozone Islands' because we wanted to see something new. In practice the map plays quite different to target map.
The map heavily relies on navy play but with the current balance in combination with the vast distance on the map one can quite easily rush tech 3 air. Suggestions on how to combat this are welcome .
A map made in request by @LegendSmith where he wanted to see more 3 v 3 v 3 maps. The map is heavily reliant on navy play. There are multiple player layouts possible for the map. The intended layout is to have one member of each team on their corresponding main islands, such that there are various 1v1's breaking out. In practice this turned out to be a horrible layout: as soon as one island is won then that team will generally win as a whole.
A map inspired heavily on the Astro Crater map made by BSR_Astro. The map uses the latest map development techniques such as a map-wide lighting and normal map.
In contradiction to the original there is minor reclaim in the spawn locations and there is quite some reclaim in the center. The center is directly influenced by your neutral civilian settings. You can freely enter and exit the water anywhere outside of the craters to allow your commander to easily get out of a dangerous situation.
Link with more information: -https://gitlab.com/supreme-commander-forged-alliance/maps/battle-of-the-craters
A map inspired heavily on Sludge made by GPG. The map is made with the game mode Phantom in mind. It can accompany up to five players. You can reach both neighbors with tactical missiles, but you can only reach one neighbor with a t2 artillery at any time.
A mod made as a replacement for the current featured King of the Hill mod that is part of FAF. At the moment of writing it supports:
It works on any map and there are a few options available:
A point is given for every 30 seconds of control. The hill can be controlled by either having your commander on the hill or reaching a mass threshold with (land or naval) units. A hill can be contested by having your commander on the hill or reaching a lower mass threshold with (land or naval) units.
A series on how water works in Supreme Commander: Forged Alliance. Includes all the information one needs to get started on not only using water more creatively but also understanding various concepts surrounding water more thoroughly.
At the moment of writing the Ozonex editor renders the water quite differently. In turn the rendering of the water that you see in the Ozonex editor is not representative to what you'd see in-game. The GPG editor uses the exact same procedures and is therefore completely representative.
The primary usage of these elevation parameters is to both define the water surface and the range of the water ramp.
Surface Defines at which height the surface is. There can only be one surface of water - multiple surfaces to support maps with varying water height is not supported. Is also used as a marking point as to where the water ramp starts.
Any value above the surface will share the same value as the one on the surface. Uses the pixel in the most top left corner of the water ramp.
Deep Has no meaning of any kind. It is an aesthetic parameter as it is mentioned in the shader that renders the water, but never referenced anywhere in a computation. Has no game play effect of any kind.
Abyss Defines at which height the water ramp is at its lowest. Has no game play effect of any kind - solely used for coloring the terrain underneath.
Any value below the abyss will share the same value as the one on the abyss. Uses the pixel in the most top right corner of the water ramp.
Water with a surface in the left top slice, water without a surface but with the water ramp applied in the right bottom slice
The sun color parameters influence the color of the reflection of the sun. This reflection is a form of specular lighting and the options for the specular lighting are below the header 'Sun and Fresnel', discussed below. The sun color is a typical RGB color component as one would expect.
The values range between 0.0 and 2.0, which allows you to overload the color significantly. This is useful in the case that color is reduced due to shadows of some kind. Typically the range is between 0.0 and 1.0, representing values between 0 and 255 in integral-based colors.
Red The red component of the sun color.
Green The green component of the sun color.
Blue The blue component of the sun color.
A slice with red and a green sun color
The reflection of the sun is unrelated to the angle of the sun defined in the lighting settings. It is always most visible when looking perpendicular at the water, where as the reflections are invisible when looking parallel with the water.
Surface color and interpolation The surface color parameters influence the color of the surface itself. It colors the entire surface based on an interpolation of depth of the water. Lets look at the code to find out how this plays out in practice:
float4 HighFidelityPS(...) { // (...) // as found in water2.fx // we want to lerp in some of the water color based on depth, but // not totally on depth as it gets clamped float waterLerp = clamp(waterDepth, waterLerp.x, waterLerp.y); // lerp in the color refractedPixels.xyz = lerp( refractedPixels.xyz, waterColor, waterLerp); // computations such as reflections and wave crests }
The waterDepth is a value in the range between 0.0 and 1.0. At 0.0 we are at the surface height, at 1.0 we are at the abyss height. We defined these values earlier. The water depth is clamped between the two interpolation values. This has a set of consequences:
That means that if we have a minimal value that is larger than 0 all the water will always have some surface color and isn't transparent. This causes a visual annoyance when zooming out described in another article:
Now that we're aware of this we can also understand why the water becomes opaque when we up the values: we are interpolating between the refracted image of what is behind the water over a single color that we defined ourselves. When we up the values, all that remains is the surface color we defined.
An inconvenient error is that the depth of the water is inaccurately defined. This isn't as obvious when you view the water from up top, but it becomes clear when you view the water from an angle.
The reason for this is that the surface is changed in color, but not the color of the terrain behind the surface. That color is changed according to a water ramp, which we'll touch upon in this article and discuss in another.
Reflections of the sky and water crests will always appear on the surface - these are computed and combined after the surface color computations are complete.
Essentially what the surface color and its interpolation values describe is how clear the water is. Take the water from that cup standing next to you in comparison to water that you mixed with lemonade: the former is clear (hopefully) and the latter is almost opaque.
Reflection is the idea that water reflects light of its environment back to its environment. This is effect becomes more apparent the more parallel our viewing angle is with the water.
Refraction is the idea that water changes the angle of light that passes through it. This effect becomes more apparent the more perpendicular our viewing angle is with the water.
Sun A linear interpolation as to how reflective the sun should be. Not sure where this is being used directly.
Sky Determines how much the sky (cubemap) should be reflected.
Unit Determines how much a unit should be reflected.
Refraction Determines how strongly the water distorts anything that is under water.
The sky reflection parameter has precedence over the unit reflection parameter. If there is no sky reflection, then there won't be a unit reflection either. This correlation exists because the sky reflection parameter is used, on its own, to determine whether we reflect anything at all.
float4 HighFidelityPS(...) { // (...) // as found in water2.fx // lerp the reflection into the refraction refractedPixels = lerp( refractedPixels, reflectedPixels, saturate(skyreflectionAmount * fresnel)); // (...) }
As a result, if you decrease the amount the sky is reflected you'll also decrease the amount a unit is reflected by the water. If there is no sky reflection then only the refracted pixels and the surface color remain.
If you have interesting sources, approaches, opinions or ideas that aren't listed yet but may be valuable to the article: feel free to leave a message down below or contact me on Discord. The idea is to create a bunch of resources to share our knowledge surrounding development in Supreme Commander.
If you've used this resource for one of your maps feel free to make a post below: I'd love to know about it!
There are no requisites for this section.
This introduction guide will try to motivate you as to why decals can be important to both the experience of the player and the perception on the product as a whole. Essentially it is the finishing touch on a beautiful cake, the final mile of a marathon or the last tweaks on that hobby of yours.
And exactly that is why it is one of the hardest phases of the development of a map: it is already fleshed out, the resources are in place, the strata are done and as a whole its seems to be already good and playable. Why spend hours and hours on those decals?
Well, good of you to ask. Lets go on a journey together.
It is important to understand what it is that we're trying to achieve. With my students I like to work backwards: we start looking at the result and try to understand what it is trying to tell us. And let us start off good with some animated content of maps that are either in the vault or under construction. The purpose is to try and understand what it is that these decals mean to you. What is their added value in your own experience?
Hymn and Bone: there are no decals in the slider.
Fifth Nomad Mission: there are only decals in the slider.
Seton's Clutch: There are no decals in the slider
Next off we have a bundle of images of maps. Feel free to post your map down below and I'll ponder on whether it fits the next series. All of them have 2 sections that do show decals and two sections that do not show decals. Again, the purpose is to try and understand what all of this means to you.
Nomad Mission 5, under construction as of writing
Long John Silver, under construction as of writing
Mellow Shallows
When looking at the examples, determine what it is that you think that decals are doing to the map according to you.
Wild Path
Seton's Clutch, before Forged Alliance
Rainmakers Survival
Don't stop here. Experience it live yourself - open up one of the following maps in the Ozonex or GPG editor:
The GPG editor crashes when it is trying to open up a map made by the Ozonex editor that is saved as version 60 (forged alliance), instead of version 56 (vanilla). You need the Ozonex editor to open these up and save them in version 56 of the map file format in order to open them in the GPG editor.
You can find maps that you have downloaded in:
You can find the default maps at the installation folder of Supreme Commander Forged Alliance.
There is a Hide all and Unhide all button to quickly switch. You can find it under Decals -> Tools.
Use CTRL+A to select all the decals. Then press Delete. You can now quickly switch between a view with and without decals via using CTRL + Z and then deleting them again.
I hope this gives an idea to you as to what decals mean to you. This can be anything - there is no good or bad here. Use this as your argumentation.
The next topics cover as to what decals mean to me. We don't have to agree and a discussion is always welcome.
Decals on their own do not affect the simulation. After all, they do not make the terrain more bumpy or change the terrain type - it just looks more bumpy or more grassy. Nevertheless, to me they do affect the interpretation of the simulation. In other terms: to me decals have influence on the gameplay.
Let me elaborate via the usage of strata. Typically a rock stratum is used for places that are expected to be unpathable, such as cliffs, mountains and steep hills. This is done in almost every single map. Especially the default maps that are shipped with the game both learn us and use this association to make it easier for the player to understand the simulation.
In its essence: the rock stratum communicates some form of state to a player: this piece of terrain is likely unpathable.
Other instruments that communicate state are:
And that is how we get back to decals. Decals allow you to tap into a source of associations that the player typically learns throughout playing the game. This source of associations can be used to make your map easier to understand. As an example, would you say there is a hill on this bit of terrain?
After some careful consideration you'll probably say: 'Yes, of course! Look at the lighting on that piece of terrain. There must be some elevation there.' And you're right: there is.
Typically though, after play testing the map with new players, people build turrets behind the hill such that the hill blocks all projectiles flying towards units that are in front of the hill. In turn this forces me as a map designer to question as to why this is.
The reason turned out that even though the state was communicated through lighting, it was communicated too poorly. People do not have time to inspect the terrain when they are playing a real time strategy game. And because the lighting wasn't that significant, people just generally just overlooked the hill.
To communicate 'the hill' better I decided to place a few decals on it.
After which I never had the complaint again of their turrets shooting some hidden hill. Players either made their turrets in front of the hill. And if not, at the very least understood what went wrong and that they could've known about it before hand.
Therefore to me, decals can help you as a designer to communicate state.
The magic circle is an interesting concept in which a user accepts to drop the normal rules of the physical rules and replace them by new rules - allowing you to enter a world such as a game, or a movie, and emotionally live along with that world.
It is the reason that people can cry at the end of a movie: they accepted the environment which describes whether or not a user can accept a new reality as a truth - and in turn, accept anything that follows from that reality.
One can argue that initially when you start playing a game decals can help a lot to capture your imagination. It is what makes the world feel more acceptable - imagine playing this game the first time when all of the maps had no decals on them at all. The gameplay may be just as interesting. All the trailers, footages of the game and other PR material on the other hand would appear blunt and less appealing to you. In turn, you would be less quickly drawn towards the product.
The same still holds if you do not play the game competitively but more casually. The graphical appearance of a map can introduce all kinds of play and allows people to see a higher contrast in this world of play, or, step into it more easily.
We started off with a question what decals are for you. Throughout the article we have tried so far to answer this question by comparing maps with and without decals. The hard truth is however that the majority of popular maps barely have any decals on them at all.
Some people were discussing this fact in the Map & Mod Making Discord channel, and they have a good point. When we take the top 20 of the 18th of August, 2020 then the results are as following:
The overall consensus is that decals aren't that important for a map to be popular. Surely people may enjoy aesthetics maps, but generally, they won't choose a map for aesthetics. They choose a map for the game play experience that the map facilitates. And decals aren't a part of that choice.
There are maps out there that do not have that many decals, while still being appealing all on their own. And there is something to say here: decals are not a necessity. In my opinion they are a powerful tool to enhance an experience, but they cannot create the experience on their own.
A map that is beautiful on its own with a mere 318 decals on it, of which 44 are unique
And all of this brings us back to the original question: is it worth spending time on carefully placing decals on a map? This is question that is for you to answer - some will say no, others will respond with an astounding yes. I hope this article allows you to make this argument with yourself.
For more information on the magic circle:
A few good talks from GDC about level design:
This is a blog post on where you can find the current decals, how you could potentially edit these decals and how to add them back into your map. Take note that I am no designer, hence the 'edits' will be relatively simple.
This blog is also useful for adding custom stratums and, in the near future when it is supported, custom props.
We'll go through the steps with a case study for the one of the missions of the Nomad campaign.
Interesting sources A list of sources that you can use as inspiration for new decals, stratums and textures in general.
A video tutorial by @Morax about the same topic, with the focus on stratums instead of decals:
Tools
If you cannot afford Photoshop then you can use Gimp as an alternative. Gimp supports the .dds format used by Supreme Commander by default.
Take note that Supreme Commander also supports the .png format by default.
The case One of the nomad maps have lava in them. The map doesn't use the default stratum textures for lava, hence creating cracks like in Haven Reef is rather difficult.
The expected results:
The current results:
As you can see the colors do not match as nicely as one would like. Therefore we decide to make a small but evident change to the textures.
Where to find the original decals of Supreme Commander The game itself typically resides inside your Steam folder, from there you can go to:
Copy the file and change its extension from .scd to .zip. Extract the .zip file you just 'created' - the contents contain all the stratum textures of the game, nicely organised per theme.
The files we need for this case study are:
On Windows 10 .dds files can be visualized in the Explorer. Make sure that your view is not on details but instead of large or very large pictograms.
On editing decals I cannot pin point what to do for every possible edit. But I can give you some pointers and will tell you what I do to my textures to make them fit in more.
First of all, lets talk about the alpha channel. This isn't a separate alpha channel as one would typically expect, instead the base layer is not a background layer - it is a separate layer that has alpha encoded directly into the layer itself.
The channels of the decal
The layers of the decal
Therefore whenever you work with an alpha channel, think in terms of layer transparency. This is also useful to know when you search on the internet.
In our case we simply want the colors of the decal to match the colors of the stratum. Take note that the decal has different colors in photoshop than it has in the editor - this is due to the lighting settings of Supreme Commander that are applied to the decal. You can change these settings in the editor.
For the purpose of this blog we want to match the color of the decal with the color of the stratum used commonly on the plateau's. This allows us to more easily 'hide' the decal, making our life easier in the long run. We can do this by navigating to Image -> Adjustments -> Match Color and then choosing the stratum we exported along with it as source.
The original decal
The adjusted decal
Other tools that are certainly interesting without breaking any tiling patterns are:
And pretty much anything inside Image -> Adjustments is generally worth knowing about its existence.
Adding the decal back in Now that we have made our adjustments it is time to make it available within the Editor and within Supreme Commander for usage.
Navigate towards your map. We refer to your map folder as root. Add in the following folders to your map:
Save your decals in .dds format in the decals folder and save any new stratum textures in .dds format into the layers folder. Take note that this nicely matches the structure of the original env.scd file that we extracted earlier.
For the future, you can add in custom props by storing them into root/env/props.
From this moment on the decals and / or additional layers should be visible in the Resource Browser of the Ozonex editor. Choose as Type the Map folder, and the corresponding Category. From this moment on everything works as expected and you can even load in the decals from the old GPG editor.
The outcome of the change
The difference is small but it is now nearly invisible unless you pay really, really close attention to the decal work and know what to look for. In both cases, players either don't do that or they don't know what to look for. All is beautiful.
About you If you have interesting sources that aren't listed yet: feel free to contact me on Discord or the Aeolus in Forged Alliance Forever! Take note that for the latter, if I did not respond, I may have missed your message.
Generation tools, such as:
World Machine templates for this article:
The templates are designed to assist you in creating various map-wide content. They are as they are - merely a template. What the templates can do for you:
The actual work is still up to you, including:
This template is not magic and it still requires you to understand what it can do for you. The template is practically worthless if you have the basic edition of World Machine - you could at most generate a light and ambient occlusion map for maps up to 10x10 reliably.
World machine file: workflow-3026.tmd
workflow-3026.tmd
Supports the following features:
All normal maps are automatically converted to the green-looking normal map format that Supreme Commander expects for its decals.
Overview of the 3026 version
World machine file: workflow-4016.tmd
workflow-4016.tmd
Overview of the 4016 version
World Machine has an interesting interpretation of raw files. Instead of dynamically determining of a raw file is 8 or 16 bits it looks at its extension. A .raw file is considered to be 8 bits where as a .r16 raw file is considered to be 16 bits.
.raw
.r16
When you export the heightmap from any editing tool you'll have a .raw file. However, its contents are encoded in 16 bits. Therefore make sure to rename it to .r16 - otherwise World Machine will not be able to understand the raw file in question.
For a light map you can use a resolution that is the same resolution of the heightmap. That will produce sufficient results. You can view a comparison for a 20x20 (1024 heightmap resolution) map at:
For a normal map you need to use a resolution that is at least eight times the resolution of the heightmap. Anything lower will produce blurred and insignificant results.
It may appear interesting to erode your heightmap too much. This can and will cause issues in the long run where the normal map is no longer in sync with the heightmap in question. Therefore use erosion at your own risk.
World Machine tends to be memory hungry when generating its content. It can help a lot to do your final build in tiles. This significantly reduces the memory consumption of World Machine without affecting the end result. You can read more about it in Chapter 10 of the World Machine User Guide starting at page 70:
This is a professional feature and is therefore not available to everyone.
Whenever you use normal maps make sure that their axis are correctly represented. In the case of map-wide normal maps we need to flip the y-coordinate. This is done in the normal conversion node itself.
A selection of the 5th Nomad Mission without (top) and with (bottom) these techniques applied
A selection of Adaptive Skadi without (top) and with (bottom) the normal map technique applied
A selection of Salt and Pepper without (top) and with (bottom) the normal map technique applied
If you have interesting sources, approaches, opinions or ideas that aren't listed yet but may be valuable to the article: feel free to leave a message down below or contact me on Discord. The idea is to create a bunch of resources to share our knowledge surrounding various fields of development in Supreme Commander.
With thanks to Beherith from the BAR community for the opportunity to have an Q&A for two hours about World Machine With thanks to @svenni_badbwoi for creating the template for World Machine Mt. Daniel 3026. With thanks to @Balthazar for various discussions on normal maps and their interpretation in Supreme Commander.
A map for Supreme Commander: Forged Alliance (Forever)
A long forgotten salt lake that was once facilitating an experimentation facility of the Aeon faction
The map is designed to be either played as a 1 vs 1 or a 2 vs 2. Both teams start on the main land with the intention of one team member moving for the island. The mass doesn't contain any high-concentrated reclaim locations. The expansions should be clear from the design of the map.
There is reclaim on this map. This includes:
The map has various pieces of code to add additional feeling to the map. This includes:
The map has over 2700 decals in order to make it pretty. That is a lot of them.
The water looks different in this image than how it would be rendered in game
The map is based on the TA map Long Lakes
I do not expect to win considering my map doesn't look a whole lot like the original but still have slight optimism because of the sentence 'and lastly how you've chosen to convert the gameplay into FAF' .
A new map enters the arena! Welcome to Root of Beta that attempts to experiment with the latest techniques in making maps. Including but not limited to the following:
Root of Beta
There is a timelapse of the first 8 hours of the process in the make. You can expect it next year .
The mass values in the last screenshot is not as much as it seems - I've taken two times the square root of their original values. E.g., the Monkey Lord is not worth 15K but only ~300.
This is a part of a series on water within Supreme Commander. You can find other series at:
This article dives into the idea of water ramps.
A ramp is nothing more than a very thin gradient. Typically a ramp is a texture with a height of 1 and any with that is some power of 2. The reason for the latter is performance. A few examples of ramps, with a significantly larger height, are already available to you:
waterramp.dds waterramp_eg.dds waterramp_evergreen02.dds waterrampSwamp02.dds
A ramp heavily relies on transparency, hence these may look different depending on your theme of the forum. Typically a ramp looks like this in Photoshop where the block pattern indicates that the texture is transparent there.
For this article I assume that you have extracted all the textures the game has to offer. If you haven't done so and / or don't know how to please review the FAQ in the overview article. There is one explicitly on how to do this properly to allow the GPG editor and the game itself to find the textures.
Water ramps are used in Supreme Commander to color the terrain at each pixel, depending on the depth of the pixel. The functions takes in the depth as an argument that is relative to the surface and abyss parameters. At the surface or higher we expect no coloring of the water, where as a in the abyss we expect the full coloring of the water. Think in terms of lemonade: the deeper you put something in the less visible it will become.
The game provides a bunch of water ramps by default. These are used throughout the default skirmish and campaign maps. Assuming that you have extracted the textures properly previously, you can find them at:
Inside you'll find a bunch of water ramps:
The best way to see them is either through the explorer in Windows 10 or by opening them up in Photoshop. On Windows 10 if you represent images as large pictograms it can, at times, interpret .dds files properly allowing you to see its color scheme.
At the moment of writing the Ozonex editor renders the water quite differently. In turn the rendering of the water that you see in the Ozonex editor is not representative to what you'd see in-game.
Select the Water layer and then click on 'Water Properties' in the toolbar of the editor. The tool window will respond and change into a 'Water Properties' window. For this article we're interested in the 'Texure Maps' and particularly in the 'Water Ramp' texture.
At this point I assume that you have extracted all the textures the game has to offer, as described in the frequently asked questions (FAQ) section of the introduction. Click on the '(...)' button next to the water ramp texture and navigate towards:
Choose any of the water ramps available and start experimenting with them.
You can store water ramps inside your map folder. For stratum textures, decal textures and props there is a specific location where these should be stored. For water there is no hierarchy that you need to use in order for the game to find the files. It is good practice to store them inside the 'env' folder that the other textures require in order to function.
For this tutorial we'll use the following water ramp:
Put the texture in the map folder and then select it accordingly with the GPG editor.
It makes you wonder why there hasn't been a custom rainbow water ramp before'
When you upload the map to the vault the name of the folder of your map is changed. The path to your custom water textures is not adjusted accordingly, in turn the game cannot find the corresponding textures.
To approach this you can use the Ozonex editor to bump your map version. This creates a new folder with the correct version, and you can use the GPG editor to set the corresponding paths. When uploading to the vault the name of the folder of the map matches its map version and therefore no longer needs adjusting. The path remains the same and everyone can load in the custom water textures.
With Supreme Commander we're in a unique position in which we can not only toy around with graphical assets, we can also see how these assets are used in the rendering pipeline of the game. The (HLSL) shaders can be found at:
To strengthen our understanding of this article it is nice to see how the assets are used in the rendering pipeline. For this article, the following bit of code inside the terrain.fx file is particularly interesting.
// as defined in terrain.fx // apply the water color float3 ApplyWaterColor( float depth, float3 inColor) { #ifdef DIRECT3D10 float4 wcolor = tex2D(WaterRampSampler, float2(depth,0)); #else float4 wcolor = tex1D(WaterRampSampler, depth); #endif return lerp( inColor.xyz, wcolor.xyz, wcolor.w ); }
The shader code shows us that we are only interested in the first row of pixels, using the depth argument to determine what pixel we should use. The depth value is clamped between 0.0 (surface or higher) and 1.0 (abyss or lower). We use the alpha channel wcolor.w to interpolate between the input and the color retrieved from the ramp. The input is in this case a color too: the color of a fully shaded bit of terrain.
The code shown is part of the shader that renders the terrain - the water itself isn't changed. The water is influenced indirectly by the water ramp through refraction, causing the water itself to change color.
Terrain with black and red stripes on it
The editor or the game cannot find your water ramp and therefore uses the default texture to make sure at least some texture could be loaded and shown. This default texture has no transparency and therefore the terrain, even the bits and pieces above water, completely disappear in the interpolation.
One cause is that the textures that you unpacked are at the wrong location. Make sure that the paths are: Good: /textures/engine/waterramp.dds Bad: /gamedata/textures/engine/waterramp.dds
Another cause when you use custom textures is that the map version got bumped but you didn't update the path accordingly. As an example, when uploading to the vault the folder name is adjusted if it doesn't match the map version accordingly.
If you've used this resource for one of your maps feel free to make a post below: I love to know about it!
Waves add in a feeling of the environment being alive. It is visible on all default maps that have water of some kind and on custom maps when people know how to generate these. This article is trying to assist the community on the latter.
A bunch of waves on the shores of the map Mellow Shallows
On the 30th of September, 2020 the Ozonex editors doesn't support generating waves. On the contrary, the GPG editor has a procedure in place that allows you to generate waves on maps. If this is no longer the case when you read this - do notify me and I'll remove this paragraph .
Navigate to the water layer (F9). In the toolbar of the editor you'll find three little buttons named 'Edit Water Properties', 'Water brush' and 'Water waves'. Choose the latter. This will change the tool window into the Waves window.
Highlighting the actions described earlier in the GPG editor
The new tool window is basic in its nature: you select a wave, choose a depth for them to be generated on and hit generate. Waves will be generated in such a way that they orient to the shore. Slowly but surely the waves will start to spawn. It can take a while for the waves to be visible - some of them have a long animation time including a fade in time.
There isn't a lot of creative freedom in this feature. You can manually select waves but you cannot transform or rotate them. You can delete them. You can delete all the waves by clicking on the reset button.
Generally you want to use multiple types of waves and foam. The longer the animation of the wave the further away from the shore you'd like to generate them. Watch out for waves directly intersecting the terrain - this will create hard lines between the wave and the terrain and it generally looks bad. If this happens, generate the waves at a deeper shore depth. Generating the same type of waves multiple times is not uncommon and can be used to increase the density of the waves.
Personally I like the 'Incomming', 'Incomming2', 'Foam' and the 'Long slow break' waves. I toy around with them on different shore depths, generating one after the other. It is vital to both check how it looks on beaches as checking how it looks near cliffs or reefs of any kind.
A normal map is a graphical term used to describe surface texture. They are used throughout games to create a sense of detail on entities. The geometry of an entity is generally limited - geometry is expensive to process. A clear example of this is the (at times: extensive) usage of decals that function as normal maps on various maps.
normal map
One of the examples in the introduction article on decals that shows a terrain with and without decals that function as normal maps
A more general introduction of normal maps is that of a flat plane that represents a brick wall. The joints between the bricks are too detailed to represent in the geometry and therefore we fake this feeling of detail with normal maps.
An example from LearnOpenGL that clearly shows the increase in detail
Today, in the (more) modern age, geometry is no longer a limiting factor given that tessalation exists. On top of that, normal maps are replaced with PBR maps - which is topic that needs an article or 10 on its own.
In Supreme Commander there are two types of normal maps used throughout the game:
The typical purple normal map commonly used on units and as a strata normal map
purple normal map
A more uncommon green normal map used for decals to add in detail into the terrain
green normal map
The green normal map is a different format that is more friendly to compression.
We have four channels: R, G, B and A. The Red channel represents the alpha channel in the new format. The Green and Alpha channels represent the normal map and the Blue channel can be discarded due to a math trick: it can be re-computed in the shader dynamically - shaving off valuable storage that the texture will take on disk.
For this article I assume that you have a purple normal map that you want to turn into a green normal map. For the sake of this guide we'll use the following normal map:
The purple normal map that we'll use throughout this article. It represents a map-wide normal map for the map Mellow Shallows
Channels
New channel
Copy
Invert (CTRL + I)
Layers
Color > Components > Decompose > RGB
Blue
Color > Linear Invert
Color > Levels > 0-25/50
Color > Components > Compose > RGBA
Color > Curves > Channel Blue > Turn it to zero
The result of this procedure should be similar to:
An example output of the full procedure
As mentioned before - the red channel is the alpha channel. Hence - if you're seeing no red on your texture then the normal map will be hardly visible. You can tune the red channel to make it more visible, as an example we increase the contrast of the red channel significantly:
An example of tuning the red channel
Store the file in the .dds format. In Photoshop make sure to save it as BC3 with interpolated alpha or in Gimp as DXT5. They are the same format but with a different name.
.dds
BC3 with interpolated alpha
DXT5
Balthazar made a video about an alternative transformation that produces better results. You can view his video at:
Happy to. The following code is the shader code that processes the green normal map for rendering.
// as part of effects/terrain.fx float4 DecalsNormalsPS( VS_OUTPUT inV, uniform bool alphablend ) : COLOR { // read textures float4 decalMask = tex2Dproj( DecalMaskSampler, inV.mTexDecal ); float4 decalRaw = tex2Dproj( DecalNormalSampler, inV.mTexDecal ); float3 decalNormal; // compute x/z and recompute the y axis decalNormal.xz = decalRaw.ag * 2 - 1; decalNormal.y = sqrt(1 - dot(decalNormal.xz,decalNormal.xz)); // rotate the decalnormal by the decal matrix to get the decal into world space // from tangent space decalNormal = mul( TangentMatrix, decalNormal); decalNormal = normalize(decalNormal); // our blend mask is stored in the r channel of the decal float blendFactor = decalRaw.r; // get decal normal back into 0..1 range and output decalNormal = (decalNormal * 0.5) + 0.5; return float4( decalNormal.xzy, blendFactor * decalMask.w * DecalAlpha); }
There are two relevant texture look-ups:
decalMask
decalRaw
We base-line the x / z values from the raw texture . Any normal is normalized which means that the length of the vector (a normal represents a vector) is normalized too. We can use this principle to compute the y element - since the length (sqrt(x*x + y*y + z*z)) must equal to 1.
x
z
y
sqrt(x*x + y*y + z*z)
This is why we can remove the blue channel as we only need the alpha and the green channel to represent the full texture. In turn, the blue channel can be more easily compressed by compression software, such as Peazip. And that is exactly what happens as the .scd files in the data folder of the game are essentially .zip files with a different extension.
.scd
.zip
Last but not least we use the red channel of the raw texture as part of the computation of the alpha channel. The alpha channel represents transparency - that is how we can stack multiple normal decals on top of one another. They are all rendered on top of one another but due to this transparency a normal decal that is underneath can still be visible.
We can summarize that for the green normal map its channels are used as:
The blue channel represents the Y-direction of the normal. In Supreme Commander the Y-axis is the up-axis - when you move a unit in the Y-direction it moves up into the air.
By using the Y-axis as our alpha channel we are essentially saying: we want the bits that point upwards to be visible. When we invert it we are saying: we want all the bits but those that point upwards to be visible. Via tuning we can make those bits more or less visible - as we did in this guide.
An advantage is that the size of your texture will be smaller on disk after compression. A map (or mod) is for example compressed on the server - when a channel is completely uniform then it will result in a lower total file size and therefore less bandwidth for the server.
A disadvantage is that any other (normal) decal that is below your normal will be non-existent. When you are making a map-wide decal than this may be intended - but for a typical decal this is not recommended.
And another major disadvantage is that you completely throw away the normal textures used in the strata layers. As this normal will override all of them with - at times - nothing in it! This is a big issue as you are essentially throwing away detail.
For more information on why the terrain uses a different type of normal map:
For more information about the DDS format:
A well written guide of how normal maps are used in another: Smash 4!
With thanks to @svenni_badbwoi for the Gimp procedure and to @Balthazar for various help along the way.
At the moment of writing the Ozonex editor doesn't support weather markers. You'll need the GPG editor to get this all to work.
Weather generators are rare, if not at all, used by maps in the vault. A lot of the original maps were supposed to use them but the code to generate the weather is all commented out. In turn, maps generally have no weather at all.
Weather on the map Rainmakers Survival
Generating weather is fairly easy but you need to know the exact steps. The GPG editor allows the creation of the proper markers. Creating and customizing the weather involves three steps: placing the proper markers in the GPG editor, editing the script file of the map and then editing those markers inside the save file through a text editor.
Open up your map and open up the marker tools (F6). From there on navigate completely to the right and at the end you'll find the markers:
Place one of both of them in the center of the map. Then save the map and close the GPG editor - this prevents you from accidentally overriding the next step. You can have multiple generators, but for the sake of the article, I'll assume that you only have one.
You can view and edit the properties of a marker inside the editor. Select a marker and extent the 'Marker Editor' window vertically. This will reveal all the properties of, for example, a Weather Definition marker.
The weather can not be rendered and inspected inside the editor. You'll need to open up the map in Forged Alliance in order to inspect it. Constantly copying your map from the editor folder to the game folder is a bit of a pickle - therefore we use a text editor to edit the properties. This allows you to iterate more quickly when you restart your map to inspect the results.
Open up the _script.lua file from your map in your favorite text editor. A typical script file from a non-adaptive map looks like this:
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua') local ScenarioFramework = import('/lua/ScenarioFramework.lua') function OnPopulate() ScenarioUtils.InitializeArmies() -- optional, only if applicable ScenarioFramework.SetPlayableArea('AREA_1' , false) end function OnStart(scenario) end
We want to add in the weather thread so that clouds are slowly generated over time. Change it to:
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua') local ScenarioFramework = import('/lua/ScenarioFramework.lua') -- for weather generation local Weather = import('/lua/weather.lua') function OnPopulate() ScenarioUtils.InitializeArmies() -- optional, only if applicable ScenarioFramework.SetPlayableArea('AREA_1' , false) end function OnStart(scenario) -- for weather generation Weather.CreateWeather() end
With the current weather definition and generator clouds should already be generating. Start the game, disable fog of war and make sure that it is. Then it is time to start tweaking!
If you have no vision over a weather generator marker then you will not see the clouds that are being generated.
Open up the _save.lua file from your map in your favorite text editor. Any editor will suffice, as long as it has a search function.
Search the file (CTRL + F) for 'Weather Definition'. You'll find in the markers chain a marker that looks like the following:
['Weather Definition 00'] = { ['WeatherType03Chance'] = FLOAT( 0.300000 ), ['color'] = STRING( 'FF808000' ), ['WeatherType01'] = STRING( 'SnowClouds' ), ['WeatherType02'] = STRING( 'WhiteThickClouds' ), ['WeatherType04'] = STRING( 'None' ), ['WeatherDriftDirection'] = VECTOR3( 1, 0, 0 ), ['WeatherType01Chance'] = FLOAT( 0.300000 ), ['WeatherType03'] = STRING( 'WhitePatchyClouds' ), ['WeatherType04Chance'] = FLOAT( 0.100000 ), ['MapStyle'] = STRING( 'Tundra' ), ['WeatherType02Chance'] = FLOAT( 0.300000 ), ['hint'] = BOOLEAN( true ), ['type'] = STRING( 'Weather Definition' ), ['prop'] = STRING( '/env/common/props/markers/M_Defensive_prop.bp' ), ['orientation'] = VECTOR3( 0, -0, 0 ), ['position'] = VECTOR3( 522.5, 68.8418, 541.5 ), },
These values are scrambled - they can appear in any order. The important bits are:
All values are case sensitive. As an example, it is 'Dsert' and not 'desert'.
Values that are not used by the code but by the editor:
Each theme has its own list of weather that can share names but look different. Therefore choosing the right map style is important. We can find all the available weather as comments in one of the lua files of the base game:
Map Style Types: Desert Evergreen Geothermal Lava RedRock Tropical Tundra Style Weather Types: Desert LightStratus - Evergreen CumulusClouds - StormClouds - RainClouds - WARNING, only use these a ForceType on a weather generator, max 2 per map Geothermal Lava RedRock LightStratus - Tropical LightStratus - Tundra WhitePatchyClouds - SnowClouds - WARNING, only use these a ForceType on a weather generator, max 2 per map All Styles: Notes: ( Cirrus style cloud emitters, should be used on a ForceType Weather Generator, placed ) ( in the center of a map. Take note that the these are sized specific for map scale ) CirrusSparse256 - CirrusMedium256 - CirrusHeavy256 - CirrusSparse512 - CirrusMedium512 - CirrusHeavy512 - CirrusSparse1024 - CirrusMedium1024 - CirrusHeavy1024 - CirrusSparse4096 - CirrusMedium4096 - CirrusHeavy4096 -
This defines all the weather that is available. The RainClouds and SnowClouds generate rain and snow respectively - these should be used sparsely. An unlisted entry is 'None', which indicates that the no weather may be generated at all.
Search the file (CTRL + F) for 'Weather Generator'. You'll find in the markers chain a marker that looks like the following:
['Weather Generator 00'] = { ['cloudCountRange'] = FLOAT( 0.000000 ), ['color'] = STRING( 'FF808000' ), ['ForceType'] = STRING( 'None' ), ['cloudHeightRange'] = FLOAT( 15.000000 ), ['cloudSpread'] = FLOAT( 150.000000 ), ['spawnChance'] = FLOAT( 1.000000 ), ['cloudEmitterScaleRange'] = FLOAT( 0.000000 ), ['cloudEmitterScale'] = FLOAT( 1.000000 ), ['cloudCount'] = FLOAT( 10.000000 ), ['cloudHeight'] = FLOAT( 180.000000 ), ['hint'] = BOOLEAN( true ), ['type'] = STRING( 'Weather Generator' ), ['prop'] = STRING( '/env/common/props/markers/M_Defensive_prop.bp' ), ['orientation'] = VECTOR3( 0, -0, 0 ), ['position'] = VECTOR3( 518.5, 68.6699, 542.5 ), },
As an example on the range variables: if the absolute value is 90 and the range is 15 then the final value is randomly chosen from the range [75,105].
All values are case sensitive. As an example, it is 'None' and not 'none'.
It is always good to dive into the code and discover how values are used in computations. This will bring in more perspective as to what is possible and leaves out speculation on what you feel it is doing.
Let's start off with reading out the markers - turning the concrete data into a more abstract form that allows us to construct the weather.
function GetWeatherMarkerData(MapScale) local markers = ScenarioUtils.GetMarkers() local WeatherDefinition = {} local ClusterDataList = {} local defaultcloudclusterSpread = math.floor(((MapScale[1] + MapScale[2]) * 0.5) * 0.15) // Make a list of all the markers in the scenario that are of the markerType if markers then for k, v in markers do // Read in weather cluster positions and data if v.type == 'Weather Generator' then table.insert( ClusterDataList, { clusterSpread = v.cloudSpread or defaultcloudclusterSpread, cloudCount = v.cloudCount or 10, cloudCountRange = v.cloudCountRange or 0, cloudHeight = v.cloudHeight or 180, cloudHeightRange = v.cloudHeightRange or 10, position = v.position, emitterScale = v.cloudEmitterScale or 1, emitterScaleRange = v.cloudEmitterScaleRange or 0, forceType = v.ForceType or "None", spawnChance = v.spawnChance or 1, } ) // Read in weather definition elseif v.type == 'Weather Definition' then if table.getn( WeatherDefinition ) > 0 then LOG('WARNING: Weather, multiple weather definitions found. Last read Weather definition will override any previous ones.') end WeatherDefinition = { MapStyle = v.MapStyle or "None", WeatherTypes = { { Type = v.WeatherType01 or "None", Chance = v.WeatherType01Chance or 0.25, }, { Type = v.WeatherType02 or "None", Chance = v.WeatherType02Chance or 0.25, }, { Type = v.WeatherType03 or "None", Chance = v.WeatherType03Chance or 0.25, }, { Type = v.WeatherType04 or "None", Chance = v.WeatherType04Chance or 0.25, }, }, Direction = v.WeatherDriftDirection or {0,0,0}, } end end end return WeatherDefinition,ClusterDataList end
This shows us what data is relevant and transformed into another format. We can also see that there are a lot of sane defaults provided. And last but certainly not least: we can see what the new names for the data is that is used throughout the code.
function CreateWeatherThread() local MapScale = ScenarioInfo.size // x,z map scaling local WeatherDefinition, ClusterData = GetWeatherMarkerData(MapScale) local MapStyle = WeatherDefinition.MapStyle local WeatherEffectsType = GetRandomWeatherEffectType( WeatherDefinition ) //WeatherEffectsType = 'StormClouds' if WeatherEffectsType == 'None' then return end local numClusters = table.getn( ClusterData ) if not WeatherDefinition.WeatherTypes and numClusters then LOG(' WARNING: Weather, no [Weather Definition] marker placed, with [Weather Generator] markers placed in map, aborting weather generation') return end // If we have any clusters, then generate cluster list if numClusters != 0 then local notfoundMapStyle = true for k, v in MapStyleList do if MapStyle == v then SpawnWeatherAtClusterList( ClusterData, MapStyle, WeatherEffectsType ) notfoundMapStyle = false end end if notfoundMapStyle and (MapStyle != 'None') then LOG(' WARNING: Weather Map style [' .. MapStyle .. '] not defined. Define this as one of the Map Style Definitions. ' .. repr(MapStyleList)) end end end
For each cluster, which is a generator, the data that has been transformed before is being used to call the function to start generating clouds on top of those generators.
The cloud types are directly determined from the given map style that is defined in the weather definition marker - only the cloud types form that style are available because that is where the code is searching for to find a matching type.
function SpawnWeatherAtClusterList( ClusterData, MapStyle, EffectType ) local numClusters = table.getn( ClusterData ) local WeatherEffects = MapWeatherList[MapStyle][EffectType] // Exit out early, if for some reason, we have no effects defined for this if (WeatherEffects == nil) or (WeatherEffects != nil and (table.getn(WeatherEffects) == 0)) then return end // Parse through cluster position and datal for i = 1, numClusters do // Determine whether current cluster should spawn or not if ClusterData[i].spawnChance < 1 then local pick if util.GetRandomFloat( 0, 1 ) > ClusterData[i].spawnChance then LOG( 'Cluster ' .. i .. ' No clouds generated ' ) continue end end local clusterSpreadHalfSize = ClusterData[i].clusterSpread * 0.5 local numCloudsPerCluster = nil if ClusterData[i].cloudCountRange != 0 then numCloudsPerCluster = util.GetRandomInt(ClusterData[i].cloudCount - ClusterData[i].cloudCountRange / 2,ClusterData[i].cloudCount + ClusterData[i].cloudCountRange / 2) else numCloudsPerCluster = ClusterData[i].cloudCount end local clusterEffectMaxScale = ClusterData[i].emitterScale + ClusterData[i].emitterScaleRange local clusterEffectMinScale = ClusterData[i].emitterScale - ClusterData[i].emitterScaleRange // Calculate weather cluster entity positional range local LeftX = ClusterData[i].position[1] - clusterSpreadHalfSize local TopZ = ClusterData[i].position[3] - clusterSpreadHalfSize local RightX = ClusterData[i].position[1] + clusterSpreadHalfSize local BottomZ = ClusterData[i].position[3] + clusterSpreadHalfSize // Get base height and height range local BaseHeight = ClusterData[i].position[2] + ClusterData[i].cloudHeight local HeightOffset = ClusterData[i].cloudHeightRange // Choose weather cluster effects local clusterWeatherEffects = WeatherEffects local numEffects = table.getn(WeatherEffects) if ClusterData[i].forceType != "None" then clusterWeatherEffects = MapWeatherList[MapStyle][ClusterData[i].forceType] LOG( 'Force Effect Type: ', ClusterData[i].forceType ) numEffects = table.getn(clusterWeatherEffects) end // Generate Clouds for our cluster for j = 0, numCloudsPerCluster do local cloud = Entity() local x = util.GetRandomInt( LeftX, RightX ) local y = BaseHeight + util.GetRandomInt(-HeightOffset,HeightOffset) local z = util.GetRandomInt( TopZ, BottomZ ) Warp( cloud, Vector(x,y,z) ) local EmitterGroupSeed = util.GetRandomInt(1,numEffects) local numEmitters = table.getn(clusterWeatherEffects[EmitterGroupSeed]) local effects = clusterWeatherEffects[EmitterGroupSeed] for k, v in clusterWeatherEffects[EmitterGroupSeed] do CreateEmitterAtBone(cloud,-2,-1,v):ScaleEmitter(util.GetRandomFloat( clusterEffectMaxScale, clusterEffectMinScale )) end end end end
This is where the generators are turned into emitters. All the data is transformed (again) into the proper format that dictates how large the emitter can be, how much it should spawn and at what height it should spawn.
The type of a specific generator can be overridden when you force its type - this is determined when the type of emitter is chosen. Even for the forced type it only searches through the weather available in the selected map style for the forced type.
The emitters are attached to a (dummy) entity. If a player has no vision over this entity then the attached emitters do not spawn.
Make sure that:
INFO: Weather Definition { INFO: Direction={ 15, -30, 0, type="VECTOR3" }, INFO: MapStyle="Tundra", INFO: WeatherTypes={ INFO: { Chance=0.30000001192093, Type="WhitePatchyClouds" }, INFO: { Chance=0.30000001192093, Type="WhitePatchyClouds" }, INFO: { Chance=0.30000001192093, Type="None" }, INFO: { Chance=0.10000000149012, Type="None" } INFO: } INFO: } INFO: Weather Effect Type: \000WhitePatchyClouds
Survival maps or unbalanced maps are perfect examples. Either the author of the map or a vault moderator made it unranked for some reason - I suspect it is the author as vault moderators typically just hide the map.
Your title reads as everyone in the community is in consensus with your tips. Yet, there is another topic (https://forum.faforever.com/topic/180/understanding-team-maps) that clearly shows that this is not the case.
I think the title would be more appropriate as 'Moses the Red's vision on map design' to clearly indicate that this is your opinion.
Besides that - I am happy that you wrote it out. All this can do is spark new discussions either on the forums or through other channels and that is what matters most. Discussions allows one to place his / her understanding or vision of the topic at hand in a new perspective.
This article represents an in-depth discussion about markers used by the AI. We'll dive into what markers there are and how they are most properly applied.
Text editors such as:
The GPG editor is vastly outmatched feature wise on this topic. I recommend using the Ozonex editor for this topic and the article will only discuss how to approach this inside the Ozonex editor.
Personally I use Visual Studio Code as the text editor in this article. The exact same procedure applies for Notepad.
There are numerous markers available for various usages. The most common markers are the mass extractor, hydrocarbon and the blank markers used for spawn locations or objectives. More uncommon markers are the AI markers such as 'Naval Link', 'Rally Point' or a pathing marker such as 'Amphibous Path Marker'. These are markers that have no meaning to players, instead they have significant meaning to the various AI systems that players use to fight against and learn with.
Throughout this article we will dive into the AI markers. We'll discuss what markers mean to various AI's, how they could be placed in accordance and we'll dive into pathing markers and common misconceptions about them.
This article is written in collaboration with some of the developers of the AI community that surrounds Supreme Commander. In specific:
A rally point marker gives the AI an indication where it can send its units after construction when its not ready to be sent out yet. An example situation is when a platoon is being constructed. Until the platoon has been constructed, the units wait at the rally point marker.
This marker is used by:
There are two types of rally point markers:
An AI will use the closest rally point marker to a factory as its rally point. A base can have multiple rally points given that it has multiple factories. Both land, amphibious and air units can rally to a land based rally point. Naval factories will look for the nearest naval rally point.
A few rally point markers on the map Withered Battle
Question: How are Rally Point markers used exactly? The current text (about platoons) is an assumption from observed behavior. Question: Can a base have multiple functional rally point markers? Question: Do air units have a rally point marker? Question: Can Amphibious units use both rally point markers?
An expansion area marker provides the AI with an intuition as to where it can expand to. The majority of the AI's will construct a fully-fledged base or a support base at the location, depending whether or not it is a large expansion area. Such an area may include factories, generators, shields and defenses where applicable.
It does not require mass extractors near it, but mass extractors near an expansion area marker may be preferred over ones that are not. By telling the AI to build a base at the location extractors can be automatically more secured from the perspective of a player.
Besides that it can function as a forward operation base to apply pressure on the enemy. The terrain surrounding an expansion area should be flat and large enough to support a range of buildings, including factories and shields.
Whether or not an expansion is a separately functioning base depends on its distance to the spawn location and other expansions. An expansion should be about 150 - 250 units away from other expansions in order for it to be a standalone base, depending on the AI at hand. Expansions that are close to each other may share their pool of units including engineers, causing odd interactions.
A few expansion markers on the map Open Palms
Question: Is there a difference between a large expansion area and an expansion area marker? Question: Does an expansion area require extractors? Question: Can expansion area's also construct naval factories if it is close to the water? Question: Is there a minimal distance between expansions, or between the spawn and an expansion for it to be effective?
A naval area marker provides the AI with an intuition as to where it can build a full-fledged naval base. This includes naval factories, naval and anti air defenses and a sonar.
It requires a certain depth such that factories can be safely build and navy units can safely maneuver around the factories. Typically you want the marker to about 50 units off the shore such that a decent naval base can be constructed.
A naval base is much like an expansion but then with a focus on water. Units such as engineers may be shared with other expansions, depending on the direct (Cartesian) distance between the two. If such an interaction would be odd then place t the naval area marker at a sufficient distance from any other expansion area, including the spawn location.
A naval area marker that is far away from the spawning location to prevent odd interactions
A naval area marker that is close to the spawning location units can freely move up and down the beach and therefore interactions make sense
Question: Does it indeed include a sonar? Question: Can other structures, such as generators, be constructed on land that is nearby? Question: I recall that around the spawn location an AI make may naval factories, does this also hold for expansion area's near water?
A protected experimental construction marker is quite literally what it says it is: a place where the AI can build an experimental in a relative safe manner.
An protected experimental construction marker at the back of the base in Field of Isis
A naval link marker is one of the markers that didn't have a meaning until one was given to it. The majority of the AI's will not take this marker into consideration.
It provides information on where a naval army can do bombardment on some target that is on land. The marker is expected near shores that are applicable for bombardment, significantly closer to the shore than naval pathing markers would be.
A bunch of naval link markers that are significantly more close to the shore than naval pathing markers on Mellow Shallows
The defense point describes where AI's can build support bases that do not have factories. At least defenses will be built and other structures such as air pads and shields depend upon the AI at hand.
There are two types of defensive point markers:
The marker is particularly useful to protect entrances, allow the AI to utilize choke points more effectively or to allow an expansion to be more fortified than it would be on its own.
In the case of LOUD a base constructed at a defensive marker is considered to be a standalone base, given that it has sufficient distance to other expansions.
An expansion fortified with minor gun positions on the Varga Pass
Question: Can these also spawn other structures, such as generators, shields, or even factories? Question: Is there a minimal distance between a defensive points and the spawn location or expansions for it to be effective?
Transport markers allow for alternative drop off points. There markers are optional. Typically transports use land pathing markers as their drop off points. Transport markers are considered when land pathing markers are either too dangerous.
Transport markers are especially useful to mark positions that would be strange to include into the pathing graph, such as small islands. They can also be used to allow for more strategic dropping of units, such as behind a mass extractor somewhere.
A couple of red transport markers on the map High Noon
Question: Are these considered before the applicable pathing marker, or after? Question: Can you place these on water for amphibious drop points? Question: How about pick-up points, like the ferry function?
Island markers are used to mark islands. In practice they are used in the most rudimentary way such that they are more commonly used as a flag to indicate that transports may be important on this map.
These markers should be placed on each island once.
The island marker being used as a flag on Snoey Triangle
Question: These are barely used by the AI, correct?
Combat zone markers are used to indicate where we as a developer expect confrontations. This marker is poorly named as its main function is to be a target to which the AI can send out scouts. You can think of them as positions that need to be checked on a regular basis.
The marker should be placed at the center of paths from one spawn location to another or at remote hiding spots that are not intuitive for the AI but players may use.
A series of combat zones on the map Williamsons Bridge
Question: Are these also used to send out units?
For more information on how pathing markers are used:
If you've used this resource for one of your maps feel free to make a post below: I'd love to know about it!__
On the 30th of September, 2020 the Ozonex editors renders water differently than in the game. Thus it is not representative to what you would see while playing. On the contrary, the GPG editor utilizes the exact same procedures as the game does and is therefore representative. If the Ozonex editor correctly represents the water when you read this then do notify me and I'll remove this paragraph .
There are numerous water brushes available in Supreme Commander. The depth bias is not functional.
In the tool window you'll notice there is a combo box with three options, a pair of brushes and their according strength / size at the bottom.
Flatness depicts how rough the sea and therefore the reflections of the water are. You can use the red brush to make it less rough and the blue brush to make it more rough. By default all of the water is at its roughest.
A visual comparison with rough water in the top left and partially flattened water in the bottom right
Typically waves are generated by the wind. One can visualize that a lake is partially covered from the wind by some mountain by flattening it slightly. Generally completely flattened water looks strange - users are not used to water being completely flat because its rough on almost every map out there.
This is only a graphical effect - it does not affect the simulation.
Foam depicts how much wave crests / foam should be generated. You can use the blue brush to decrease the amount of foam and the red brush to increase the amount of foam. By default, all of the water generates foam.
Water of the map Paradise, with foam in the top left and without foam in the bottom right
Whether or not foam is generated depends on your water maps. The alpha channel of the water map determines whether foam should be generated. For more information about this see the article on water normal maps:
This is not functional. Technically, it is not being used in the shaders that render every single frame. One can only imagine what it was supposed to be used for. You can change the depth manually by changing the heightmap of the terrain directly.
%installation-folder%/gamedata/effects.scd/
To strengthen our understanding of the article it is nice to see how the assets are used in the rendering pipeline. For this article, the following bits of code inside the water2.fx file are particularly interesting.
// file: water2.fx float4 HighFidelityPS(...) : COLOR { // (...) float3 up = float3(0,1,0); N = lerp(up, N, waterTexture.r); // (...) }
The value inside waterTexture.r is the value we're painting with the flatness brush described earlier.
We need the red brush (the one that deducts) to decrease the roughness of the water: by default the value is 1 and through linear interpolation we therefore completely use the computed normal N at that pixel. Because every pixel will have a slightly different normal N, the water will appear rough.
When we decrease this value we'll slowly graduate towards the up vector that is uniform over the surface. Surrounding water will move towards the same up vector and therefore there is little to no difference between the normals of the neighboring pixels. In turn the water appears less rough or even completely flat.
// file: water2.fx float4 HighFidelityPS(...) : COLOR { // (...) // calculate the normal we will be using for the water surface float4 W0 = tex2D( NormalSampler0, inV.mLayer0 ); float4 W1 = tex2D( NormalSampler1, inV.mLayer1 ); float4 W2 = tex2D( NormalSampler2, inV.mLayer2 ); float4 W3 = tex2D( NormalSampler3, inV.mLayer3 ); float4 sum = W0 + W1 + W2 + W3; float waveCrest = saturate( sum.a - waveCrestThreshold ); // (...) // Lerp in a wave crest refractedPixels.xyz = lerp( refractedPixels.xyz, waveCrestColor, ( 1 - waterTexture.a ) * waveCrest); // (...) }
The value inside waterTexture.a is the value we're painting with the foam brush described earlier. The value inside waveCrest is computed according to the alpha channel which is stored in sum.a of the water maps. By default, the waveCrestThreshold is 1.0: only water that has a higher alpha channel than 1.0 will have foam.
We need the blue brush (the one that increases) to decrease the foam on the water: by default the value is 0 and through the computation done (1 - waterTexture.a) the resulting value is 1. By default all the water will have foam assuming that the water normal maps have support for it. The waveCrest value will be different on all pixels and ranging between 0.0 and 1.0. In turn this generates white shapes on top of the water that can be interpreted as foam with the right textures.
Environment map An environment map is a look-up table for the environment commonly used for reflections. It tries to answer the question: 'If I look into the mirror, what is it that I see?'. They are typically generated beforehand and are therefore static. Completely generating these from scratch for every frame is extremely expensive and would stall any game to a hold. Only recently, with ray tracing and de-noising technologies, are we able to partially compute these reflections in real time.
Environment maps are also commonly named cube maps or sky boxes. The former because each part of an environment map represents a side of a cube. That cube is always rendered last - behind everything else. The latter is because typically it is a sky that is being represented.
This is quite the information and I encourage you to look at the following article:
An environment map from the OpenGL tutorial series on learnopengl.com
Water in Supreme Commander uses environment maps extensively to allow the reflections of the water to match the environment. Unit reflections are also taken into account - these are generated dynamically. Both of these effects can be especially seen when you flatten the water.
A piece of water that has been flattened - clearly showing the environment map used for reflections
In the tool window we can see that the default environment map is:
/textures/engine/waterCubemap.dds
When we load it in we can argue that it is cloudy on almost every single custom map out there. The various sides of the environment map are available in the various different layers.
The default environment map opened in Gimp
The game provides a bunch of environment maps by default. These are used throughout the default skirmish and campaign maps. Assuming that you have extracted the textures properly previously, you can find them at:
%InstallationFolder%/textures/environment/
Inside you'll find a bunch of environment maps:
There is no easy way to view these through the Windows Explorer. I'll show a few of them as an example.
EnvCube_Desert01a,dds
EnvCube_RedRocks08a.dds
EnvCube_Tundra03a.dds
The images appear to be of low quality but remember - water doesn't reflect them equally because of the noisy surface. In practice it is more of a look-up map for coloring the water than accurately reflecting the environment.
Select the Water layer (F9) and then click on 'Water Properties' in the toolbar of the editor. The tool window will respond and change into a 'Water Properties' window. For this article we're interested in the 'Texure Maps' and particularly in the 'Environment' texture.
Assuming that you have extracted the textures correctly previously, click on the '(...)' button next to the environment texture and navigate towards:
Choose any of the environment maps that are available and start experimenting with them.
A visual comparison of the changes to the surface of the water. Especially visible when the water is flattened
You can store environment maps inside your map folder. For stratum textures, decal textures and props there is a specific location where these should be stored. For water there is no hierarchy that you need to use in order for the game to find the files. It is good practice to store them inside the 'env' folder that the other textures require in order to function.
If you know more on how to format the environment maps such that Supreme Commander can interpret it properly, feel free to contact me and I'll update this article.
When you upload the map to the vault the name of the folder of your map can be changed when it doesn't represent the map version correctly. The path to your custom water textures is not adjusted accordingly, in turn the game cannot find the corresponding textures.
To approach this you can use the Ozonex editor to bump your map version to create a new folder with the correct version. Then you can use the GPG editor to set the corresponding paths to the new folder. When uploading to the vault the name of the folder of the map matches its map version and therefore no longer needs adjusting. The path remains correct and everyone can load in the custom water textures.
Water with and without environment reflections
The editor or the game cannot find your environment map and therefore uses the default texture to make sure at least some texture can be loaded and shown. The default texture doesn't have the correct layout and therefore there are generally no reflections.
One cause is that the textures that you unpacked are at the wrong location. Make sure that the paths are: Good: /textures/environment/EnvCube_Desert02a.dds Bad: /gamedata/textures/environment/EnvCube_Desert02a.dds
For more information on environment maps:
For more information on how one frame in Supreme Commander is rendered:
Water that is pixelated has been a common discussion between map developers in various Discords, fora and other chat applications. As an example:
This is a bug within the editor: some setting is off and the high fidelity version of the water isn't generated properly in turn. This happens both in the editor and, because it uses the same code to generate the water, in game too.
A clear example is the map 'Open Waters':
The top left corner has the smooth, correct version of the water. Where as the bottom right corner has the incorrect, pixelated water.
Typically this can be fixed by just saving the map again. There are cases when this doesn't work however. In those cases you have to change some setting of the water, such as notch up the water slightly, just to notch it back down to the value it was before. I assume some state is corrupted, disabling the generation of high fidelity water. By changing the settings all of the state is replaced and then high fidelity water can be generated both in the editor and in game.
You can adjust the height water property in the GPG editor by enabling the water layer, edit the water properties and then change the surface height just to change it back again.
Considering the engine is from 2007 this is likely intended behavior instead of a bug. Which makes it impossible to address directly, we can only circumvent it. The behavior only applies in game - the old GPG editor and the new Ozonex editor do not have this issue.
Lets start with an example:
If you look closely you'll notice that the top part of the island is pixelated where as the bottom part is sharp. If you zoom out further the rest of the island is pixelated too. If you zoom in further all of the islands shores are sharp again.
I suspect this is an optimization from the engine- graphic cards weren't as good in 2007 as they are now. Rendering high fidelity water at such heights is, generally, aesthetically the same as rendering a lower quality version of the water. One can describe it is as a Level of Detail (LOD) for the water.
The change of water is visible because of the surface color of the water in combination with the color lerp. The water at the shore has a constant color applied to it. Because bits and pieces of water dissapear when you zoom out, the color at those pixels jump slightly. This causes the pixelation to be (clearly) visible. As an example:
I've increased the contrast of the shores to clearly show that the water is still being changed, but that the change is less visible. the change is aesthetically the same when the water has no surface color at all near the shore.
The color lerp stands for 'Color Linear Interpolation' which takes the depth as an argument of its function. The min (no depth, at the shore) and max (deepest point of the water) are then used to interpolate the surface color which is then added to the color of the water. I'm not going in depth any further because that is beyond the point of this article :).
You can adjust the color lerp min water property in the GPG editor by enabling the water layer, edit the water properties and then change the color lerp min property. The lower the properly the less visible the change will be.
The problem with regard to the water becoming pixelated when you zoom out has been investigated previously. There are a few console commands that can be run in the console to prevent the problem from happening. As an example:
I'm not speaking for the team - this emerged from a discussion between me and @archsimkat. I read somewhere that the balance team disappeared from the old forums because a lot of discussions got derailed. I don't think that argument holds on this forum anymore given Brutus's response.
And given how valuable those discussions can be to provide insights to (new) players I think they should return. Regardless whether you agree with the PR's or not. And I'm hoping someone from the balance team can join in on this discussion and tell their tale - at the moment I don't know who they are .