Introduction
Greetings CDDA! I am a long-time lurker and player and a big fan of the project. I am not an experienced enough programmer to tackle 3d ballistics project myself, but I think it is worthwhile for the core developers to take this on and I can offer some organized thoughts on this matter.
I believe the current ballistics system can be greatly improved by removing the current 2d dispersion and a ‘TODO’ for 3d dispersion system in /src/ballistics.cpp and replacing it with a more generalized simulation. I included a bit of math in this document to assist the thought process of whoever ends up pursuing this project.
I propose we simulate initial velocity and mass, character accuracy, mechanical accuracy, gravitational force, atmospheric drag, wind force, terminal ballistic damage and maybe Coriolis wind/force if anybody is willing to tackle that. To support this system, some preliminary work must be done.
Preliminary Work
Implement projectile physics
Ballistic projectiles must travel at a certain speed from the launcher. It is worthwhile to perform calculations on the projectile 10 times in one turn (second), or more depending on how tolerable the lag is. It can even be a world-gen option. We should call this period: ballistic_time_step_size
A projectile should determine whether the fuze conditions will be met within the next calculation period and if so, then work out exactly which tile to strike/activate in.
A player (or later on NPC) will input direction and elevation into the ballistics function and this will result in a projectile leaving the launcher at the direction and elevation the player specified (degrees direction and elevation must be converted into x,y,z component velocities by the function)
A ballistic projectile should have the following parameters specified by its JSON:
- Applicable launcher list
- Mass
- Silhouette Area (from the front)
- Drag Coefficient
- Muzzle Velocity for each launcher (to be split among xyz components by ballistic function)
- Muzzle Energy for each launcher (0.5massvelocity^2)
- Projectile Damage at Muzzle for each launcher (can use existing slash/blunt/pierce system, basically 100% damage at muzzle with fall-off based on terminal speed)
- Mechanical accuracy of the projectile (given in degrees, but displayed to player in MOA, 1MOA~0.0167degrees.)
A launcher should have the following parameters available:
Mechanical accuracy of the launcher (given in degrees but displayed to player in MOA. Ex: rifles have accuracies of 0.5MOA-5MOA)
Math
We should use the following definition of drag:
Drag = (Density of Air * Drag Coefficient * Silhouette Area)/2
Glossary
- a_px, a_py, a_pz = acceleration of projectile in x,y,z direction
- C_d = drag coefficient (0.04 for streamlined object, 0.38 for aerodynamic elongated object and 0.47 for sphere)
- ρ = air density at current elevation (1.225kg/m^3 at sea level, 1.007 at 2km, 0.4135 at 10km)
- A = silhouette area
- m = mass of projectile
- g = gravitational acceleration (9.8 m/s^2) on earth’s surface
- x_p, y_p, z_p = xyz position of projectile at next iteration
- x_0p, y_0p, z_0p = previous iteration’s xyz position of projectile
- v_0x, v_0y, v_0z = the xyz component velocity of projectile at previous iteration
- ballistic_time_step_size = delta time since last iteration (0.1s default provided it doesn’t lag)
Acceleration Equations
a_px =(-0.5C_dρA(v_px+v_wx)^2)/m
a_py =(-0.5C_dρA(v_py+v_wy)^2)/m
a_pz =-g-(0.5C_dρA(v_pz+v_wz)^2)/m
Kinematic Equations
x_p=x_0p+v_0xballistic_time_step_size+0.5a_px^2
y_p=y_0p+v_0yballistic_time_step_size+0.5a_py^2
z_p=z_0p+v_0zballistic_time_step_size+0.5a_pz^2
Initial Velocity
Initial velocity is provided by the projectile’s initial velocity (v_0) and is split into X, Y and Z components by vector math from spherical to cartesian using the compass direction and elevation the character has provided the ballistic function.
v_0x=v_0*sinφcosθ
v_0y=v_0*sinφsinθ
v_0z=v_0*cosφ
- θ=compass direction
- φ=elevation
Limitation: I chose not to specify side silhouette area and side drag coefficient for wind to simplify work for the future.
Create “area target” fire mode
The player should be allowed to fire weapons in four ways:
- On the local map, aim at a selected point target (ex: zombie, cursor) and fire directly at it as players do currently and the program will compensate for projectile drop due to gravity. This will be noticeable for throwing weapons and bows.
- Open the “area target” GUI and select/type a compass direction and gun elevation and fire at it.
- Fire using the “long range point target” option if equipped with a weapon equipped with an optical sight. This should significantly expand the reality bubble of the player in the chosen direction (based on quality/stabilization of optic up to 1500 meters/squares) and allow them to manually enter elevation and windage corrections when they select a tile to shoot at.
- Additionally, if player finds/creates an artillery computer attached to a weapon, they should be allowed to use the ballistics computer GUI and to open the world map and select a certain tile to shoot at or to input the exact coordinates and have the program compensate for most of the forces acting on the projectile.
Virtual Z-Levels
Artillery fire (e.g., catapults, mortars) requires a projectile to travel to z-elevations far in excess of what’s necessary for OVERMAP_HEIGHT for normal gameplay.
Depending on how they are implemented, virtual z-levels can be useful later for aircraft and AAA fire at aircraft. (ex: your aircraft flies at 12km elevation and is at virtual Z-level 6000)
Reality Bubble
The popular flight simulator based on MicroProse Falcon 4 (BMS.) has background simulation (think of dwarf fortress world gen) and then a detailed simulation “reality bubble” for the main aircraft and for all munitions launched from the aircraft. I propose a similar approach for CDDA.
As a ballistic object travels through the CDDA world, it should trigger enemy spawns the same way a player would and if the fuze triggers at a certain position, it should simulate the release of whatever payload it carries.
This system should allow for the sterilization of remote areas from enemies through artillery bombardment.
Dispersion
Launcher Dispersion
Every launcher should have a mechanical dispersion maximum statistic specified in degrees (may be displayed to player in MOA) and every projectile launched from this launcher should roll x_dispersion from -mechanical_dispersion_maximum to mechanical_dispersion_maximum. it should then roll y_dispersion from -mechanical_dispersion_maximum to mechanical_dispersion_maximum and finally roll this for the z component.
Character (player or NPC) Dispersion
- The character’s weapon skill (ex: throwing, bows) and a new “indirect attack” proficiency should be averaged to add x,y,z dispersions from 10 degrees at level 0 to 0 degrees at level 10.
- The launcher’s aiming device should make this easier or harder. If a launcher has no artillery sight, then it should multiply character dispersion by 3.
- If it has a rudimentary sight, then it should multiply it by 2
- If it has a decent artillery sight, then it should multiply it by 1.5
- If it is attached to a ballistic computer, then it should multiply it by 1
Total Dispersion
- character_dispersion_maximum =(applicable_weapon_skill+indirect_attack_proficiency10)/2launcher_aiming_device_modifier)
- character_dispersion_x,y,z= roll from –character_dispersion_maximum to character_dispersion_maximum
- Finally, add both mechanical_dispersion and character_dispersion to the direction and elevation the character provided the ballistic function and use this value to launch the projectile.
GUI and Command Line Parser
There should be a GUI with mouse support where a player can enter gun direction and elevation using dials or the command line parser or use the ballistics computer functions if one is present.
Ex parser commands:
- fire NNW 45
- 350.555 30
- 20 degrees 60 degrees
- 3/4pi pi/2
- directly up
- zenith
Artillery Launcher Examples
- Catapult (standalone or vehicle mounted)
- Trebuchet (standalone or vehicle mounted)
- Large Slingshot (standalone or vehicle mounted)
- Black powder cannon (standalone or vehicle mounted)
- 37-150mm mortars List of infantry mortars - Wikipedia
- Field guns and howitzers
Tangential Suggestions
Drones, Self-Spotting and BDA
Artillery is much more fun when you’re able to see the destruction you’re causing. It can be handled in a realistic manner through the following technologies:
- Remote observation through TV feed from launched projectile if camera and radio are mounted
- Remote observation through camera mounted on terrain/quadcopters/fixed wing drones/robotic vehicles in the area. This will provide additional challenge with multiple reality bubbles since the drones will need one on their own.
Drones are the most effective and realistic method of spotting targets for your own artillery fire. Commercial quadcopter spotting for a mortar is the go-to strategy of the current batch of wars and a game can’t be realistic without simulating this capability.
Terminal Ballistics
There should be some handling for shooting light projectiles out to long distance and the damage caused by such.
The projectile should impact with enough energy (J) and pressure (kPa) to damage the target.
Fuze types
Several methods of activating a payload should exist:
- Impact fuze – the projectile will activate the payload after lightly touching an object/tile. Easy to make.
- Timer fuze – detonates after a set amount of time after arming. Easy to make.
- Delayed impact fuze – the projectile will strike whatever is in its way first and then activate the payload.
- Radio-proximity fuze – the projectile will activate its payload when it reaches 5 tiles distance to an object after a 50-tile arming period
- Pressure mine fuze – creates a mine triggered by something stepping on it/driving over it after it impacts the ground
- Magnetic mine fuze – creates a mine triggered by a metal object passing over it after it impacts the ground
- Command-activated fuze – to be used with a TV-feed and remote to activate the payload on command
Explosives Simulation
I propose we implement a virtual explosive object that will be created prior to detonating an explosive. When a bomb detonates, it should check an inner explosive radius for other bombs and that bomb should check its inner explosive radius for other bombs and this should happen iteratively, and each object should be added to the virtual explosive object. The inner explosive radius should be one third of the actual explosive radius to avoid dealing with weird explosion geometry.
This virtual explosive object should then be treated as a single bomb with the yield of all component bombs. This will allow the player to stack explosives in an area and explode them as a single large bomb.
It can be fun to implement a fuze failure chance to simulate unexploded ordnance (that can then be exploded with additional artillery fire)
It may be fun to simulate explosion velocity and explosion energy for every explosive.
Payloads
Some ideas of payloads that can be activated by the fuze:
- Dummy – does nothing when activated. Strikes everything in the tile it lands in. Has a 30% chance of bouncing forward once but losing 30% of its x and y velocities.
- Explosive – hammer strikes primer when explosive impacts something with enough force and detonates the secondary explosive
- Activatable item – acts as if the player activated it. Must be crafted with a powered microcontroller (with battery) and motor (solenoid.)
- Pressure Mine – creates a pressure plate activated mine upon being activated by the fuze. Anything that steps/drives over it will detonate the mine.
- Magnetic Mine – creates a magnetically activated mine upon being activated by the fuze. Metal objects/subjects (like cyborgs) passing over this mine will detonate it.
Commanding NPC Area Fire
It would be fun for the player to act as a spotter for NPC controlled artillery batteries. It would require implementing radios, radio channels and artillery conversation options where you specify either map coordinates or direction and elevation over the radio channel.
It would also be fun to command a group of NPC soldiers near the player to volley fire their bows/muskets/grenades in a certain direction to bully zombies before the charge into a location.
Weather Simulation
Wind speed can be specified either abstractly or it can be specified by altitudes and locations (ex, wind will blow SSW at 3m/s from 0 to 1000m at these world map tiles, but blow NE at 10m/s from 1000m to 10km at those same world map tiles)
Expanding Point Cloud Type Artillery
It may be fun to simulate grapeshot type projectiles launched from an artillery piece as a constantly expanding cloud that will strike a set of tiles with constantly decreasing probability/damage.
Virtual Projectiles Using Multiple Powder Charges
It’s worth simulating loading a certain quantity of powder charges into the gun (see XM231/XM232 system XM231/XM232 Modular Artillery Charge System (MACS) ) and this process creating a projectile with varying muzzle velocities.
Faction Wars
To provide targets for artillery.