Forbidden Elements Tower Wars
From TDGwiki
Contents |
Statistics
- Map Size: 128x128
- Players: 8
- Author(s): Zoizite & Kaye-
- Project Start Date: Feb '06
- Project Status: Finished
- Version: 3.25
- Download: Forbidden Elements Tower Wars
About the Map
Forbidden Elements Tower Wars, henceforth FETW, is a Tower Wars map competition between 4 teams of 2. Each team is out to last the longest as they defend their stock of 50 lives from waves of units sent from opposing teams. These units are purchased from each player's Barracks and are spawned for each opposing team to walk along the predetermined path to the center. If a unit reaches the center, the team that 'leaked' that unit has lost 1 life. In order to defend your lives, you must construct towers of various strengths and abilities to kill the units before they reach the center.
History
Somewhere along the line in February of 2006, Zoizite made a map known as Forbidden Elements Tower Wars. It was very well received and quite popular on Battle.net for some time. However FETW had fallen to horrible lag that made it impossible to play. Additionally, Zoizite's computer had died and no unlocked version was to be found. It is for these reasons that the map fell into obscurity for a while until a combined effort between Zoizite, CHUNK, Shvegait, and Kaye- broke the protection and revived FETW.
Towers
In the beginning, you will have 3 available towers: Ranged, Splash, and Special. Over time, you will gain the ability to upgrade Elements of your choosing. These elements are:
- Fire
- Demon
- Cold
- Holy
- Earth
- Lightning
- Wind
- Poison
- Magic
- None
There are 4 ranks to every element, each rank offering a large improvement over the last. In addition to this, there are 4 levels per rank that offer only damage increases. A tower can be created as a level 1 rank X tower, or it can be upgraded from level 1 to 4 and then to the next rank.
Separate of tower ranks and levels, every element has an upgrade that increases the attack speed of all towers of that element.
Non-Element
Fire
Large splash radius.
- Fire Tower
- Blaze Tower
- Infernal
- Pyromancer
- Pyromancer
- Infernal
- Blaze Tower
- Fire Tower
Demon
Bouncing attack.
- Demonic Tower
- Black Tower
- Succubus Tower
- Wraith
- Wraith
- Succubus Tower
- Black Tower
- Demonic Tower
Cold
Slows targets.
- Cold Tower
- Frost Tower
- Glacier Tower
- Hyperborean
- Hyperborean
- Glacier Tower
- Frost Tower
- Cold Tower
Holy
Various tower buffs and unit dispels.
- Holy Tower
- Divine Tower - Dispel Magic
- Heavenly Tower - Power Up
- ArchAngel- Zeal
- ArchAngel- Zeal
- Heavenly Tower - Power Up
- Divine Tower - Dispel Magic
- Holy Tower
Earth
Highest damage rate against ground units.
- Earth Tower
- Terra Tower
- Boulder Tower
- Golem
- Golem
- Boulder Tower
- Terra Tower
- Earth Tower
Lightning
Longest attack and damage range.
- Lightning Tower
- Bolt Tower
- Thunder Tower
- Blitz Tower
- Blitz Tower
- Thunder Tower
- Bolt Tower
- Lightning Tower
Wind
Highest damage rate against air units.
- Wind Tower
- Squall Tower
- Tempest Tower
- Zephyr
- Zephyr
- Tempest Tower
- Squall Tower
- Wind Tower
Poison
Deals damage over time.
- Poison Tower
- Venom Tower
- Bane Tower
- Pestilence - Shadow Strike
- Pestilence - Shadow Strike
- Bane Tower
- Venom Tower
- Poison Tower
Magic
Various unit debuffs and damage spells.
- Magic Tower - Slow
- Arcane Tower - Faerie Fire
- Runic Tower - Runic Prison
- Sibyl - Chain Lightning
- Sibyl - Chain Lightning
- Runic Tower - Runic Prison
- Arcane Tower - Faerie Fire
- Magic Tower - Slow
Archer
Equally effective against all units.
- Archer Tower
- Ranger Tower
- Rogue Ranger
- Artemis
- Rogue Ranger
- Ranger Tower
- Archer Tower
Crashing Lag
The Cause
The cause of the game-ending lag was due to a burst execution of inefficient code. Of notable importance is the CreateNUnitsAtLoc() function, which caused a significant amount of the lag due to its creation of a Unit Group and other unnecessary code when creating only 1 unit at a time. However, that is minor compared to the code structure, which was the direct cause of lag.
When a unit was purchased by a team, it would begin by removing it immediately. The problem lies when it must several large loops in order to create that unit in the right position for every other team. Every unit purchased -> three units created. While this would normally be fine, what happens when all the players' barracks are creating a unit at once; 8 * 3 = 24 units must be created instantly. Again, this isn't that big a deal. The problem lies in the rate at which those 24 units are being created, due to the gameplay. Players are mashing their hotkeys to create about 4 units per barracks at once. That's 4 * 8 * 3, 96 units at once. Now it has to continue this for the complete barracks, which is, roughly, 15 available per unit * 8 non-heroes per barracks * 8 barracks * 3 opposing teams = 2880 calls to CreateNUnitsAtLoc() in a rather short amount of time, a matter of seconds. That is the problem.
The Solution
The, now obvious, solution was to make part of that timer-based. You can't, without affecting gameplay, prevent players from purchasing units so quickly. What you can do is reduce the number created at that moment. Previously, each player has a incoming queue of units to be spawned along his or her path. Under the new system, each team has an outgoing queue of units. Instead of picking from each players' queues at the periodic spawn timer, it must pick from each other team. Additionally, it doesn't actually do anything but add to the team's queue upon purchasing a unit. Looking back at the number of units being spawned in a short period of time, it is essentially 0, since neither CreateNUnitsAtLoc() nor CreateUnitAtLoc() are called at this time..
The new system instead does everything during a base loop of 4. Admittedly, it has half the period of the old timer, but it is more effective to be spreading out the processing. It first observes team 1's queue, and whether or not there is a unit. It then loops among the remaining players and creates the unit, if it exists. That created unit instantly starts pathing, and then it moves on to team 2 and does the same, except on the other player's path for each team. Thus, every period, it loops 4 * 3 times and creates up to 12 units at once using the far more efficient CreateUnitAtLoc(). Thus the lag was fixed, and the game became playable once more.
However, here lies an interesting problem within this system. If, in the example above, team 3 also has a unit to spawn, there isn't a 3rd path to send it down; it has to go down the first player's path for team 4. This creates the issue of 'double spawning' along one path, and it would often do it. The solution employed was a bit brute force; it merely detects the distance between the current and the last unit spawned for that team and shoves it to the other side. Additionally, the system was changed from creating pairs of units at the same time to equally timed alternating, which allowed the fix to work perfectly.

