Jump to content
Sign in to follow this  
bewilderbeest

Need advice on how to create a MP area capture system

Recommended Posts

Hi all,

I'm a relatively new Arma coder, so I'm looking for some advice on how to improve my multiplayer capture system. It currently runs, but the longer the server is up, the slower it gets, and I don't know why :(

I've currently got a structure whereby I use a list of map markers to create client-side triggers. These triggers use setVariable on the player to denote which capture area they've entered or exited. It looks something like:

player setVariable ['CAP_POINT', 'CAP_POINT_AIRSTATION_MIKE', true];

On the server I have a while-true loop which goes through each player, pulls out the capture area they're at, and then does a process of reconciliation to figure out which areas are contested, which are uncontested and then ticks up a capture timer accordingly.

The pseudo-code for this in various stages. First we get an array of each player + the cap point they are at:

_capPointPlayerMapping = [];
{
 _curCapPoint = _x getVariable ['CAP_POINT', ""];
 _capPointPlayerMapping = _capPointPlayerMapping + [[_curCapPoint, _x]];
} foreach playableUnits;

I then reduce this down to a mapping of each cap point, and an array of players present (I wish we had hashes!! (I know we've got some stuff on the dev branch) ).

For each capture area I then pass to a function which returns the following:

- Number of WEST players

- Number of EAST players

- Number of GUER players

- Name of dominant team

- Contested state (true if multiple sides are present)

This is then reconciled into a set of actions for each area. RESET, CONTINUE or BLOCK.

- If it's RESET, take the current counter value for the capture point and set it to zero

- If it's BLOCK, don't increment the counter

- If it's CONTINUE, increment the capture counter value

If the capture counter is over a threshold, mark the capture point as owned by the currently dominant team in that area.

I then store the following data as an array for comparison the next time round the loop. [CAP_POINT_NAME, ARRAY_OF_PLAYERS, TIMER].

 ['CAP_POINT_NAME', [ <PLAYER 1>, <PLAYER 2>, <PLAYER 3>], 20]

After this I sleep for 2 seconds and do it all over again.

My problem is that the capture time slowly creeps up on our server. We run a 64 player Wasteland mission, so there's already a load of stuff running in the background. The overall loop time, according to diag_tickTime calculations ranges from 0.0220032s all the way up to 1.18164s. Is there a reason for this timing discrepancy?

Looping over the list of players and doing some string comparisons and array reconciliation isn't difficult. There are only about 15 capture areas on the map.

is player getVariable [] a REALLY slow call? Is there a better way I can get client data up to the server? Any advice you more experienced coders can give me would be really helpful.

My code is available at https://gist.github.com/nickludlam/9bb8bf4521eaeb16d81c and the required array captureAreaMarkers is [ ['MARKER_NAME_1', 'Description of area'], ['MARKER_NAME_2', 'Description of area 2'] ].

Thank you lovely Arma community!

Bewilderbeest

Share this post


Link to post
Share on other sites

Or failing any direct advice on this specific problem, can anyone share their tricks on how to debug non-performant code in Arma script? I'm using diag_tickTime to get an idea of speed for individual methods, but is that basically as good as it gets?

Share this post


Link to post
Share on other sites

Thanks kylania, I had no idea that existed!

I'm trying to debug an overloaded server, but I'm guessing the codePerformance method doesn't really work like that given it has a GUI element. Any other things for debugging server load?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×