As you might have seen in our recent teaser, the upcoming, overhauled version of G String will feature some proper spaceship action! The player will go into battle with allies to take on enemy vessels of various sizes and perform other tasks. If you didn't see the recent teaser yet, check it out:
We have been working on this for a while already and are now confident enough to present it as a definitive part of the game. Now, let's have a closer look at what's in store:
When designing the gameplay for the space battles, we prioritized making it quick and easy to grasp, because there is neither time nor place for any kind of tutorial or lengthy in-game instructions.
The first challenge we faced was designing the spaceship controls. We decided it would be most optimal to only use the key bindings that the player already knows. That includes moving the ship via W A S D in a similar manner as in firstperson mode and using the sprint button to boost the ship's speed. Concluding this, the longitudinal (roll) axis will be locked, which also makes sense storywise: you will be seeing the Earth right beneath you the whole time and the ship's stabilizers will align you to it. Aside from this, the primary weapons can be fired with the left mouse button and an autoaim system will additionally assist you while shooting enemies.
Since the Source engine isn't capable of any kind of open worlds by default, the whole world is scaled down by a factor of one-sixteenth to allow building a larger environment. But ultimately, the player still needs to stay within a predefined playable area. We solved this issue by simply tying its requirement into the story. Should the player still leave the area, they will either die or turn back automatically - something that we still need to finalize.
Overall a sturdy and outworn look is prevalent during the space scenes to match the rest of the mod. This includes the interior model of the spaceship and the ship's UI, which flickers a little and has a noise effect.
To make the battle scenes more appropriate for gameplay, we color coded a few crucial elements. The target UI highlights targets in red, yellow and green which represent enemies, neutrals and friendlies respectively. The laser colors from turrets and spaceships match the general color schemes of their models: enemies fire blue lasers while friendlies fire orange ones.
The ship's UI is made of holograms, which are based on a custom system we have programmed on top of VGUI. Source already offers a facility to render UI in world space (DrawPanelIn3DSpace in IMatSystemSurface for those of you who know their way around the SDK), but frankly it's not too appealing to look at or to use. Our solution renders everything based on dynamic meshes or models. VGUI is still used internally to draw text to a texture atlas which can then be drawn with a dynamic mesh as well.
Cascaded Shadow Mapping
We implemented a custom solution for cascaded shadow mapping just for the space environment. While most of the mod fares better with blurred, soft shadows due to the polluted air that scatters the light, the space scenes work well with sharper shadows. CSM makes it possible to have a higher quality shadow within the interior model of the spaceship while also allowing for shadows farther away.
Our CSM renders all cascades to a depth texture atlas, using the built-in flashlight depth texture rendering code to profit from all internal engine optimizations. The common world shaders, like LightmappedGeneric and VertexLitGeneric, will then sample one of those cascades to apply the shadow. Selecting a cascade is based on modifying the UVs prior to performing the sampling like in the following example:
// Check whether the projected UVs are outside of bounds of the first cascade. // 0.0 will sample the far shadow map, 1.0 the close shadow map. float blendCascades = step(shadowMapUVs.x, 0.49) * step(0.01, shadowMapUVs.x) * step(shadowMapUVs.y, 0.99) * step(0.01, shadowMapUVs.y); // Select the cascade UVs. shadowMapUVs.xy = lerp(shadowMapUVs.xy * cascadedStepData.x + cascadedStepData.yz, shadowMapUVs.xy, blendCascades);
This makes things a lot simpler and more optimized. You only need to worry about a single texture for all shadow maps and you don't need to use branching in the shader, which could potentially lead to way more lookup instructions in the compiled shader code.
While lightmaps won't be used in space, we still implemented support for them. While applying a lightmap, you cannot tell anymore which lights have been aggregated to a specific texture color, like you can easily do when rendering vertex or pixel lights. However, this is very much necessary to render a shadow that belongs to a specific light, like the directional sun light, because you only want to mask that specific light source. A more optimal solution would be producing a mask in VRAD, which could optimally be stored in the alpha channel of the lightmap, but this is simply not possible to implement in the 2013 SDK without access to the engine code.
Instead, we are approximating the mask by calculating the light deviation from the expected ambient and light colors that were set in Hammer. If there is no deviation, the light will be fully masked, but the more the texture colors deviate, the less shadow will be applied. In the example above, you can see how the orange spotlight is still clearly visible in the shadowed area with this trick.
Since we are planning to support VR in G String, we also made the space environment compatible using an Oculus Rift. While the 2013 SDK already offers a certain support for VR by default, there were still a few special things to consider in our case.
The crosshair hologram, for example, moves with your head in VR and is aligned to the object you are currently aiming at to prevent a cross-eyed appearance. We also project the crosshair back onto the hologram aim panel sphere and align it accordingly, which feels a lot more natural than aligning it to a quad.
There are also a few neat extras to discover in VR when looking around the ship. You can see the jet engines brighten up when you accelerate the ship or the thruster effects at the sides of the ship when you turn or strafe.
If you are interested in checking out our code, you can take a look at our GitHub repository: www.github.com/Biohazard90/g-string_2013.
We are excited about finishing this mod and hope you will enjoy it when it comes out!