Underrail Forum

Underrail: Infusion => Development Log => Topic started by: Styg on March 10, 2026, 02:14:58 am

Title: Dev Log #16: Targeting and Projectiles
Post by: Styg on March 10, 2026, 02:14:58 am
See nicely formatter HTML version on the website (https://stygiansoftware.com/infusion/devlogs/16-targeting-and-projectiles.html).

Hi guys,

In this dev log I want to go over the changes that I’ve made to the ranged weapon targeting system, which could also be called the projectile attack system.

This is the system that is used primarily when attacking with any sort of projectile-based weapon, such as firearms and crossbows, but also energy and chemical "projectiles."

The reason I made the changes that I’ll describe below is partly to better integrate it into the new engine, with its 3-dimensionality and destructibility. But, also, I wanted to change the way that the difficulty of using these weapons changes with range and skill. Namely, I wanted for these weapons to still retain good effectiveness at close or point-blank ranges even at low skill levels, so they could easily be used without too much investment both in the early game and as off-spec weapons further into a play-through.

(https://stygiansoftware.com/images/devlogs/infusion/16/1.png)

This is how it all works now.

First, in order to be able to fire at any given target, there must be a penetrable path from your firing voxel to one of the voxels occupied by the target—this is called a ranged touch check. In our engine, a voxel is a relatively large cube with the edge length of one meter (so a human takes up two voxels when standing and one when crouched, for example). It’s basically a 3D "tile."

Every object in the game occupies one or more voxels. We use these for low-resolution gameplay mechanics, such as pathfinding and vision. A voxel itself consists of the core, the 6 sides, and 12 edges. These are used to better facilitate smaller or thinner objects such as doors, columns, and such... but that’s not important right now. You only need to remember that the initial range check is done using these.

https://stygiansoftware.com/videos/devlogs/infusion/16/video3.mp4 (https://stygiansoftware.com/videos/devlogs/infusion/16/video3.mp4)

When firing a ranged projectile weapon, such as a pistol, for example, the game first calculates your attack rating. A lot of things can affect this rating, but it’s mainly determined by your effective skill level (Guns skill in this case), stance (in the case of firearms, it means what aiming device you’re using—iron sight, reflex sight, optics, etc.), and focus.

This is measured against the target’s defense rating. I’m not completely set on how this rating is going to be summed up, but for now it’s an esoteric mix of constant values, distance, momentum, and evasion. Basically, the rating grows with how far, how fast, and how evasive the target is.

These two values are then fed into a saturating (diminishing returns) function that determines the maximum degree of aim vector tilt—meaning, by how much the attacker can be off from a perfect shot. When the projectile is about to be launched, the game rolls a random value from this range and uses it to tilt the vector.

This vector is then made into a ray and traced against the bounding box of the target that the attack was aimed at. Let’s call this a primary target check. It actually consists of two checks, as it’s traced against two bounding boxes—the full and the inner bounding box.

If it intersects with the inner bounding box, which typically consists of the inner 2/3 of the full bounding box, the attack is counted as a hit. During this check, all obstacles are ignored, and we rely solely on the ranged touch check to determine if there’s a clear path to the target. When this happens, it’s called a true hit, and it means we don’t need to do any actual ray marching of the projectile through the world space.

If it does not intersect with the inner bounding box, then the projectile is traced through the actual game space, and it can hit any character or destructible or indestructible obstacle in its path.

If it ends up landing inside the full bounding box of the initial target, it will be counted as a grazing hit (which means it deals half the damage). If it lands inside a bounding box of any other target, it can be a hit or a grazing hit depending on if it also intersects with its inner bounding box.

So, unlike in Underrail 1, where only things like bursts or shotgun attacks could cause collateral damage, in Infusion, any projectile you launch can potentially end up hitting a different target or an obstacle.

It is sort of a hybrid system that allows for true hits that do not account for other obstacles and characters if you aim precisely, but in all other cases forces you to adjust for other targets and obstacles.

I found this system to be superior to true physical simulation when it comes to our engine because the player does not have the fine-grained positioning capabilities for either the character or the source of the projectile (the weapon). We do not want to constantly be ending up in silly situations due to some part of the level geometry unexpectedly fully blocking attack paths.

https://stygiansoftware.com/videos/devlogs/infusion/16/video2.mp4 (https://stygiansoftware.com/videos/devlogs/infusion/16/video2.mp4)

Now, because we no longer roll a hit chance during the attack but instead tilt the attack vector, this has a couple of (intended) consequences.

First, the targets that are small and/or far away become naturally harder to hit because for any given vector tilt angle, the gap between the traced ray and the target point increases with the target’s distance; and the smaller the target is, the more likely this is to result in a miss.

So, while you might not need that much Guns skill to hit a burrower when up close, hitting a spawn at 10+ range without significant investment in the said skill could only be the result of a lucky shot.

Secondly, it works seamlessly for any kind of thing that needs to interact with the projectile, be it another character, an obstacle (destructible or otherwise), a cosmetic particle, a cloud of flammable gas, a rip in the spacetime continuum, or whatever else we come up with in the future. As long as it can be detected during the ray marching, we can interact with it.

Finally, we can easily use this system for weapons that fire multiple projectiles, such as shotguns, where each pellet becomes a separate projectile.

https://stygiansoftware.com/videos/devlogs/infusion/16/video1.mp4 (https://stygiansoftware.com/videos/devlogs/infusion/16/video1.mp4)

One downside of the system is that it becomes effectively impossible to calculate exact hit chances for a given attack beforehand. For this reason, as some of you have noticed, I have switched to descriptive difficulty indicators (Easy, Moderate, Hard, etc.).

* * * * * * *
So far I’ve only discussed how the projectile system is used with standard weapon attacks, but it can and will also be used for other things, such as grenade shrapnel, psionic particles, and such. It can be used anywhere where there’s a physical projectile that needs to be traced through the game space while not being affected by gravity or air drag.

* * * * * * *
There are cases where gravity and air drag are significant factors—with thrown weapons, for example, such as throwing knives, grenades, and even simple rocks. For these, I have developed a different system, which I will showcase in a future dev log.

* * * * * * *
Likewise, there’s more to be said about actual damage models of different creatures and how they affect hit chances and damage amounts. This topic deserves a dev log of its own.

* * * * * * *
Obstacles, destructible or otherwise, are also a fitting dev log subject. We actually have quite precise collision mechanisms when it comes to the environment, owing to the fact that we generate low-poly meshes for our pre-rendered assets to be used for shadow maps.

* * * * * * *
Anyway, that’s all for now.

Keep in mind, all these mechanics are subject to further adjustments pending testing, but so far I find this system quite intuitive and fun.

It’s back to the trenches for me now. I hope you found this dev log interesting. Be sure to follow me on X, where I post smaller tidbits of development regularly.

Cheers!

Title: Re: Dev Log #16: Targeting and Projectiles
Post by: Vagabond on March 10, 2026, 04:38:30 am
Dragon Breath rounds confirmed! Yippie!