Advertisement

Simulating large scale battles

Started by September 08, 2010 05:40 AM
6 comments, last by Edtharan 14 years, 5 months ago
I'm designing a browser-based game that will involve battles between large armies.

I'm trying to make some design-level decisions about how best to do this and simulate something that seems statistically realistic.

The way I'm doing it now (for example) has two armies with various accuracy%, damage, health, and sizes.

Which side fires is currently random with 50% probability for either side regardless of the size of the armies.

Here is some example code (the actual game is a little more complicated with each side being able to have multiple types of units)

<?php$accuracy_1 = 50;	//a percent$damage_1 = 20;$health_1 = 100;$size_1 = 50;$accuracy_2 = 50;	//a percent$damage_2 = 20;$health_2 = 100;$size_2 = 60;//initialize the healths of army 1for ($i=0; $i<$size_1; $i++){	$current_health_1[$i] = $health_1;}echo "initialized all $size_1 of army 1's soldiers to their max current health of $health_1<br>";//initialize the healths of army 2for ($i=0; $i<$size_2; $i++){	$current_health_2[$i] = $health_2;}echo "initialized all $size_2 of army 2's soldiers to their max current health of $health_2<hr>";//main battle loopwhile (($size_1>0) && ($size_2>0)){	$dice = rand(1,2);	if ($dice == 1)	{		//army 1 shoots with a random soldier at a random soldier in army 2		//first we choose a random soldier from army1:		$dice = rand(0,$size_1-1);		//now we do an accuracy roll to see if the soldier shoots successfully		$dice = rand(1,100);		if ($dice <= $accuracy_1)		{			//shot was successful, now we ramdomly pick a soldier he hit			$dice = rand(0,$size_2-1);			//now we subtract the firing soldier's damage from the targetted soldier's health			$current_health_2[$dice] -= $damage_1;			//now we see if the shot soldier is dead			if ($current_health_2[$dice] <= 0)			{				//since this soldier died, we replace his health with the soldier who is				//highest in the array and reduce the size of the army by 1				$current_health_2[$dice] = $current_health_2[$size_2-1];				$size_2--;			}			//no else condition needed since if soldier is still alive, there's nothing more to do		}		//no else condition needed since if the soldier misses, this side's turn is over	}	else	{		$dice = rand(1,$size_2);		$dice = rand(1,100);		if($dice <= $accuracy_2)		{			$dice = rand(0,$size_1-1);			$current_health_1[$dice] -= $damage_2;			if ($current_health_1[$dice] <= 0)			{				$current_health_1[$dice] = $current_health_1[$size_1-1];				$size_1--;			}		}	}}echo "army 1 has $size_1 soldiers left<br>";echo "army 2 has $size_2 soldiers left";?>


Is this reasonable for combat (statistically) or would it make more sense for which side fires to be random with probability in proportion to army size?

example: size_1 = 100, size_2 = 200, so there would be a 2/3 chance of army 2 firing this round and a 1/3 chance of army 1 firing this round.


Also a bigger question:

Is this a reasonable way to simulate things? (eg. with flatly distributed probability, select one soldier from the army, then with flatly distributed probability, select one soldier from the opposing army, then do a single accuracy roll, then subtract 'damage' health)

The reason I lack confidence with my current design is that the results don't conform very well to Lanchester's equations.

Basically, the way I'm doing things now, the smaller 'damage' or 'accuracy' or 'health' is, the bigger the advantage of having a larger army seems to be.

For example, if size_1 = 50 and size_2 = 60, accuracy_1 = accuracy_2 = 50, damage_1 = damage_2 = 1, health_1 = health_2 = 100, then the result of the battle is that army 1 loses every soldier and army 2 loses no more than 5.

This seems too skewed a result for only a 20% larger force, causing me to question the statistical validity of my overall design for battle.
Well I suppose one issue with your design is since damage is effectively evenly distributed a larger army can soak far more damage before starting to suffer loses then a smaller one.

Army 1 can starts suffering loses after hit 199, while army 2 suffers loses after hit 239 assuming completely even distribution and every soldier fires in a round. Or in terms of rounds Army 1 suffers 11 casualties in round 7 and is completely wiped out in round 9. While army 2 wouldn’t start suffering casualties until round 10 assuming army 1 maintained full strength until then.

You should have another think of how you want damage, health and unit numbers to work together.

One approach could be that damage or firepower is the chance of hit being scored. So a unit with 10 fire power has 10% chance of scoring a hit in a round, a unit with 80 an 80% chance. Health could be the number of hits a unit can take before dying 1 being the standard.

Then you can battles like the following:
Solider – 10 FP, 1 Health
Tank – 40 FP, 2 Health

If Army 1 has 4 soldiers and army 2 has 1 Tank then Army 1 has to score 2 hits to win before army 2 scores 2.

Then scale as large as you want.

100 soldiers and 10 tanks vs 50 tanks and 10 soldiers.

Higher level units either have greater chance of making a hit or can soak more damage or a combination of the 2.
Advertisement
This page will likely give you a starting point.
Quote:
Original post by Gooberius
This page will likely give you a starting point.


I used Lanchester's equations to compare the results of my simulations. I actually spent an hour last night learning how to solve systems of differential equations so I could reduce his equations to closed form A(t)'s and D(t)'s.

Originally, I was going to use his equations for the simulation itself. But after running some tests, I saw that even battles involving tens of thousands of units per army took no time for my server to calculate. So I've decided to only use my solutions to Lanchester's equations as a guide to see how well my shot-per-shot method is distributing its results.

Quote:
Original post by TechnoGoth
Well I suppose one issue with your design is since damage is effectively evenly distributed a larger army can soak far more damage before starting to suffer loses then a smaller one.

Army 1 can starts suffering loses after hit 199, while army 2 suffers loses after hit 239 assuming completely even distribution and every soldier fires in a round. Or in terms of rounds Army 1 suffers 11 casualties in round 7 and is completely wiped out in round 9. While army 2 wouldn’t start suffering casualties until round 10 assuming army 1 maintained full strength until then.

You should have another think of how you want damage, health and unit numbers to work together.

One approach could be that damage or firepower is the chance of hit being scored. So a unit with 10 fire power has 10% chance of scoring a hit in a round, a unit with 80 an 80% chance. Health could be the number of hits a unit can take before dying 1 being the standard.

Then you can battles like the following:
Solider – 10 FP, 1 Health
Tank – 40 FP, 2 Health

If Army 1 has 4 soldiers and army 2 has 1 Tank then Army 1 has to score 2 hits to win before army 2 scores 2.

Then scale as large as you want.

100 soldiers and 10 tanks vs 50 tanks and 10 soldiers.

Higher level units either have greater chance of making a hit or can soak more damage or a combination of the 2.


So in other words, lower the health/damage ratio. I agree. I was talking about how a high health/damage ratio gave superior numbers a huge advantage. In the opposite direction (which is basically equivalent to your suggestion), things work out better.

As for multiple unit types like you said, yep, that's the plan.

I'm still working out a nice simple design so that there is enough variety to provide some depth to army composition, but not so much that it becomes a chore for players to figure out. I'd say the toughest part is making all unit types relevant.

What about turn allocations? Should it go back and forth, be 50/50 each time? Or should one side's chance to fire be in proportion to their army size relative to the sum of both army sizes?
I’d probably have simultaneous rounds. Attacker fires, Defender fires, all casualties are removed.

You could add more depth by adding additional phases to combat for certain units types:

For instance you could have artillery that adjusts combat round as follows:
1 - Defenders Artilleries Fire
2 - Casualties Removed
3 - Attackers Artilleries Fire
4 - Casualties Removed
5 - Remaining Attackers Fires
6 – Remaining Defenders Fire
7 - Casualties Removed

You could of course change that to fit you units and design objectives. Such as having bombers provider first strike capability only on attack and artillery only providing it on defence.

Don’t feel you have to have lots of units with just slightly different stats. Instead think of the roles you want different units to perform and the types of strategies you want to allow.

You might want to have bombing runs for instance in which bombers can launch a single attack against an enemy force with a low. Or allow units with high movement to attack multiple targets in single turn/day.

Infantry might be the back bone of a low income player’s army while tanks are the back bone of higher income player, but supported by another unit type might make infantry more powerful bring them back into use later on.

Advertisement
Quote:
Original post by Gooberius
This page will likely give you a starting point.


Wow that's pretty fascinating, and it confirms what I've been thinking from studying various strategy games.

Quote:
Original post by Beyond_Repair
Quote:
Original post by Gooberius
This page will likely give you a starting point.


Wow that's pretty fascinating, and it confirms what I've been thinking from studying various strategy games.

Lanchester's Laws are really only applicable to Wars of attrition, but as most computer games are prety much wars of attrition anyway... :D


Quote:
Original post by sooner123
I'm designing a browser-based game that will involve battles between large armies.

From the sounds of it, it seems to be a Turn Based Strategy game.

One thing you want to look at is how much control the player has over the combat. If the combat is simple (eg: move Player 1 army to attack player 2 army, give the results once one side is defeated) then you only need a simple system. However, if you want more player involvement (either during or before) in the combat, then you will need a more complex system.

As an example of a more complex system: if the player is going to be able to place their armies in location where they are harder to hit (like bunkers and such), then you need a variable to account for this (basically a "hard to Hit" valriable and have that reduce the chance of a hit (the chance to hit is Accuracy - HardToHit).

Also, will the Army units be able to have armor to reduce the damage of any hits they take? You will need another variable here too (the damage might be DamageDone = AttackDamage - Armor).

Quote:

Is this reasonable for combat (statistically) or would it make more sense for which side fires to be random with probability in proportion to army size?

It would depend on whether you are trying to use Lanchester's Linear Law, or Square Law.

If you are trying to simulate aimed fire (modern warfare style), then you should have the chance to shoot based on the size of the army.

If you are just simulating unaimed fire or hand to hand combat, then the system you ahve will work best.

The reason for this is in hand to hand, each person gets to attack one person or be attacked by one person at a time. With aimed fire, the more units you have, the more fdirepower you can bring to bear on any one target, so the more troops you have the more attacks you should be able to make in a given time.

Another idea you might want to add in is formations. This can be easly handled by setting two variables called "Attack Frontage" and "Defense Frontage".

Attack Frontage is the number of units from that group that can attack, where as the Defense Frontage is the number of units from that group that can be attacked.

You just need to update the frontage amounts each attack round, or the formation is changed.

For example:

A Medieval Pike Formation can attack with several ranks (for the example 2 ranks), so the Attack Frontage is double the width of the formation.

However, you could still only allow the front rank to be killed in an attack, so the Defense Frontage is equal to the width of the formation.

So if the formation is 20 units wide, then only 20 units could be targeted in an attack round. But, as 2 ranks can attack, they can make 40 attacks in an attack round.

Then you can have weapons/unit types that ignore frontage, like an archery unit (or artillery unit) that fire indirectly. Then the Attack Frontage is the whole unit and the Defense Frontage of the targeted unit is also the entire unit (but the defense frontage for the archers would still be dependent on the archer's formation).

If you had these abilities as options for the unit (Direct Fire/Indirtect Fire) then the player has a choice as to which one to use. If Direct Fire was more accurate (and use the Square Law) but was subject to the frontage rules, and Indirect Fire ignored the frontage rules but followed the Linear Law and was less accurate, then you have an interesing tactical choice that the player has to make.

This topic is closed to new replies.

Advertisement