diff --git a/binaries/data/mods/public/globalscripts/Templates.js b/binaries/data/mods/public/globalscripts/Templates.js
index a9e46fc..30d36d1 100644
--- a/binaries/data/mods/public/globalscripts/Templates.js
+++ b/binaries/data/mods/public/globalscripts/Templates.js
@@ -187,7 +187,8 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, damag
 				ret.attack[type] = {
 					"minRange": getAttackStat("MinRange"),
 					"maxRange": getAttackStat("MaxRange"),
-					"elevationBonus": getAttackStat("ElevationBonus")
+					"elevationBonus": getAttackStat("ElevationBonus"),
+					"spread": getAttackStat("Spread")
 				};
 				for (let damageType of damageTypes.GetTypes())
 					ret.attack[type][damageType] = getAttackStat(damageType);
diff --git a/binaries/data/mods/public/gui/common/tooltips.js b/binaries/data/mods/public/gui/common/tooltips.js
index e907c62..b6da3dc 100644
--- a/binaries/data/mods/public/gui/common/tooltips.js
+++ b/binaries/data/mods/public/gui/common/tooltips.js
@@ -24,15 +24,15 @@ var g_SplashDamageTypes = {
 var g_RangeTooltipString = {
 	"relative": {
 		// Translation: For example: Ranged Attack: 12.0 Pierce, Range: 2 to 10 (+2) meters, Interval: 3 arrows / 2 seconds
-		"minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(minRange)s to %(maxRange)s (%(relativeRange)s) %(rangeUnit)s, %(rate)s"),
+		"minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(minRange)s to %(maxRange)s (%(relativeRange)s) %(rangeUnit)s, %(rate)s, %(spread)s"),
 		// Translation: For example: Ranged Attack: 12.0 Pierce, Range: 10 (+2) meters, Interval: 3 arrows / 2 seconds
-		"no-minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(maxRange)s (%(relativeRange)s) %(rangeUnit)s, %(rate)s"),
+		"no-minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(maxRange)s (%(relativeRange)s) %(rangeUnit)s, %(rate)s, %(spread)s"),
 	},
 	"non-relative": {
 		// Translation: For example: Ranged Attack: 12.0 Pierce, Range: 2 to 10 meters, Interval: 3 arrows / 2 seconds
-		"minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(minRange)s to %(maxRange)s %(rangeUnit)s, %(rate)s"),
+		"minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(minRange)s to %(maxRange)s %(rangeUnit)s, %(rate)s, %(spread)s"),
 		// Translation: For example: Ranged Attack: 12.0 Pierce, Range: 10 meters, Interval: 3 arrows / 2 seconds
-		"no-minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(maxRange)s %(rangeUnit)s, %(rate)s"),
+		"no-minRange": translate("%(attackLabel)s %(damageTypes)s, %(rangeLabel)s %(maxRange)s %(rangeUnit)s, %(rate)s, %(spread)s"),
 	}
 };
 
@@ -284,6 +284,7 @@ function getAttackTooltip(template)
 		let maxRange = Math.round(template.attack[type].maxRange);
 		let realRange = template.attack[type].elevationAdaptedRange;
 		let relativeRange = realRange ? Math.round(realRange - maxRange) : 0;
+		let spread = +template.attack[type].spread;
 
 		tooltips.push(sprintf(g_RangeTooltipString[relativeRange ? "relative" : "non-relative"][minRange ? "minRange" : "no-minRange"], {
 			"attackLabel": attackLabel,
@@ -298,6 +299,12 @@ function getAttackTooltip(template)
 					translate("meters") :
 					translatePlural("meter", "meters", maxRange)),
 			"rate": rate,
+			"spread": sprintf(translate("%(label)s %(val)s %(unit)s at %(range)s"), {
+				"label": headerFont(translate("Spread Hit Radius:")),
+				"val": spread,
+				"unit": unitFont(translatePlural("meter", "meters", spread)),
+				"range": sprintf("%(range)s %(unit)s", { "range": maxRange, "unit": translatePlural("meter", "meters", maxRange) })
+			})
 		}));
 	}
 	return tooltips.join("\n");
diff --git a/binaries/data/mods/public/simulation/components/Attack.js b/binaries/data/mods/public/simulation/components/Attack.js
index b048152..69259a6 100644
--- a/binaries/data/mods/public/simulation/components/Attack.js
+++ b/binaries/data/mods/public/simulation/components/Attack.js
@@ -440,6 +440,15 @@ Attack.prototype.GetAttackStrengths = function(type)
 	return ret;
 };
 
+Attack.prototype.GetSpread = function(type)
+{
+    if (type != "Ranged" || !this.template[type])
+        return 0;
+
+	let spread = +this.template[type].Spread;
+	return ApplyValueModificationsToEntity("Attack/" + type + "/Spread", spread, this.entity);
+}
+
 Attack.prototype.GetSplashDamage = function(type)
 {
 	if (!this.template[type].Splash)
@@ -513,8 +522,8 @@ Attack.prototype.PerformAttack = function(type, target)
 		let predictedPosition = (timeToTarget !== false) ? Vector3D.mult(targetVelocity, timeToTarget).add(targetPosition) : targetPosition;
 
 		// Add inaccuracy based on spread.
-		let distanceModifiedSpread = ApplyValueModificationsToEntity("Attack/Ranged/Spread", +this.template.Ranged.Spread, this.entity) *
-			predictedPosition.horizDistanceTo(selfPosition) / 100;
+		// let distanceModifiedSpread = ApplyValueModificationsToEntity("Attack/Ranged/Spread", +this.template.Ranged.Spread, this.entity) *
+		let distanceModifiedSpread = this.GetSpread(type) * predictedPosition.horizDistanceTo(selfPosition) / 100;
 
 		let randNorm = randomNormal2D();
 		let offsetX = randNorm[0] * distanceModifiedSpread;
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
index b0d8007..eb04f6a 100644
--- a/binaries/data/mods/public/simulation/components/GuiInterface.js
+++ b/binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -389,6 +389,7 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
 		for (let type of types)
 		{
 			ret.attack[type] = cmpAttack.GetAttackStrengths(type);
+			ret.attack[type].spread = cmpAttack.GetSpread(type);
 			ret.attack[type].splash = cmpAttack.GetSplashDamage(type);
 
 			let range = cmpAttack.GetRange(type);
