This is something I've been observing since I started making JSON-made weapons: the only entity in the entire game which takes fall damage is the player. So What I think is to enable fall damage for ground creatures, along with NPCs Not only is it not fun to see them landing perfectly fine like nothing happened instead of having a meaty red soup lying on the ground, it's also quit illogical.
If fall damage is enabled for most other NPCs and monsters, I think an AI rehaul would be also necessary. From what I've experienced, monsters are made so that their pathing doesn't have as much of a worry towards vertical platforming. I would like fall damage for everything. But I wouldn't like to see monsters randomly falling and dying from the mountains on either side of my valley settlement.
I briefly thought about NPCs taking damage as part of a mod (that much would be easy), but yes the AI would need to be redone to account for this so it probably isn't worth it. I've thought about this too. The player takes damage from falling only, but not from high speed collisions in any other direction. Well I know in vanilla you don't usually have that problem... with the 1.0+ techs anyhow. Also the fall damage takes into account gravity, which doesn't really make sense. The gravity accelerates your fall, but it is the speed times mass that accounts for (almost all) of the force of impact. Neither does a static fall height make sense in the calculation(since the actual speed of impact from a fall would be different based upon gravity, aerodynamics). The gravity itself only adds as much force to the impact when colliding as it does when you're standing there. Your own mass provides the inertia. Code: local minimumFallDistance = 14 local fallDistanceDamageFactor = 3 local minimumFallVel = 40 local baseGravity = 80 local gravityDiffFactor = 1 / 30.0 local curYPosition = mcontroller.yPosition() local yPosChange = curYPosition - (self.lastYPosition or curYPosition) if self.fallDistance > minimumFallDistance and -self.lastYVelocity > minimumFallVel and mcontroller.onGround() then local damage = (self.fallDistance - minimumFallDistance) * fallDistanceDamageFactor damage = damage * (1.0 + (world.gravity(mcontroller.position()) - baseGravity) * gravityDiffFactor) damage = damage * status.stat("fallDamageMultiplier") status.applySelfDamageRequest({ damageType = "IgnoresDef", damage = damage, damageSourceKind = "falling", sourceEntityId = entity.id() }) end if mcontroller.yVelocity() < -minimumFallVel and not mcontroller.onGround() then self.fallDistance = self.fallDistance + -yPosChange else self.fallDistance = 0 end self.lastYPosition = curYPosition self.lastYVelocity = mcontroller.yVelocity() You wouldn't really take more damage from a 20mp/h (32.187km/h) collision on a planet that is 2x Earth gravity as compared to Earth. You take just as much damage in an environment lacking gravity(provided what you are colliding with is not going to move/absorb the impact). Let me give you an Code: local pos = mcontroller.position() local mass = mcontroller.mass() local dist = dist(pos, self.last_pos or pos) local deltaSpeed = dist / dt local change = deltaSpeed - (self.last_deltaSpeed or deltaSpeed) local collisionDamage = 0 elseif (change > 0.3) and mcontroller.isColliding() or mcontroller.isNullColliding() then --0.3 is just a numbe I plugged in for example collisionDamage = change * mass elseif (change > 1) and world.liquidAt(pos) then collisionDamage = (change * mass) / 3 --3 is a plugged number here, perhaps swap (change * mass) - ((change * mass) / viscosity ) etc --I don't know the realistic way to calculate off hand but better than nothing end if collisionDamage > (minCollision or 0) then --define this elsewhere, adjust for balance status.applySelfDamageRequest({ damageType = "IgnoresDef", damage = collisionDamage * (collisionMultiplier or 1), --define this elsewhere, adjust for balance damageSourceKind = "collision", sourceEntityId = entity.id() }) end self.last_pos = mcontroller.position() self.last_deltaSpeed = deltaSpeed That code could be made better by considering the hardness of the material you collided with(probably tile "health") and viscosity of liquids, but that's all extra/overkill/OCD. And yes notice that code makes you possibly take collision damage(at higher speeds) from liquid collision too(as you really would). The exact numbers would need tinkered with til it feels right. It could easily be adjusted to not check every update tic, but every 5 tics etc if that is preferable. It might also replace isColliding() with a check for tiles in the collision path based off the previous trajectory... but that might be unacceptably expensive for not much advantage. Now that code does reference this added function(obviously you'd need to add it) Code: function dist(t1, t2) return math.sqrt(((t1[1] - t2[1])^2) + ((t1[2] - t2[2])^2)) end Yeah I know... it is a game and I put too much thought into it, but that's how I think.
Well I mostly wrote that for the devs in case they're reading the thread. That's a code replacement for /stats/player_primary.lua and I expect they could read it just fine Although I don't actually know to what degree that happens. I'm sure they do some reading, but if they spent all day reading these forums, combing over Steam forums, twitter, and reddit... they'd never get anything done. So I figure it is a shot in the dark.