[ARTICLE] Snowplow and the tricks we used to create the Largest map in TF2

Fruity Snacks

Creator of blackholes & memes. Destroyer of forums
aa
Sep 5, 2010
6,394
5,571
Snowplow and the tricks we used to create the Largest map in TF2*

A post-mortem on the things I learned that have made me a better level designer

Introduction:
Snowplow is huge. It's easily twice the size of hydro, with each stage being the equivalent of a full Hydro map. When you start making maps that are that large, the Source Engine, and by proxy, Hammer, start to have fits. Cordoning off sections of the map becomes your REALLY good friend, and you need to start getting creative with how things happen. Skybox creation, optimization, detailing and more all start to become a little bit harder due to sheer size. I don't expect another map the size of Snowplow to be made, but I'm going to write up some things that YM and I did to help anyone else in the future who may find themselves risking Sources Limits.

1. How big is Snowplow, really?
Take a look. This is the topdown view onto the hammer grid. There are not many sections of the map with really large out of bound areas. The largest one is the ravine next to Stage 1, CP 2. Everything else is actually pretty close to the skybox. This just helped with optimization and keeping things a bit smaller. We didn't want to get any closer to the edge of the map than we needed.
psmqhFT.png

Fully zoomed out top-down view of Snowplow in hammer.

2. Skybox
Another popular question is “What does the skybox look like?” Again, take a look. It's pretty messy and looks nothing like it does in game. Since Snowplow was so large, we couldn't get too close to the map edges and thus, we couldn't separate the stages in hammer enough to make sure the skyboxes didn't fight with each other. Additionally, both stages were two separate themes, so we couldn't use the same skybox to begin with.

M2aceET.png

You can see the overlapping skyboxes here. That spawn point is at the center of skybox clusters.


To remedy this, we separated the Stage 1 and Stage 2 skyboxes into their own dynamic prop clusters. They were then enabled/disabled during stage transition, to whatever stage was active at the moment. This allowed for us to use the same skybox space for both stages, which meant we could have bigger skyboxes in each stage.
I would suggest using this technique in any multistage map. It means that you can have much more detailed skyboxes at the cost of a higher dynamic proper count, which unless you're snowplow, shouldn't be a problem. Just make sure your edicts aren't super high.

3. Lighting
The skybox is the same, but the lighting styles feel different, what did you do? Nothing really. The Badlands environmental lighting is pretty awesome and can work in all environments, winter, alpine, desert, hell, throw it on the moon and you could probably make it work. Changing the physical environment and making your light entities just a different shade can do a lot to a map.

4. Collaboration
There were points when YM and I were working on the map at the same time. Hammer hates this, so how did we do it? When I was making snowplow, I was in LOVE with non-orthogonal geometry. This meant lots of weird-angled structures, like the entirety of Stage 2, CP 2. One of the best ways to do this in Source is through Instances. Instances are separate .vmf's where you can build whatever you want, then place it in your main map file. 90% of the stuff in an instance will work exactly like if it wasn't in an instance. What this means, is that you can build normal structures on grid in a separate .vmf and then put them into your map at whatever angle you want. Warning though, standard optimization/VVIS rules do apply here, so if it's a func_detail in the instance, it'll be a func_detail in the main file.

LeQlDPX.png

Stage 2, point 1 instance. This is actually two instances. The little hut on the left, then everything else.

Now, onto the important bit of this. Majority of Stage 2 was at one point, instances. I think Stage 2 at one point had 5 instances: The entire of point 1 and 2's structures, and full entirety of the finale. Displacements and all. This number is lower now as we've collapsed some of them down into the main file. So while YM was working on the main file and Stage 1, I could work on instanced sections of stage 2. Having all files synced through dropbox meant that just reloading the map always meant I had the most up-to-date save. This worked out rather well and I would recommend it to anyone else who is collaborating together on level design, or detailing. Warning though, make sure that you're both saving often and autosaves are turned on.

I suggest looking at the func_instance wiki page for more information. I'll see if I can do a tutorial on those for everyone. You can do a fair bit, and they're pretty neat.

5. Having to change up places you've already Artpassed.
This happened a couple times with Snowplow. We'd be testing, feeling pretty confident with an area, start detailing it, then discovering that it kind of sucks and we need to do a lot of changes. We were under a bit of time crunch, so we didn't want to hold on detailing for very long. Notably this happened around Stage 1, point 2 and 3, along with Stage 2, point 1 and 3. It's tough, but sometimes it just NEEDS to happen. The best advice I can give about this is to try and do your best with what you already have, and build around/from that. Tearing out a section though is something that you have to do. Block out the new section, test it and if you're confident with it, start to detail it while you test it more.

6. Optimization.
Surprisingly, wasn't too hard when you get the basic idea of whats going on. For my computer (which, admittedly, is built for compiling games/levels/etc), I could compile the shipped copy of snowplow in approx. 45 minutes. 35-36 of that being VRAD (Lighting). I don't want to go into optimization techniques right now, that's for another tutorial, but I will leave it with one example. Picture your map as a big cake. You want players to only have the smallest possible pieces of cake as they can. Design your map with that in mind, breaking it up with geometry so that players can only see the pieces you want them to see at a time. A big chunk of having an optimized map, is designing your map to be optimized. (Think about that for a minute).

Again, if I get some time I'll do a tutorial on VVIS and general optimization… and hopefully make it something that is easy to understand.

7. Testing
We had a special super-secret-but-not-really-testing-group-of-awesome we called upon whenever we needed to have testing done on Snowplow. We then went to public testing. There was LOADS of data that was there. With YM and I being scientists by education, we naturally did what we knew best. We recorded data and graphed it. We looked at standard deviation, we looked at it compared to previous versions, we set goals. We had excel spreadsheets (I'm not kidding) for a few versions to keep track of data. It was REALLY HELPFUL. Tie this in with the, at the time, recently released heatmaps.tf and we were able to locate trouble spots with relative ease. This, again, is a topic worthy of it's own article, which may or may not get written. Data analytics and statistical analysis though, are really fun and super useful in game development. (Honestly, this was the part that made me happy, bubbly and giggly the most. I LOVE DATA.)

Mp58q4f.png

Graph of a select amount of runs of Snowplow with near-server play.

YAgVwdH.png

Average health of the train after leaving each point.

Conclusion:
Thats about it for now. Hopefully you picked something new up, or had a “Why didn't I think of that” moment. Maybe you already knew all this. Who knows! I just hoped you enjoyed the read… or the pretty pictures. Now, a lot of this is written from my perspective. YM may have more he could add, if he so chooses. If anyone has any additional questions, just ask 'em and I'll do my best to answer them.

Thanks everyone for the support during development!
---

*This fact not actually fact checked, so believe at your own disgression, but we're pretty sure we're the largest, or second largest TF2 Map ever made. Definitely the largest official map.
 
Last edited:

Psy

The Imp Queen
aa
Apr 9, 2008
1,706
1,491
Ah, the old show and hide trick for multi-stage skyboxes. Had to do the same for Nightfall. :)
 

Fruity Snacks

Creator of blackholes & memes. Destroyer of forums
aa
Sep 5, 2010
6,394
5,571
Ah, the old show and hide trick for multi-stage skyboxes. Had to do the same for Nightfall. :)

Yeaaaa

It was a pretty obvious solution, but fun to implement.

If you look closely actually on stage 2, you can see that the particles still burn from the Stage 1 blue-base destruction
 

worMatty

Repacking Evangelist
aa
Jul 22, 2014
1,258
999
I'm interested to know your thoughts on the use of non-orthagonal geomtry and visleaves in Snowplow. Did the instances generate a lot of ugly-looking leaves, and were they a problem? Is it possible to see some example screenshots of the portal file loaded from your most recent compile?

Thanks for the article. Very interesting.
 

Crash

func_nerd
aa
Mar 1, 2010
3,319
5,500
I'd like to see your portals loaded up, just out of curiosity, when you have a chance. I'm curious how tangled up it all got. I use some instancing for angled buildings on Probed but it makes a mess of things.
 
Oct 6, 2008
1,948
446
Nope - I think this was the largest map ever made (my original goldheist)

Awesome map! And I agree, it's HUGE!

You can still get it here

http://tf2.gamebanana.com/maps/163323

That being said, I played it for the first time the other night - really enjoyed the game stle :)

The heatmaps thing is cool - how do you get them onto all your maps for testing, etc? Thanks
 
Last edited:

Fruity Snacks

Creator of blackholes & memes. Destroyer of forums
aa
Sep 5, 2010
6,394
5,571
Nope - I think this was the largest map ever made (my original goldheist)



You can still get it here

http://tf2.gamebanana.com/maps/163323

That being said, I played it for the first time the other night - really enjoyed the game stle :)

The heatmaps thing is cool - how do you get them onto all your maps for testing, etc? Thanks

*This fact not actually fact checked, so believe at your own disgression, but we're pretty sure we're the largest, or second largest TF2 Map ever made. Definitely the largest "official" map.

Even with your verticality (cheater) we're still bigger. Thats tiny compared to maps like Zinkenite or Meridian or most 3 stage maps.

Portfiles:
portfile_1.png

portfile_2.png

portfile_3.png

portfile_4.png

portfile_5.png


There's a lot of blue lines, but you'll notice that most of them are still relatively organized.

Oddly enough, the bit that is on grid is probably the worse when it comes to portal.
 
Last edited:

A Boojum Snark

Toraipoddodezain Mazahabado
aa
Nov 2, 2007
4,775
7,670
The thing to remember about portals is, unless you are having issues with the max portal/leaf limit (I think you'll run into others before that, though), all it really does it optimize compile time. Having messy portals isn't an issue if it means the map runs smoothly for it.

Did you actually have problems that were solved by staying away from the edge? As far as I've ever seen that doesn't mean anything to the engine until you actually touch the edge.
 

Fruity Snacks

Creator of blackholes & memes. Destroyer of forums
aa
Sep 5, 2010
6,394
5,571
The thing to remember about portals is, unless you are having issues with the max portal/leaf limit (I think you'll run into others before that, though), all it really does it optimize compile time. Having messy portals isn't an issue if it means the map runs smoothly for it.

Did you actually have problems that were solved by staying away from the edge? As far as I've ever seen that doesn't mean anything to the engine until you actually touch the edge.

We just didn't want to go near it to begin with, so we just stayed away.
 

Pocket

Half a Lambert is better than one.
aa
Nov 14, 2009
4,696
2,580
Something I never thought to ask, because I'd forgotten about the new lowered limits on fullness, is how you managed to stay within them. Because even Hydro exceeds the limits nowadays, and Snowplow is twice that size. Is it just not very complex for its size?
 

Fruity Snacks

Creator of blackholes & memes. Destroyer of forums
aa
Sep 5, 2010
6,394
5,571
Something I never thought to ask, because I'd forgotten about the new lowered limits on fullness, is how you managed to stay within them. Because even Hydro exceeds the limits nowadays, and Snowplow is twice that size. Is it just not very complex for its size?

47ish props worth of interior beams.
 

Flower_Shop_Guy

♪ -- ♫ -- ♪
aa
Mar 10, 2015
196
488
Hey, I have a question: map have around 1520 edicts, and no issues with 32 players servers? Cos, my b1 "eclipse" had much edicts as yours and servers crashed with "Engine error: ED_Alloc: no free edicts" error, after 15-20 minutes of playing. :) Issue was gone when I reduced number of edicts. (~1440 now)
 

Bunbun

aa
May 18, 2014
401
782
Just wondering what was the most horrifying part of making snowplow?
 

ics

http://ics-base.net
aa
Jun 17, 2010
841
543
I'm interested in entity related things. What does actually eat them so much? Is it the lighting or the cap point things themselves or the train track path_tracks?
 

Fruity Snacks

Creator of blackholes & memes. Destroyer of forums
aa
Sep 5, 2010
6,394
5,571
Just wondering what was the most horrifying part of making snowplow?

Working with YM. He's smelly. (jk).

For me, the scariest part was making something that, personally, I would be proud of and happy to say "Yes, I worked on that!" Despite the wide spectrum of responses, I am very proud to have said "I worked on snowplow!" despite some of its short comings.

I'm interested in entity related things. What does actually eat them so much? Is it the lighting or the cap point things themselves or the train track path_tracks?

] report_entities
Class: ai_network (1)
Class: ambient_generic (69)
Class: beam (17)
Class: env_shake (14)
Class: color_correction (3)
Class: env_soundscape (4)
Class: env_fog_controller (3)
Class: env_soundscape_proxy (83)
Class: env_screenoverlay (10)
Class: env_sprite (317)
Class: filter_activator_name (1)
Class: env_tonemap_controller (3)
Class: filter_activator_tfteam (6)
Class: filter_activator_class (2)
Class: func_areaportal (43)
Class: func_brush (13)
Class: func_door (34)
Class: func_regenerate (10)
Class: func_door_rotating (13)
Class: func_respawnroom (8)
Class: func_illusionary (27)
Class: func_respawnroomvisualizer (17)
Class: func_nobuild (1)
Class: func_tracktrain (3)
Class: func_occluder (23)
Class: game_round_win (2)
Class: info_observer_point (17)
Class: info_particle_system (61)
Class: info_player_teamspawn (98)
Class: info_target (4)
Class: item_ammopack_medium (21)
Class: item_ammopack_full (7)
Class: item_ammopack_small (5)
Class: item_healthkit_full (1)
Class: item_healthkit_medium (19)
Class: keyframe_rope (77)
Class: item_healthkit_small (15)
Class: logic_case (5)
Class: logic_compare (6)
Class: logic_relay (77)
Class: point_template (2)
Class: logic_timer (7)
Class: math_counter (1)
Class: prop_dynamic (183)
Class: math_remap (1)
Class: prop_physics_multiplayer (4)
Class: monster_resource (1)
Class: scene_manager (1)
Class: move_rope (33)
Class: shadow_control (3)
Class: path_track (131)
Class: sky_camera (2)
Class: phys_bone_follower (17)
Class: soundent (1)
Class: player (1)
Class: spotlight_end (17)
Class: point_clientcommand (1)
Class: team_control_point (6)
Class: point_spotlight (17)
Class: team_control_point_master (1)
Class: team_control_point_round (2)
Class: tf_mann_vs_machine_stats (1)
Class: team_round_timer (1)
Class: tf_objective_resource (1)
Class: team_train_watcher (2)
Class: tf_player_manager (1)
Class: tf_gamerules (1)
Class: tf_team (4)
Class: trigger_capture_area (6)
Class: trigger_hurt (10)
Class: trigger_multiple (19)
Class: trigger_push (2)
Class: vote_controller (1)
Class: worldspawn (1)

Basically dynamic props and the path_tracks take up the most. Theres multiple animations per trap, and multiple bodygroups on the train, the entire skybox set up is multiple prop_dynamics.... along with a load of various other things that we can't use prop_statics for.