We are currently trying out a new resource-based building system on our Development & Testing Server. The system itself is work in progress and could change at any time, but as our first test games were a lot of fun and we find that it has a great potential it should be about time to explain to you how it currently works, so you can quickly adapt and discuss the system with us on a higher level of understanding.
What’s a resource system?
Tremulous used a pool of build points that each team was given at the beginning of a match. Teams could spend the build points to build structures. When structures got destroyed, the build points entered a queue and after a while became available to the teams again. There was a sudden death mechanism that disabled building alltogether after a timelimit was hit.
Resources are, just like Tremulous build points, spent to build structures but they are not returned if a structure gets destroyed. Think of them as an actual payment for building the structure, as opposed to a mere limit of how many structures you can have simultaneously. Replacing and moving of structures is still possible and won’t be penalized: if a structure at n% health gets deconstructed for either reason, you will get n% of its price back. The resource system I’m going to talk about describes the way that building resources, which we will still refer to as build points (BP), are acquired.
Resource Generating Structures (RGS)
Both teams are given an initial amount of build points. If they want to acquire more, they need to build Resource Generating Structures (RGS) that generate them over time. The human RGS is called Drill, the alien one is called Leech. They, too, have a construction price. RGS have a spherical area of effect described by their range. If the areas of effect of two RGS intersect, they will have a reduced efficiency, forcing teams to expand over the map.
Resource generation
Each RGS has an efficiency e. If a RGS doesn’t interfere with another one (that means that their distance is above a threshold), that efficiency will be at 100% (e = 1), otherwise it will be lower, but positive. The mine rate of a RGS also depends on the level-wide (team independent) base rate r(t) (in BP/min), which itself depends on the time t (in minutes after the match begun). The current generation rate of any RGS is simply e×r(t). r(t) has an initial value r(0) = R₀ which can be configured on the server. The base rate r(t) also has a half life period T (in min), which can also be set on the server. This will replace the artifical sudden death, as teams will get a decreasing number of resources over time. The formula to calculate r(t) is R₀×2-(t/T).
Example
Let’s asssume we have a single RGS on the map. Since its area of effect does not overlap with another RGS, it will generate resources at 100% efficiency, so e = 1. Now let R0 be 15 BP/min and let T be 15 min. If the RGS already exists at the beginning of the match (t = 0), it would generate at a rate of 15 BP/min at that moment. If the match has been running for 15 minutes (t = T), the RGS would only generate 7.5 BP/min (no matter if it has been present since the beginning or has just been built). After 30 minutes (t = 2T), the RGS would generate 3.75 BP/min.
Interference: Idea and Approximation
One of the key ideas behind the RGS approach is that it should force the teams to expand and gain control of the map. This is accomplished by reducing the efficiencies of RGS that are built too close to each other (another approach would’ve been to simply forbid placing of a RGS in the range of another one but we found this to be too artificial and rigid). Our idea was that a number of RGS together would, no matter what teams they belonged to, generate at a rate that was proportional to the volume of the union of their spherical areas of effect (AOE). This alone would’ve been far too complex to implement in a real time game but since we also need to assign every RGS an individual generation rate (because they might belong to different teams), this approach was out of question. We decided to use an approximation of it though: We look at pairs of interfering RGS and calculate the intersection quota q. If q = 1 then the AOEs are identical. If q ≈ 0 then they barely touch. If q = 0.5 that would mean that 50% of the AOE of one RGS lays inside the AOE of the other one. Now for two interfering RGS, we independently halve the part of the efficiency that corresponds to the overlapping area. So if the efficiency of one of the RGS was at 100% and 20% of its AOE overlapped with that of the other one, we would reduce the efficiency to 80% + 0.5 × 20% = 90%.
Example
We only have two RGS on the map. They might belong to different teams or a single team. Now let the RGS range be 800 qu (quake units), so that their area of effect is a sphere with a radius of 800 qu. If the two RGS are at a distance of 1600 qu or higher, they would both mine at 100%. If they were both in the very same spot (which is not possible, of course), they would both mine at 50% efficiency. If they were at a distance of 800 qu, parts of their AOE would overlap and we would find the relative size of the intersection area to be 5/16. So now we would half 5/16 of the initial efficiency and get a new efficiency of (1 – 5/16) × 100% + 5/16 × 100% × 0.5 = 11/16 + 5/32 = 27/32. Both RGS together would now mine at a total efficiency of 2 × (27/32) = 54/32 which is exactly the volume of the union of their AOEs divided by the volume of a single AOE. Note that our approximation is always exact if each RGS interfers with not more than another one.
Approximation side-effects
The pairwise approximation appproach yields exact results for pairs of RGS but produces an error when more than two RGS interfere. This error will always penalize the cluttering of RGS (meaning building many of them close by). If, hypothetically, n RGS are built in the very same position, the total efficiency would be n/2(n-1). So one or two RGS will yield 100% efficiency but three RGS will only generate at 3/4 of the speed of a single RGS. If you build 10 RGS in the same spot the total efficiency would drop to less than 2%. While this effect is, in theory, an error, it has a number of positive side effects:
- The number of calculations that is necessary for n interfering RGS is n×(n-1) and thus its complexity is in O(n2). The fact that players have a motivation not to let RGS AOEs interfer will help keep the server load low.
- You can choose to build two RGS closeby so that one takes over completely if the other one gets destroyed. Since this advantage comes at double price and build time, I consider it a balanced decision that can make strategic building more interesting. At the same time the penalty will prevent mindless ‘more is better’ spamming of RGS.
- RGS can also be used as a weapon against campers: Just build a lot of RGS next to the enemy camp and they won’t be able to generate any more resources there.
Get involved!
If you want to help in the development of the resource system, give your feedback on the forums and help us testing by participating in our development games, which we will announce on the forums and on IRC.