Ships Config Guidelines – Arma 3
Intro
101 - How to set up a ship for Arma 3
What's the difference between a boat and a ship? Well, a ship is usually large enough to carry a boat. Subs are also called boats, regardless of size. :)
For Arma purposes, lets call boats anything shorter than 60m (the apparent geo lod limit of Arma) and ships over 60m. Subs are subs!
There are 2 approaches to ships and boats in Arma 3. Typically boats are modelled and implemented as "vehicles" where as ships historically have been implemented as "static" objects.
A few very brave modders have attempted to mix the two. USS Iowa (mod by AusSnipe73) - http://www.armaholic.com/page.php?id=27109 - defines a ship vehicle but then attaches many different static objects and turrets to the ship to build out a 270m long vessel.
Similar efforts have been used to attempt to get a driveable LHD (from Arma 2).
Please be aware of our Arma 3 modding license: http://community.bistudio.com/wiki/Arma_3_Modding_License
Comparison to A2/OA ships
- PhysX support (ShipX, SubmarineX)
- Improved penetration materials
- More detailed Fire Geometry LODs
- Improved tweakability of HitPoints LODs
Model requirements {p3d}
General
The behavior of the ship in the water does not depend anymore on the LandContact points, but on the GEO and PHYSX LODs. The PHYSx LOD seems to represent the water displacement of the ship. If you put too much mass (a value over the displacement) the ship sinks. The PHYSx LOD must be similar in form and size, to the ship's hull. It must also follow the Geometry LOD rules (closed and convex) and must be composed of only one component (that's what BIS says in the VSB2 editing wiki)
GEO is very important. It has given me a lot of problems. You must balance the mass in all axis (plural axes?) and keep the weight down so the ship doesn't turn and sinks. In subs it is specially important because it controls how it moves once submerged and how it maintains depth.
LODs (included in Arma 3 boat p3ds)
- Fire Geo
- View Geo
- HitPoints
- Land Contact
- Memory
- Physx
- Bouyancy
- Geo
- View Cargo
- View Pilot
- View Gunner
- Resolution LODs 1-8
- ShadowVolume 0, 10, 1000, 1010
- A new PhysX LOD
- There needs to be a lod (4e13) consisting of convex components as simple as possible.
- Requires the latest Arma 3 Tools to binarize
- This lod should contain ship’s hull, and ...
- There needs to be a lod (4e13) consisting of convex components as simple as possible.
- Bouyancy LOD
- Memory LOD
- See Model.cfg for a list of memory points
Model config changes {model.cfg}
- Example from the Armed Speed Boat in Arma 3:
class cfgSkeletons { class Default { isDiscrete = 1; skeletonInherit = ""; skeletonBones[] = {}; }; class Boat_Armed_01_hmg_F : default { SkeletonBones[]= { "damagehide", "", "rearturret", "damagehide", "reargun", "damagehide", "drivewheel", "damagehide", "otocvez", "", "otochlaven", "otocvez", "commanderview", "otochlaven", "zasleh_gmg", "otochlaven", "volant", "", "radar", "", "kompas", "", "fuel", "", "mph", "", "rpm", "", "amps", "", "oil", "", "trim", "", "tmp", "", "volt", "", "otocvez2", "", "otochlaven2", "otocvez2", "otochlaven2_shake", "otochlaven2", "z_gatlingr", "otochlaven2_shake", "recoil", "otochlaven2", "bolt", "recoil", "gunnerview2", "otochlaven2", "magazine", "otochlaven2", "ammo_belt2", "magazine", "bullet006", "ammo_belt2", "bullet005", "bullet006", "bullet004", "bullet005", "bullet003", "bullet004", "bullet002", "bullet003", "bullet001", "bullet002", "zasleh2", "otochlaven2", "otochlaven2_static", "otocvez2", "positionlights", "" }; }; }; class CfgModels { class Default { sections[] = {}; sectionsInherit=""; skeletonName = ""; }; class Boat_Armed_01_hmg_F:Default { skeletonName="Boat_Armed_01_hmg_F"; sections[]= { "otochlaven", "otochlaven2", "engine", "p svetlo", "camo", "camo2", "camo3", "zbytek" }; /*potential axis= otochlaven otocvez2 otochlaven2 magazine recoil2 damagehide otochlaven2_shake engine karoserie p svetlo konec hlavne usti hlavne recoilhlaven_axis osahlavne osaveze2 konec hlavne2 usti hlavne2 eye2 osahlavne2 bolt_axis2 marker_light1 magazine2 gunnerview2 pilot2 ammo_belt_axis2 drivewheel_axis watereffectl watereffectr engineeffectl engineeffectr pos driver pos driver dir pos cargo pos cargo dir pos gunner pos gunner dir commanderview mph_axis rpm_axis tmp_axis amps_axis volt_axis oil_axis fuel_axis trim_axis marker_light2 pip0_pos pip0_dir pip3_pos pip3_dir pip2_pos pip2_dir konec p svetla machinegun_eject_pos machinegun_eject_dir positionlight_red_1_pos positionlight_green_1_pos slingloadcargox slingloadcargo1 slingloadcargo2 slingloadcargo3 slingloadcargo4 slingloadcargo5 slingloadcargo6 otocvez drivewheel mph rpm tmp amps volt oil fuel trim recoil camo camo2 camo3 zbytek zasleh2 zasleh_gmg positionlights bolt bullet001 bullet002 bullet003 bullet004 bullet005 bullet006 ammo_belt2 */ class Animations { class Damagehide { type="hide"; source="damage"; selection="damagehide"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 1.0; // unHideValue = -1.0;//(default) animPeriod = 0.0; initPhase = 0.0; }; class Barrel_recoil { type="translation"; source="ReloadAnim"; selection="recoil"; axis="recoil_axis";//*probably* sourceAddress = mirror; minValue = 0.0;//rad 0.0 maxValue = 0.5;//rad 28.64789 offset0 = 0.0; offset1 = -0.05; animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class Bolt_recoil { type="translation"; source="ReloadAnim"; selection="bolt"; axis="bolt_axis";//*probably* sourceAddress = mirror; minValue = 0.0;//rad 0.0 maxValue = 0.5;//rad 28.64789 offset0 = 0.0; offset1 = -0.25; animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class Turret_shake { type="translation"; source="ReloadAnim"; selection="otochlaven2_shake"; axis="otochlaven2_shake_axis";//*probably* sourceAddress = mirror; minValue = 0.0;//rad 0.0 maxValue = -0.2;//rad -11.459156 offset0 = 0.0; offset1 = 0.2; animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class Turret_shake_aside { type="translation"; source="ReloadAnim"; selection="otochlaven2_shake"; axis="otochlaven2_shake_axis";//*probably* sourceAddress = mirror; minValue = 0.0;//rad 0.0 maxValue = 0.65;//rad 37.242256 offset0 = 0.0; offset1 = 0.2; animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class Magazine_hide { type="hide"; source="reloadMagazine"; selection="magazine"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 0.28; unHideValue = 0.72; animPeriod = 0.0; initPhase = 0.0; }; class MainTurret { type="rotationY"; source="mainTurret"; selection="otocvez"; axis="otocvez_axis";//*probably* // sourceAddress = clamp;// (default) minValue = -6.2831855;//rad -360.0 maxValue = 6.2831855;//rad 360.0 angle0 = -6.2831855;//rad -360.0; angle1 = 6.2831855;//rad 360.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class DamageHideOtocVez { type="hide"; source="damage"; selection="otocvez"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 1.0; // unHideValue = -1.0;//(default) animPeriod = 0.0; initPhase = 0.0; }; class MainGun { type="rotationX"; source="mainGun"; selection="otochlaven"; axis="otochlaven_axis";//*probably* // sourceAddress = clamp;// (default) minValue = -6.2831855;//rad -360.0 maxValue = 6.2831855;//rad 360.0 angle0 = -6.2831855;//rad -360.0; angle1 = 6.2831855;//rad 360.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class DamageHideOtocHlaven { type="hide"; source="damage"; selection="otochlaven"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 1.0; // unHideValue = -1.0;//(default) animPeriod = 0.0; initPhase = 0.0; }; class RearTurret { type="rotationY"; source="rearTurret"; selection="otocvez2"; axis="otocvez2_axis";//*probably* // sourceAddress = clamp;// (default) minValue = -6.2831855;//rad -360.0 maxValue = 6.2831855;//rad 360.0 angle0 = -6.2831855;//rad -360.0; angle1 = 6.2831855;//rad 360.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class RearGun { type="rotationX"; source="RearGun"; selection="otochlaven2"; axis="otochlaven2_axis";//*probably* // sourceAddress = clamp;// (default) minValue = -6.2831855;//rad -360.0 maxValue = 6.2831855;//rad 360.0 angle0 = -6.2831855;//rad -360.0; angle1 = 6.2831855;//rad 360.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class muzzleFlash { type="hide"; source="muzzle_source"; selection="zasleh_gmg"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 0.0; unHideValue = 0.1; animPeriod = 0.0; initPhase = 0.0; }; class zaslehROT { type="rotationZ"; source="muzzle_source_rot"; selection="zasleh_gmg"; axis="zasleh_gmg_axis";//*probably* sourceAddress = loop; minValue = 0.0;//rad 0.0 maxValue = 4.0;//rad 229.18312 angle0 = 0.0;//rad 0.0; angle1 = 6.2831855;//rad 360.0; animPeriod = 1.4013e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class muzzleFlash2 { type="hide"; source="muzzle2_source"; selection="zasleh2"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 0.0; unHideValue = 0.8; animPeriod = 0.0; initPhase = 0.0; }; class zasleh2ROT { type="rotationZ"; source="muzzle2_source_rot"; selection="zasleh2"; axis="zasleh2_axis";//*probably* sourceAddress = loop; minValue = 0.0;//rad 0.0 maxValue = 4.0;//rad 229.18312 angle0 = 0.0;//rad 0.0; angle1 = 6.2831855;//rad 360.0; animPeriod = 1.4013e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class fuel { type="rotation"; source="fuel"; selection="fuel"; axis="fuel_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = 0.5235988;//rad 30.0; angle1 = -0.5235988;//rad -30.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class mph { type="rotation"; source="speed"; selection="mph"; axis="mph_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 2.0;//rad 114.59156 maxValue = 25.0;//rad 1432.3945 angle0 = 2.7925267;//rad 160.0; angle1 = -2.7925267;//rad -160.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class rpm { type="rotation"; source="rpm"; selection="rpm"; axis="rpm_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = 2.7925267;//rad 160.0; angle1 = -2.7925267;//rad -160.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class amps_random { type="rotation"; source="rpm"; selection="amps"; axis="amps_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = 0.17453292;//rad 10.0; angle1 = -0.17453292;//rad -10.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class oil_random { type="rotation"; source="rpm"; selection="oil"; axis="oil_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = -0.17453292;//rad -10.0; angle1 = 0.17453292;//rad 10.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class trim_random { type="rotation"; source="speed"; selection="trim"; axis="trim_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = 0.08726646;//rad 5.0; angle1 = -0.08726646;//rad -5.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class tmp_random { type="rotation"; source="rpm"; selection="tmp"; axis="tmp_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = -0.08726646;//rad -5.0; angle1 = 0.08726646;//rad 5.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class volt_random { type="rotation"; source="speed"; selection="volt"; axis="volt_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 angle0 = 0.2617994;//rad 15.0; angle1 = -0.2617994;//rad -15.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class DrivingWheel { type="rotation"; source="drivingWheel"; selection="drivewheel"; axis="drivewheel_axis";//*probably* // sourceAddress = clamp;// (default) minValue = -1.0;//rad -57.29578 maxValue = 1.0;//rad 57.29578 angle0 = 2.000147;//rad 114.59999; angle1 = -2.000147;//rad -114.59999; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class Ammo_Belt_2_Rotation_prep { type="translation"; source="ReloadAnim"; selection="ammo_belt2"; axis="ammo_belt2_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 0.0001;//rad 0.005729578 offset0 = -1.0; offset1 = 0.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class Ammo_Belt_2_Rotation_main { type="translation"; source="ReloadAnim"; selection="ammo_belt2"; axis="ammo_belt2_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.3;//rad 17.188734 maxValue = 0.999;//rad 57.238483 offset0 = 0.0; offset1 = -1.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class Ammobelt_Hide { type="hide"; source="reloadMagazine"; selection="ammo_belt2"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 0.09; unHideValue = 1.0; animPeriod = 0.0; initPhase = 0.0; }; class Bullet001_2_Hide { type="hide"; source="revolving"; selection="bullet001"; sourceAddress = mirror; minValue = -1.0;//rad -57.29578 maxValue = 0.0;//rad 0.0 hideValue = 0.975; // unHideValue = -1.0;//(default) animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; }; class Bullet002_2_Hide { type="hide"; source="revolving"; selection="bullet002"; sourceAddress = mirror; minValue = -1.0;//rad -57.29578 maxValue = 0.0;//rad 0.0 hideValue = 0.98; // unHideValue = -1.0;//(default) animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; }; class Bullet003_2_Hide { type="hide"; source="revolving"; selection="bullet003"; sourceAddress = mirror; minValue = -1.0;//rad -57.29578 maxValue = 0.0;//rad 0.0 hideValue = 0.985; // unHideValue = -1.0;//(default) animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; }; class Bullet004_2_Hide { type="hide"; source="revolving"; selection="bullet004"; sourceAddress = mirror; minValue = -1.0;//rad -57.29578 maxValue = 0.0;//rad 0.0 hideValue = 0.99; // unHideValue = -1.0;//(default) animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; }; class Bullet005_2_Hide { type="hide"; source="revolving"; selection="bullet005"; sourceAddress = mirror; minValue = -1.0;//rad -57.29578 maxValue = 0.0;//rad 0.0 hideValue = 0.995; // unHideValue = -1.0;//(default) animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; }; class Bullet006_2_Hide { type="hide"; source="revolving"; selection="bullet006"; sourceAddress = mirror; minValue = -1.0;//rad -57.29578 maxValue = 0.0;//rad 0.0 hideValue = 1.0; // unHideValue = -1.0;//(default) animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; }; class Muzzle1_shake { type="translation"; source="ReloadAnim"; selection="recoil"; axis="recoil_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.85;//rad 48.701412 maxValue = 1.0;//rad 57.29578 offset0 = -1.0; offset1 = 0.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class Muzzle1_shake_back { type="translation"; source="ReloadAnim"; selection="recoil"; axis="recoil_axis";//*probably* // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 0.85;//rad 48.701412 offset0 = 0.0; offset1 = -1.0; animPeriod = 0.0; initPhase = 0.0; // memory = true;//(default assumed) }; class Bolt_move_2 { type="translation"; source="ReloadAnim"; selection="bolt"; axis="bolt_axis";//*probably* sourceAddress = mirror; minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 offset0 = 0.0; offset1 = 0.5; animPeriod = 2.8026e-045/*#DEN*/; initPhase = 0.0; // memory = true;//(default assumed) }; class PositionLights { type="hide"; source="collisionLights"; selection="positionlights"; // sourceAddress = clamp;// (default) minValue = 0.0;//rad 0.0 maxValue = 1.0;//rad 57.29578 hideValue = 0.0; unHideValue = 1.0; animPeriod = 0.0; initPhase = 0.0; }; };//Animations };//modelclass };//CfgModels
About shipX and submarineX
New config parameters {config.cpp}
Base class is Ship. There are 4 child classes FloatingStructure_F, Ship_F, SmallShip and BigShip.
FloatingStructure_F uses simulation ShipX.
Submarine_01_F inherits from FloatingStructure_F but is defined as vehicleClass="submerged" and does not appear to be implemented as a "vehicle".
C_Boat_Civil_04_F inherits from FloatingStructure_F is defined as vehicleClass="submerged" and does appear to be implemented as a "vehicle" but you cannot interact with it (get in etc).
Boat_F inherits from Ship_F and is the basis of most of the "boats" in Arma 3.
Boat_Armed_01_base_F inherits from Boat_F and uses simulation shipX.
Boat_Civil_01_base_F inherits from Boat_F and uses simulation shipX.
Rubber_duck_base_F inherits from Boat_F and uses simulation shipX.
SDV_01_base_F inherits from Boat_F and uses simulation submarineX.
SDV_01_base_F is used as the basis for all SDVs in Arma 3.
Basic parameters
Key noted items from Boat_Armed_01_base_F
radarType = 8; steerAheadSimul = 0.5; steerAheadPlan = 0.35; predictTurnPlan = 0.8; predictTurnSimul = 0.6; brakeDistance = 5; acceleration = 15; turnCoef = 0.75; maxSpeed = 75; simulation = "shipx"; waterLeakiness = 55.5; waterLinearDampingCoefY = 5; waterLinearDampingCoefX = 2; waterAngularDampingCoef = 1.2; waterResistanceCoef = 0.015; rudderForceCoef = 0.3; rudderForceCoefAtMaxSpeed = 0.02; waterEffectSpeed = 5; engineEffectSpeed = 5; waterFastEffectSpeed = 28;
Engine parameters
Key noted items from Boat_Armed_01_base_F
thrustDelay = 0.2; overSpeedBrakeCoef = 0.2; enginePower = 1085; engineShiftY = -0.1; idleRpm = 200; redRpm = 1200; class complexGearbox { GearboxRatios[] = {"R1",-0.782,"N",0,"D1",2,"D2",1.85,"D3",1.75}; TransmissionRatios[] = {"High",1}; gearBoxMode = "auto"; moveOffGear = 1; driveString = "D"; neutralString = "N"; reverseString = "R"; };
Comparison with USS Iowa (mod by AusSnipe73)
Inherits from Ship_F
radarType = 4; simulation = "shipx"; maxSpeed = 61; overSpeedBrakeCoef = 0.8; enginePower = 1580000; engineShiftY = 0.0; waterLeakiness = 1000.0; turnCoef = 1000.0; thrustDelay = 20; waterLinearDampingCoefY = 2; waterLinearDampingCoefX = 200.0; waterAngularDampingCoef = 1.2; waterResistanceCoef = 0.2; rudderForceCoef = 1000.0; rudderForceCoefAtMaxSpeed = 400.0; idleRpm = 500; redRpm = 1200; brakeDistance = 3; supplyRadius = 3; precision = 15; steerAheadSimul = 0.5; steerAheadPlan = 0.35; predictTurnPlan = 0.8; predictTurnSimul = 0.6; class complexGearbox { GearboxRatios[] = {"R1",-0.782,"N",0,"D1",2.0,"D2",1.85,"D3",1.75}; TransmissionRatios[] = {"High",1.0}; gearBoxMode = "auto"; moveOffGear = 1; driveString = "D"; neutralString = "N"; reverseString = "R"; };
Submarine and Ship Config Detail
Collins class submarine that uses submarinex simulation class:
http://www.freeuploadsite.com/uploads/13725721431.rar
There you have a working example.
Now, for the config:
The behaviour of the ship in the water does not depend anymore on the Landcontact points, but on the GEO and PHYSX LODs. The PHYSx LOD seems to represent the water displacement of the ship. If you put too much mass (a value over the displacement) the ship sinks. The PHYSx LOD must be similar in form and size, to the ship's hull. It must also follow the Geometry LOD rules (closed and convex) and must be composed of only one component (that's what BIS says in the VSB2 editing wiki)
GEO is very important. It has given me a lot of problems. You must balance the mass in all axis (plural axes? ) and keep the weight down so the ship doesn't turn and sinks. In subs it is specially important because it controls how it moves once submerged and how it mantains depth
Code:
airCapacity = 1209600;
Quite important for submarines. Determines the time the crew inside the ship can be below the surface before dying suffocated for lack of air. It seems that when using class submarinex, the engine sets the crew as if they were below the water
Code:
verticalTurnCoef = 20.2;
This line seems to control the speed for ascending/descending.
Code:
waterSpeedFactor = 3.0;
No idea of what this does. I have tried a couple of values and I haven't seen changes
Code:
periscopeDepth = 15.5;
This is the depth the sub mantains when you activate the "Mantain periscope Depth" Action. It is important to know that for big models (not a SDV sized submarine) that this depth DOES NOT coincide with the depth marker in the left upper corner of the screen
Code:
idleRpm = 1000;
Selfexplaining
Code:
redRpm = 4000;
Idem
Code:
thrustDelay = 2;
Delay after we start executing a movement and the ship/submarine starts the actual movement
Code:
simulation = "submarinex";
simulation = "shipx"; PHYSx simulation classes
Code:
overSpeedBrakeCoef = 0.8;
Brake effectivity. If you follow VBS 2 explanations, this value is (overSpeedBrakeCoef*enginePower). The higher the value, the better it brakes
Code:
enginePower = 3278;
Engine power in HPs
Code:
engineShiftY = 2;
This lines tells where the engine applies the force related to the origin of the model. Esentially what one mus calculat is the distance in the vertical axis between the Y value of center of mass of the model and the Y Value of the propeller, waterjet or whaterver moves the shipcuando pegamos un acelerón y valores positivos que se hunda. Negative values tend to make the bow rise when you accelerate and positive values tend to make it dive
Code:
waterLeakiness = 1000;
This parameter determines the quantity of water (M^3 x S) that will fill the volume of the PHYSx LOD per second. Tipically lower vaues for boats, higher for bigger ships. Modifies the sinking rate of a ship when this suffers damage.
Code:
waterResistanceCoef = 0.01;
Represents the resistance if the hull. The higher the value the higher the resistance. This affects acceleration and maximum speed.
Code:
waterLinearDampingCoefX = 10.0;
This value represents lateral movements produced by waves. Higher values will make the ship corner better and slide less to the sides.
Code:
waterLinearDampingCoefY = 1.2;
This one represents vertical movements depending on the waves. Higher values will modify how much the ship sinks/goes down depending on the waves. It can also affect the flotation line mantaining the ame Ship mass. Higher values will also make a ship sink slower
Code:
waterAngularDampingCoef = 8.0;
Smooth the angular movement in all axis, higher values will reduce swinging/swaying, but may cause strange behavior in turns/rolling over waves.
Code:
rudderForceCoef = 12; rudderForceCoefAtMaxSpeed = 15;
How the rudder works. The higher the value the more the ship will turn, BUT the more it will incline when turning. Values to high could even make a ship turn upside down (and sink) when turning. If you are transporting non scripted vehicles the can easily fall if this value is set too high.
There are two values. The first one is for low speed (usually ships turn better when sailing faster than a certain speed) and the second one when going at MEDIUM or FAST speed.
Code:
memoryPointsLeftWaterEffect = "waterEffectR"; memoryPointsRightWaterEffect = "waterEffectL"; memoryPointsLeftEngineEffect = "EngineEffectL"; memoryPointsRightEngineEffect = "EngineEffectR";
These are points in the memory LOD that represent the spawning points for water particle FX. The first ones represent bow FX, the last ones represent the foam generated by the engine propeller
Config for SDV in Arma 3
Inherits from Boat_F
radarType = 8; verticalTurnCoef = 0.05; turnCoef = 0.5; steerAheadSimul = 0.5; steerAheadPlan = 0.35; predictTurnPlan = 0.8; predictTurnSimul = 0.6; brakeDistance = 25; acceleration = 15; maxSpeed = 30; waterSpeedFactor = 1; periscopeDepth = 1.2; idleRpm = 200; redRpm = 1200; thrustDelay = 2; formationX = 15; formationZ = 15; simulation = "submarinex"; overSpeedBrakeCoef = 0.8; enginePower = 45; engineShiftY = 0.4; waterLeakiness = 0; waterResistanceCoef = 0.015; waterLinearDampingCoefX = 2; waterLinearDampingCoefY = 0.8; waterAngularDampingCoef = 1; rudderForceCoef = 0.2; rudderForceCoefAtMaxSpeed = 0.05;
Damage handling
Boats/Ships offer differing protection levels for themselves and crew inside, depending on place you hit them. Balancing damage is usually most time-consuming task for armored vehicles.
Basic config
armor = 30; class Damage { tex[] = {}; mat[] = {"A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_ext.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_ext_damage.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_ext_destruct.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_int.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_int_damage.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_int_destruct.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_ctrls.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_ctrls_damage.rvmat","A3\boat_F\Boat_Armed_01\data\Boat_Armed_01_ctrls_destruct.rvmat","A3\Static_F_Gamma\data\staticturret_01.rvmat","A3\Static_F_Gamma\data\StaticTurret_01_damage.rvmat","A3\Static_F_Gamma\data\StaticTurret_01_destruct.rvmat","A3\Static_F_Gamma\data\staticturret_02.rvmat","A3\Static_F_Gamma\data\StaticTurret_02_damage.rvmat","A3\Static_F_Gamma\data\StaticTurret_02_destruct.rvmat","a3\boat_f\Boat_Armed_01\data\Minigun.rvmat","A3\boat_f\Boat_Armed_01\data\Minigun_damage.rvmat","A3\boat_f\Boat_Armed_01\data\Minigun_destruct.rvmat","a3\boat_f\Boat_Armed_01\data\Minigun_Boat_Armed_01_add.rvmat","A3\boat_f\Boat_Armed_01\data\Minigun_Boat_Armed_01_add_damage.rvmat","A3\boat_f\Boat_Armed_01\data\Minigun_Boat_Armed_01_add_destruct.rvmat","a3\Data_F\Vehicles\Turret.rvmat","A3\Data_F\Vehicles\Turret_damage.rvmat","A3\Data_F\Vehicles\Turret_destruct.rvmat"}; };
Armour plates setup
Hitpoints
Hitpoints represent weak points in structure of ships: turret servos, ammo storages, engine. They can also improve internal penetration handling.
Example from Boat_Armed_01_base_F
class HitPoints { class HitBody { armor = 0.7; material = 50; name = "karoserie"; visual = "zbytek"; passThrough = 1; }; class HitEngine { armor = 0.12; material = -1; name = "Engine"; visual = ""; passThrough = 1; }; class HitTurret { armor = 0.7; material = -1; name = "otochlaven"; visual = "otochlaven"; passThrough = 1; }; };
Hitpoint categories
There are 3 common hitpoint categories in Arma 3's vehicles:
- HitHull, handling internal penetration - when damaged over 0.9, vehicle will explode.
- HitEngine, handling damage of engine
Turrets have their own class HitPoints, coontaining info about how easy it is to damage given turret:
- HitTurret, horizontal rotation
- HitGun, vertical rotation - this should handle any event that renders tank guns inoperable, f.e. hit to servos
New attributes
Hitpoints gained two important config attributes in Arma 3:
- radius, defining size of “hitpoint sphere” around each vertice in Hit Points LOD assigned to given hitpoint’s selection
- explosionShielding, multiplying damage inflicted by indirect damage. The smaller it is, the less damage hitpoint will receive.
Internal damage
Internal damage is handled by HitHull class. When KE round penetrates the armor plates, it passes the damage to HitHull hitpoints array as seen in example model. The hitpoint vertices are set up in such way that the nearest distance between them equals RADIUS attribute in HitHull class, and they cannot be activated by rounds that fail to penetrate armor.
During implementation of internal damage handling it is important to tweak following attributes:
- armor
- explosionShielding
- radius
If the results of config tweaking are not satisfying, consider adding greater detail to Hit Points and Fire Geometry LODs.