Author Topic: [Rejected] "NuCom" cover mechanics  (Read 7452 times)

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
[Rejected] "NuCom" cover mechanics
« on: February 02, 2020, 02:26:45 am »
Rejection reason: this is beyond/outside the scope of OXCE


Hello, I have made a fork of the most recent OXCE release which should implement cover.

https://github.com/InfuriatedBrute/OpenXcom

All the code  is "done", but it is completely untested and uncompiled. But there's no harm in announcing early...? Not sure if this is the right forum either.

It works as follows:

  • If no mods manually enable its features, it will not do anything.
  • If a unit shoots and hits another unit, and the attacker's weapon has ignoreCover = false, and the defender has takesCover = true, then the projectile has a %chance equal to the (unused) LightCover value on the MCD of the corresponding wall adjacent to the defender to hit that wall instead. Even though it otherwise would hit the defender.
  • The AI accounts for this by considering enemies against which it has cover less of a threat when deciding where to flee to, and by preferring flanking shots.
  • UFOextender also accounts for this by adjusting the shown accuracy value.

Known problems are as follows:

  • When cover works, it will look like the unit was hit because the projectile is adjusted at the moment it is hit. I often find it difficult to see whether a unit was hit anyways, so maybe there should be a way to display text saying whether it was hit or not?
  • UFOextender accuracy always considers the cover value, even if the target cannot take cover. Arguably this is good.
  • The AI will prefer cover, but that remains true even if you could easily flank it. The logic for changing this would be pretty complicated and it might be hard to tune how close should be considered a distance at  which the player could "easily flank" the AI. Also I simply forgot to do this.
  • It's difficult to enable. You have to set almost every unit to takeCover and almost every weapon to not ignoreCover. Then you have to adjust all wall MCDs to their appropriate cover values.
  • It does not consider elevation (z-values). Arguably good.
« Last Edit: February 19, 2023, 01:44:15 pm by Meridian »

Offline Meridian

  • Global Moderator
  • Commander
  • *****
  • Posts: 9091
    • View Profile
Re: Light cover fork
« Reply #1 on: February 02, 2020, 02:34:03 am »
Hello, I have made a fork of the most recent OXCE release which should implement cover.

Just FYI, you have made a fork of OXC, not OXCE.

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #2 on: February 02, 2020, 03:24:55 am »
Hm. That will take some work to fix I guess.

Will this maybe get accepted into mainline OXCE if I fix/finish it? And even if it does, will people use it?

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: Light cover fork
« Reply #3 on: February 02, 2020, 02:48:52 pm »
I do not think that arbitrary altering bullet trajectory is good thing, it look more like force shield that catch incoming bullet than hitting obstacle.

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #4 on: February 02, 2020, 06:23:57 pm »
Yankes, I can implement the other more "realistic" method of cover which you implicitly mention and I call "Realphyzek" if you want. Basically just make the deviation more of a spectrum from 0-150 instead of that sudden jump from 10 deviation when you roll a hit to 50 when you roll a miss.

However I would need a formula for efficiently predicting accuracy considering cover. Right now all I can think of for Realphyzek accuracy prediction is simulation by shooting 10-1000 rays and seeing what hits each time the player/AI asks for a prediction. I don't understand the projectile math in calculateTrajectory/applyAccuracy enough to figure it out mathematically; part of that code says "don't ask" so I would really need your help.


TLDR: give me an accuracy prediction formula that considers realistic cover and I will implement realistic cover.


I have seen a graphic that shows the spread so a formula probably exists...?

Alternatively I could work on making it "not look like a force shield", but that's not what I would prefer.
« Last Edit: February 02, 2020, 06:45:40 pm by Bobit »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: Light cover fork
« Reply #5 on: February 02, 2020, 08:10:49 pm »
In not currently working as realistic as possible? If there clean LOF then unit can be hit, if not, object will be hit. If unit is only partially covered, this mean something is in between then some hits hit cover and some could hit unit. This mechanic could have some tweaks and improvement but basic premise is sound. Adding artificial roll that cause miss is neither of this two.

Thinks that could improve current mechanic:
a) Allow AI to kneel
b) Teach AI to avoid obstacles when shooting, and use them when moving
c) Maybe allow better targeting to not shooting into mass center of target

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #6 on: February 02, 2020, 09:43:24 pm »
Yankes, plz keep responding. What I want to do is b)Teach AI to avoid obstacles when shooting and maybe when moving. It is my opinion that the best way to do this is the following:

  • When in setupEscape(), the AI will consider enemy units against which it has cover as only a fraction of a spotter.
  • When in findFirePoint(), the AI will prefer not to shoot at targets it is unlikely to hit.
  • For the player's convenience, UFOextender accuracy should show the chance that the shot will actually hit. Otherwise, a realistic partial cover system will just be confusing as you have no idea how good cover is.

I consider all three elements of this essential to a decent realistic partial cover system. They are all fairly easy to implement, but in all three I am missing one key component: a function which determines a shot's actual chance to hit. The key is surely in applyAccuracy(), but I don't understand the math in applyAccuracy(), so that's where I need your help. I can implement everything else and give you the tools to balance it further.

Imo vanilla hit deviation isn't big enough for partial cover to matter (do some tests in debug mode if you like), and that's why the AI works well without understanding partial cover at all: it doesn't matter. But vanilla should stay vanilla. Which is why I also suggest allowing modders to add hit deviation between 10-50, but that is a secondary concern and pretty trivial to implement, albeit possibly difficult to balance.

------------------------------------------------------------------------------------------------------------------------------------------

The difficulty of that final component is the main reason I originally went with the "artificial" method. If the function is impossible to implement, I would like to resume my work on the "artificial" method, because having artificial cover is better than the vanilla approach of having almost no partial cover. At least as a modding option, assuming it doesn't cause glitches in the engine. However that won't mean much if it's a separate fork that never gets updated while the main branch gets all the updates, so I won't do it unless there's a chance it will be merged into the main branch.Also keep in mind that the "artificial" method is used by FiraxisCOM and Xenonauts, but the "realistic" method has only successfully been implemented by Phoenix Point. 96COM  and by extension OpenXCOM does not really have partial cover, so it gets away without the AI knowing about it. So if you can't implement the "realistic" method of accuracy prediction, please support my attempt to implement the "artificial" method by merging it once it is complete (if it is not buggy).
« Last Edit: February 02, 2020, 10:07:37 pm by Bobit »

Offline Rubber Cannonball

  • Colonel
  • ****
  • Posts: 195
    • View Profile
Re: Light cover fork
« Reply #7 on: February 03, 2020, 12:06:15 am »
Wow, this looks like a hard and complicated task.

Consider a unit kneeled behind a low stone wall on a vanilla farm map.  The wall provides maybe 35% cover for a flat trajectory plasma rifle shot.  The wall provides maybe 20% cover for a medium range arcing bow shot.  The wall provides 0% cover for a grenade aimed one tile behind the kneeled unit.

The biggest danger to the ai unit is being seen or having been seen.  Another big danger is moving into motion scanner range.  Another big danger is being near a mysterious cloud of smoke that just popped up last turn.  The player has many ways of eliminating cover as a factor if he suspects an ai unit is behind it.

Just my thoughts for what its worth.  Good luck!

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #8 on: February 03, 2020, 01:34:24 am »
Rubber, I agree in general. I did implement two things to counteract some of your concerns: certain weapons like grenades cause the AI to ignore cover, and cover is only considered when escaping into cover or firing at enemies in cover. It could be a complex problem, idk because I don't know the math, or we can just simulate it 1000 times every time the want to shoot if that somehow doesn't lag. It is a LOT simpler if using the "artificial" method I already implemented, but that method won't get much support among the project leads.

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: Light cover fork
« Reply #9 on: February 03, 2020, 11:22:50 pm »
Yankes, plz keep responding. What I want to do is b)Teach AI to avoid obstacles when shooting and maybe when moving. It is my opinion that the best way to do this is the following:

  • When in setupEscape(), the AI will consider enemy units against which it has cover as only a fraction of a spotter.
  • When in findFirePoint(), the AI will prefer not to shoot at targets it is unlikely to hit.
  • For the player's convenience, UFOextender accuracy should show the chance that the shot will actually hit. Otherwise, a realistic partial cover system will just be confusing as you have no idea how good cover is.

I consider all three elements of this essential to a decent realistic partial cover system. They are all fairly easy to implement, but in all three I am missing one key component: a function which determines a shot's actual chance to hit. The key is surely in applyAccuracy(), but I don't understand the math in applyAccuracy(), so that's where I need your help. I can implement everything else and give you the tools to balance it further.

Imo vanilla hit deviation isn't big enough for partial cover to matter (do some tests in debug mode if you like), and that's why the AI works well without understanding partial cover at all: it doesn't matter. But vanilla should stay vanilla. Which is why I also suggest allowing modders to add hit deviation between 10-50, but that is a secondary concern and pretty trivial to implement, albeit possibly difficult to balance.

------------------------------------------------------------------------------------------------------------------------------------------

The difficulty of that final component is the main reason I originally went with the "artificial" method. If the function is impossible to implement, I would like to resume my work on the "artificial" method, because having artificial cover is better than the vanilla approach of having almost no partial cover. At least as a modding option, assuming it doesn't cause glitches in the engine. However that won't mean much if it's a separate fork that never gets updated while the main branch gets all the updates, so I won't do it unless there's a chance it will be merged into the main branch.Also keep in mind that the "artificial" method is used by FiraxisCOM and Xenonauts, but the "realistic" method has only successfully been implemented by Phoenix Point. 96COM  and by extension OpenXCOM does not really have partial cover, so it gets away without the AI knowing about it. So if you can't implement the "realistic" method of accuracy prediction, please support my attempt to implement the "artificial" method by merging it once it is complete (if it is not buggy).
First of all, cover in OXC is multi layer, not only that you stay behind but every thing in between. Each object "cast shadow" that can protect you from some of attacks. And this is realistic and it now working, to make AI aware of this do not need adding any "artificial" logic to fix it. You need:
a) Calculate it (using montecarlo methods, probably hard and will require refactor to cache voxels in some hierarchical structure)
b) Approximate it (each object and wall have predefined "shoot difficulty" and your ask AI to choose easy shoots). You can add this info to UI too. And this will not affect in any way result of shoot. This could be simple number of filled voxel in tile.

Overall neither I or Meridian are interested in "realistic cover", improving current functionalities ok, subverting them no.

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #10 on: February 04, 2020, 02:58:53 am »
Ignore the artificial thing then. Correct me if I'm wrong, but you seem interested in adding the approximation function, which is good for vanilla. If you do that, "subverting the functions" would be as simple as letting modders change the (accuracyRoll->deviation) formula, so not much reason not to do it.
« Last Edit: February 04, 2020, 03:07:59 am by Bobit »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: Light cover fork
« Reply #11 on: February 04, 2020, 08:29:50 pm »
Ignore the artificial thing then. Correct me if I'm wrong, but you seem interested in adding the approximation function, which is good for vanilla. If you do that, "subverting the functions" would be as simple as letting modders change the (accuracyRoll->deviation) formula, so not much reason not to do it.
Could you rephrase what you mean? Because I have feeling that we speak about something different.

My stance is that NO change will be made to shoot accuracy or any mechanic in it. Only add helper function that will calculate approximate of real accuracy of given shoot.

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #12 on: February 04, 2020, 09:27:59 pm »
The helper function is 90% of what I want.

I suggest using the helper function in setupEscape() (AI prefers to escape to partially obscured positions), in findFirePoint() (AI prefers not to shoot at enemies which are partially obscured), and player UFOextender accuracy prediction. But you can probably figure that out yourself, so ignore this paragraph if you don't understand it.

However, I suspect that the helper function will tell you that partial cover is awkward in vanilla. This is because of the code in src/Battlescape/Projectile/applyAccuracy(), the way in which accuracy is converted to deviation on lines 411-416, means that only the cover in the very small 10 deviation cone when you roll a hit has any impact.  The few times that the 10 deviation cone is partially obscured, it's likely to obscure it by something like 50%.

This is why I suggest allowing modders control over the formula used in lines 411-422. The modders could do things like:

  • Make rolled misses always miss (no 100% hit chance with a sniper rifle point blank range), by changing lines 420-422 to have 40 guaranteed deviation when missing, rather than possibly having 0 deviation.
  • Make rolled hits always hit (and partial cover is totally ignored) by decreasing hit deviation on line 416 to 0.
  • Make partial cover more relevant and less binary by setting hit deviation on line 416 to 20, or to 10-50 depending on how high your roll was.

Also, a helper function which shows hit chance considering cover is good. But a helper function which shows hit chance considering cover, the fact that rolled misses sometimes hit in close range, and the fact that rolled hits sometimes miss because the target is so small or the shooter so far away, would be the best. But probably too hard to code.

If you still don't understand what I'm saying, and still want to, we could schedule a live text chat.
« Last Edit: February 04, 2020, 09:45:18 pm by Bobit »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: Light cover fork
« Reply #13 on: February 04, 2020, 10:16:52 pm »
  • Make rolled misses always miss (no 100% hit chance with a sniper rifle point blank range), by changing lines 420-422 to have 40 guaranteed deviation when missing, rather than possibly having 0 deviation.
  • Make rolled hits always hit (and partial cover is totally ignored) by decreasing hit deviation on line 416 to 0.
  • Make partial cover more relevant and less binary by setting hit deviation on line 416 to 20, or to 10-50 depending on how high your roll was.

Looking on this code of this function I could rewrite it in may way, but none of them would include any thing from this list. This is things that I do not like and I do not want be added to OXCE. This go in opposite direction that should it go. Even as modder option is not worth it as all new code add cost do codebase.

Offline Bobit

  • Colonel
  • ****
  • Posts: 186
    • View Profile
Re: Light cover fork
« Reply #14 on: February 05, 2020, 01:59:43 am »
Just let modders control the global variable on line 416. No extra formulas, they can just give a flat value for the integer. That's sufficient.