Jump to content

When I Get Bored I "Reverse Engineer" Games


Recommended Posts

Sometimes with games I like to try and figure out how things were done by experimenting in game.  I know this is completely pointless with 0AD because it is open source (not that I'd be able to make sense of the code), but I find it fun to try and pick apart the systems and make predictions and see if I was right; plus, it is good exercise for all this mathematics I'm supposed to be learning!

I have been looking at construction in 0AD.  I select a group of citizens, build a structure, then immediately destroy it and build it again, this time timing the construction -- this ensures that all builders are optimally positioned for the timed build.  I do this with a single builder, then two, three, four, as many as I think I need for the data.

I tried this with houses and after gathering the data I can make an educated guess that the formula for construction is something like this:

t = k/sqrt(n)

where t is the time taken (in seconds), n is the number of builders at the site, and k is a constant specific to the type of building being constructed.

The k constant for houses is 12. (k will always equal the build time using a single builder.)

Am I close?

As I write this I remember that I think citizen soldiers and women build at different rates.  I can't remember which I used but I think it was all women.

Anyone else "play" games in weird ways like this?

[update]

I've experimenting with building temples.  I think the data I got was a lot better this time and the formula I sort of guessed my way to is a very good match.  It seems the power of n is not a constant but is specific to building types:

t = k/(n^c)

where t is the construction time (in seconds), n is the number of builders at the site, and k is a constant specific to the type of building being constructed, and c is a new constant, also specific to the type of building.  For houses k=12 and c=1/2, for temples k=240 and c=sqrt(1/2).

[update]

After a bit more experimenting with temples I've found that sometimes c=2/3.  It's very odd to me that there are groups of numbers of builders that can be predicted perfectly (within 1 second) with c=sqrt(1/2), then comes another group that fits c=2/3 much better, it seems to constantly flip between the two values for c over increasingly larger groups.

That's a bit disappointing.  Something else must be going on here, the switching is too regular to be down to random glitches or CPU spikes.  It has to be something systematic, like rounding errors.

Trying to work this stuff out is fun but I'm getting bored of testing.  I will try to figure out what the connection is between these data and the building type stats and come up with a general formula, then I will try to predict the build time for a building I haven't tested.

[update]

I was way off. :(

I timed a build of a civic center and it took 2.8 times as long to build as my prediction.

I even repeated the house building experiments before making my prediction, because I noticed that my data was way off.  A single person building a house in 12 seconds!?  I must have had a load of construction buffs or something.  Still, it didn't help in the end. :(

Oh, well.  Now I will have to find out what the real algorithm is and see if I was on the right track.

Edited by Libervurto
  • Like 2
Link to comment
Share on other sites

Might have to warn you that continuous investigation of code behavior might lead to bugfixes.

http://trac.wildfiregames.com/wiki/BuildInstructions

http://trac.wildfiregames.com/wiki/GettingStartedProgrammers

I suggest though to lookup the components and templates in binaries/data/mods/public/simulation/ as it's much faster than a blackbox analysis.

The buildtime depends on the number of workers, on the units that work individually (at least the code supports that) and the buildings HP. Also auras and technologies can affect the build rate - for example the female inspiration aura (10% faster males in the range of females). Most importantly, the more units are assigned to a building, the slower they work individually (hence some pro players build each structure with only one unit, so that the construction finishes just when it's economically feasible to use it at capacity).

http://trac.wildfiregames.com/browser/ps/trunk/binaries/data/mods/public/simulation/components/Repairable.js#L74

Repairable.prototype.GetRepairRate = function()
{
    let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
    let cmpCost = Engine.QueryInterface(this.entity, IID_Cost);
    let repairTime = this.repairTimeRatio * cmpCost.GetBuildTime();
    return repairTime ? cmpHealth.GetMaxHitpoints() / repairTime : 1;
};

 

  • Like 3
Link to comment
Share on other sites

Okay, I couldn't follow the code very well but I did catch that the power being used is 0.7, which is very close to the sqrt(1/2) I was using (roughly equal to 0.707).  So, that's nice!

I have devised a general formula based on the building max HP and number of workers, it's not precise but it's a good estimate.

t = k / n^0.7

k = v^2 / 22000

Where v is the building max HP, n is the number of workers, and t is the build time.  I used a separate variable k because it is useful to have that calculation done in parts; k is the build time for one worker.  k would probably be precalculated and stored as an attribute of the building class.

We could create a look-up table for the workrate, for 1 to 100 workers, which could save processing time.

for n = 1 to 100
    workrate[n] = 1 / n^0.7
next n

Then the formula becomes a single multiplication

t = k*workrate[n]

 

I wonder if this would work any better or worse than the current code. :huh:

Edited by Libervurto
Link to comment
Share on other sites

The code looks performant enough. The Math.pow() operation is only done when SetBuildMultiplier is called (i.e. whenever a builder is added or removed). Repair and GetRepairRate are likely called more often on average (and these functions are trivial, just 4 divisions).

Useful 0 A.D. math includes computing when economic upgrades are worth it in comparison to creating more workers, or comparing the profit/cost ratio of trade carts with gatherers, or computing how many units survive when outnumbering the enemy using Lanchester's laws.

 

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...