It’s been a busy two months for the Amper team. The start of the university year and end of summer festivities have meant we’ve had to temporarily re-target our priorities. However, this has provided an excellent opportunity for the team to put the time and care into the finer details needed for an authentic Team Fortress experience.
In this month's blog post we invited members of our team to discuss what they’ve achieved since we last dived into the development process for the Team Fortress: Source 2 project.
In addition to the continued development of the project, we’ve been working behind the scenes to rethink our approach to social media, branding, and community. We’ll have more to share on this at a later date!
Now, onto the details!
s&box recently added the ability for addons to use custom shaders. Using HLSL, we are able to extend the base Source 2 shaders to adjust how models look in-game. This lets us begin to re-implement various iconic TF2 shading features to better match its style. Currently we have two features being worked on: rim lighting and light warps. Here’s a sneak peek at our progress on this:
Rim Lighting Rim Lighting is used in TF2 to ensure that player models are always somewhat visible, even in low visibility situations, such as dark corners and tunnels. This is achieved by highlighting the very edges of the model in specific spots, allowing their iconic silhouettes to stand out against similarly colored backgrounds. We currently have a basic implementation of this, letting us achieve the same effect. Here’s an example of how Rim Lighting is implemented:
Lightwarp Lightwarp is a feature that allows adjustment of how models are lit. Source 1 used this to adjust the standard light to dark transition with a custom, 2D texture-based gradient. This effect is used in many Source 1 titles, such as Day of Defeat and TF2, which makes extensive use of this feature to make the light to dark transition harsher and create its signature style. We currently have a basic version of this, however more tweaking is needed to to more closely resemble Source 1’s implementation.
Here’s an example of what a Lightwarp texture looks like:
Here is an example using a Lightwarp to achieve a cell shaded style. This better illustrates the effect lightwarps can have on how a model is lit. This is another example of a Lightwarp texture, this time highlighting how one might achieve a more stylised visual:
Cell shade Lightwarp example:
Our goal in the long term is to replicate TF2’s animation system as closely as possible, or even upgrade it to take greater advantage of the Source 2 toolset. Unfortunately, due to some key differences between Source 1 and Source 2’s methods of setting up models and animations, a lot of manual work is needed to achieve this.
As of right now, we actually have all nine classes up and running with proper, albeit barebones, animations. Now what has to be done is the cleaning up of the playermodel files. Due to the age of TF2, the multitude of developers it has seen, and the non-1-to-1 transfer of Source 1 content to Source 2, there is a lot of mess that has made its way into TF:S2 models.
https://streamable.com/8t1u2x
The biggest hurdle right now is the IK Rule system. The system used in Source 1 was very simple, but very easy to set up and use, and could be directly applied to an animation sequence. Source 2’s IK System is far more robust, but unfortunately is not transferable and requires a bit of extra setup to get working without breaking TF2’s original animation system. As you could imagine, doing this for 3+ weapon animation sets for 4+ movement types with 9+ directional animations for 9 classes can be a bit exhausting (108 animations minimum for each class, just for foot IK!). This is especially tedious for Scout and Medic, as they have directional animations for their jump animations due to their double jump and coat respectively.
I had been ignoring these issues for the sake of getting the playermodels working for internal playtests, but in the end I aim to clean them up properly. My goal is to make it as easy as possible to understand, deconstruct, and reuse our files, as accessible modding is a HUGE reason I got into TF2 in the first place.
Side note: Although we do not plan to use them in the release version of TF Base, I will be looking into setting up non-stock weapon animations so they are easier for creators to access at launch. This includes animations for weapons such as the Huntsman, Flaregun, and the Eyelander. However, I cannot guarantee we will ship with these finished as they are low priority compared to other features and mechanics yet to be implemented.
Nothing feels more powerful to me than landing a critical rocket on a target. This is why I have taken up the task of implementing critical hits into TF:S2.
It might be surprising to learn that most of the development time for critical hits was spent on the visuals. The functional implementation was rather simple, as for the most part it is a matter of simply multiplying the damage by a factor of 3.
The real challenge was making it look right in this new engine. The Source engine had a nifty little thing called material proxies, which, among other things, also handled the critical weapon glow. They allowed the TF2 developers to set parameters in the weapon's material, in this case the $selfillum parameter.
To match the weapon glow as accurately as possible, I needed to find a way to replicate this behavior. Luckily, Source 2 has something similar called dynamic material expressions. This required me to edit all existing weapon materials to support these expressions, but after a bit of experimentation, I managed to replicate the glow effect with satisfying results.
But of course, that was not everything. Afterwards, I implemented the critical shot sounds and the particle effects surrounding the crit-boosted weapon. Then, there was just one thing left to do: bullet tracers. In TF2, hitscan weapons emit so-called particle tracers, which are thin lines that rapidly travel from your weapon barrel towards the bullet’s impact point. They give off the illusion that the bullets are actually traveling towards your target. Since critical hits in TF2 use special particle tracers that leave a glowing effect on the impact point, I felt compelled to add support for them.
Fun fact: The weapon particle actually attaches to your hands, not your weapon. This is how it works in Team Fortress 2 as well. You're welcome for never being able to unsee this.
In the latest blog post we announced that as part of creating the TF Base in Source 2, we want to stick as closely as possible to vanilla TF2. And this, of course, implies the HUD as well.
Over the course of the last few months I’ve been doing some work on recreating the base Team Fortress 2 HUD in s&box. One of the most notable differences between these two games is the how HUD systems are handled. People who have at least tried messing with the HUD in the base game may already know that TF2 uses the vgui system.
While the vgui system is good at what does, I wouldn’t consider vgui the most robust HUD system out there. In s&box however, for HUD creation we use scss (for better or for worse, depending on how you think about it). This system turns the game’s HUD into a pseudo web page with lots of elements that you can stylize like you would on a real HTML page with CSS: each HUD element has its own class, to which we assign different properties in the stylesheet file. Stylesheet files are hot loaded in s&box, which makes the process of quickly changing the file and seeing the output result incredibly smooth and simple.
Now let’s talk specifically about the TF2 HUD; it is well known that the way TF2’s UI elements were constructed is not ideal. Sometimes they overlap, overflow the container and even straight up disappear - good ol’ Source spaghetti. Since s&box uses scss instead of vgui, with a heavy focus on flexbox, aligning elements together becomes so much easier. In order to better organize the elements and make it as much not mess as possible, I have split the HUD elements into 3 main categories: vitals, weapons and objectives.
Elements in the vitals category showcasing all the information about the player’s state - Health, Ammo, Charges, Effect Meters, etc.
The weapon category contains all the custom elements that are created by the weapon itself, such as the overlay that appears when you are scoped in with the Sniper Rifle.
Objective elements contain everything related to the current gamemode state, like timers and counters. Each category has its own creation and destruction hooks that can help the developer show and hide certain HUD elements on demand.
I am trying to make all HUD elements as abstract as I possibly can, so that (with proper documentation) people can reuse/modify them according to their own needs. For example: if you want to make a gamemode that involves capturing 12 control points with the CTF flags in 12 minutes, you can focus on building the gamemode logic, not tinkering with the position of the HUD elements - it all should just automatically work.
Please note that the following topic is in heavy development and is subject to change...
I previously mentioned how the HUD in TF2 was not in a great state behind the curtain. Oh boy - don’t even get me started on the gamemode logic.
If you made or at least tried to make a map in the Team Fortress 2 version of the Hammer, you probably have noticed that sometimes configuring the gamemode for your level can be a bit chaotic. For instance, some game modes require you to put just two flag entities and two capture zones to make a CTF map. Some require you to mess with team_round_timer, tf_gamerules, and other logic entities’ I/O system to get something like A/D or 5CP done, and some game modes have their own tf_logic_* entities that presumably control the gamemode.
It’s very inconsistent and sometimes counter-intuitive, in my opinion, but you can get used to it. And so did literally everyone who made any TF2 map in the history of TF2 maps. However if you try to go a little bit deeper, you will soon find out that there’s always a certain extent on how far you can go with gamemodes.
Since we are rewriting Team Fortress 2 from scratch on a new engine I wanted to make the whole system more consistent and accessible so that people who make levels can have some sort of customizability in what they want players to do.
For now, I have decided to split gamemode related entities in two parts: gamemode entities and objective entities:
The first part defines the overall logic for the gamemode: it declares how players should spawn, what are the win conditions, what HUD elements should it have, etc. Every level must contain only one of these gamemode entities.
The other part is objective entities - things that players must interact with: control points, flags, timers, counters, etc. Each entity has its own purpose and can be reused across gamemodes.
For instance, in game modes like A/D we have a countdown timer entity (tf_logic_timer), which is used to add a time limit to the map. In something like KOTH we will have two timer entities, one per team, and both timers will be shown on the HUD. In the same sense, if you, for example, decide to make a KOTH gamemode with 4 teams instead of 2, adding those 4 other times to the system will be just a matter of adding 2 more timer entities for both new teams.
I expect this to be iterated upon once we get these tools in the hands of our Level Designers to make changes based on their feedback. Once we come down to a more or less final design, this system will be documented and prefabs for each gamemode will be made for public use.
Justyn and I spent some time porting and fixing all assets used in cp_mercenarypark, enabling them to work well with Source 2’s Physically Based shaders. The only thing we could not retain from the original assets was the foliage sway effect used in the palm trees, which required a vertex shader not present in s&box. Fortunately, we can author our own shader and implement this effect in the future.
As many of you are aware, in 2018 Valve released the ‘Supervillain Lair’ map for SteamVR Home, which used Mercenary Park assets. Justyn brought many of these assets over because they were already tuned for Source 2’s shaders, including this unused Parasol material that we thought was interesting to share.
Just as a frame of reference, the original shared its UV and material with 10+ other models in the map as an optimization to reduce draw calls through more efficient batch rendering. On the other hand, the SteamVR Home version has its own UV and it comes as a Physically based material!
It is bewildering why Valve chose to not use this asset after spending a significant amount of time polishing it up, but I guess we found a use for it…
I recently made some minor changes to Arena Well to fix up the lighting a little bit, and got it as close to TF2 as I could, focusing on environment lighting and overall saturation of the map. It’s still hard to reproduce the bloomy yellow/orange sunlight shining on the walls, but I’m sure we’ll find a way.
As I already covered the porting of Well on the previous blogpost, I’m now going to show you the new stuff I’ve been working on. We thought it would be a great idea to show off the potential of Source 2 lighting using TF2 assets by changing Well into a night time variant. Here’s some screenshots of my progress:
This is not the final version. I’m really looking forward to what you think of this new environment for Well, and the minor details I’ve been adding to the map to make it feel a bit more alive!
Something else I worked on these past months was my little Badlands themed scene, I’m quite proud of how it turned out. It also made us learn which environment lighting settings we should use for exterior scenes in this theme. It took quite a few tries and some hours of compiling but here it is!
We have received an overwhelming number of applications since we initially announced this project on our Twitter. To be honest, we never expected to see such talent and diversity in our applicants.
While we cannot accept nor reply to everyone due to the quantity of applicants, we're letting you know that you could still be considered in the future if we need more talent.
Again, thank you to everyone who's applied to date. We've been overwhelmed by all the responses and feedback regarding our project. It is truly awesome to see the incredible response from the community and your passion for Team Fortress: Source 2.