Skip to content

Fix pen handling for multiple func_breakable_surf skipping glass breaking effect#1716

Merged
Rainyan merged 7 commits intoNeotokyoRebuild:masterfrom
sm90x:bug/shatter-penetrate
Mar 1, 2026
Merged

Fix pen handling for multiple func_breakable_surf skipping glass breaking effect#1716
Rainyan merged 7 commits intoNeotokyoRebuild:masterfrom
sm90x:bug/shatter-penetrate

Conversation

@sm90x
Copy link
Copy Markdown
Contributor

@sm90x sm90x commented Feb 21, 2026

Description

Fix bullet penetration through multiple func_breakable_surf panes.

Two fixes:

  • Proper penetration handling for glass on both sides (glass texture and nodraw texture)
  • Saves the function penetration handling function from stopping too soon and failing to apply shatter effects to glass

Plus I told the ai to not apply any damage reduction with these, but I am not sure what the behavior in the original is. (easily removable if incorrect)

The original fix had some crash happen, I went through the firing range and it didn't crash. I also tested the double shatter multiple times, nothing bad happened.

disclaimer: These changes were authored by AI. I reviewed it best I could, but it's the first time I look at Source(tm) code. The solution makes sense I guess.

AI assisted in finding cause of bug.

Toolchain

  • Linux GCC 10 Sniper 3.0

Linked Issues

@sm90x sm90x force-pushed the bug/shatter-penetrate branch from c2ee1fe to 1bd5807 Compare February 21, 2026 23:42
Rainyan

This comment was marked as off-topic.

@Rainyan

This comment was marked as outdated.

@Rainyan

This comment was marked as outdated.

@sm90x
Copy link
Copy Markdown
Contributor Author

sm90x commented Feb 22, 2026

Thanks! I'll see if I can solve that, or at least make it more like ognt. In all versions very shallow angles fail to draw the decal.

@sunzenshen
Copy link
Copy Markdown
Contributor

sunzenshen commented Feb 22, 2026

While AI generated comments are useful for understanding what the introduced changes were, I would reconsider:

  • Is the code is clean enough to be understandable? Perhaps variable names could be adjusted?
  • Do the comments just repeat what is happening in the code? It may be better to only keep comments that explain the why of the code.

Generally repeating what the code does in the comments eventually leads to a "the map is not the territory" mismatch, and it's a pain for collaborators that aren't using AI to keep comments up to date. And collaborators that are comfortable with AI can just query an agent to research what the code actually does. Excessively verbose comments also potentially confuse humans and can cause AI agents go into a contradiction resolving rabbit hole, so I would learn from such comments but then try to make them more succinct.

@sunzenshen
Copy link
Copy Markdown
Contributor

Also I would generally keep the Description field on topic about what this PR does, and to move the methodology explanations and general commentary in the comments section.

@Rainyan
Copy link
Copy Markdown
Member

Rainyan commented Feb 22, 2026

Here's a test map with 1 unit width windows to the right, and 2 unit windows in the left rows:

ntre_pen_test_map.zip

And some screenshots of the test.

Shooting 1 bullet with the weapon_zr68s at setang 0 90 0; eyeangles:

OGNT

ognt

Penetrates eleven 1 unit panes. So I guess 1*11 < MAX_PENETRATION_DEPTH holds, assuming OGNT used the same constant? This is what we would want.

NTRE branch at commit cbcc3b0 (latest commit before this PR)

ntre_master

Penetrates 1 pane, but then the bullet does appear to traverse through the rest? Or at least the bullet decal is drawn.

This PR at commit 1bd5807 (current latest)

ntre_PR

Goes through them all. Which is a bit unexpected, considering the issues mentioned above with the bullet decal.

Arguably going through all of the panes is still better than what we currently have in the master branch logic, but ideally we'd want the parity behavior.

@sm90x
Copy link
Copy Markdown
Contributor Author

sm90x commented Feb 23, 2026

I've been testing and trying this, I noticed the panes in the dev map don't break if you shoot from the other side, only one glass breaks at a time. Is that a map thing or the fix is doing weird things?

happens in ognt huh

image

@Rainyan
Copy link
Copy Markdown
Member

Rainyan commented Feb 24, 2026

I can't reproduce only 1 pane breaking at a time in OGNT. For NTRE master branch, I am seeing only 1 pane break, regardless of which side it's shot from.

However, I'm also seeing the strange discrepancy in OGNT for the amount of panes penetrated, based on which side of the pane the shot comes from:

ognt_nodraw

In the above screenshot, the left side has the bullet enter from the glass texture side, resulting in 11 panes of 1 unit thickness penetrated (at least for the ZR68S). Whereas penetrating from the nodraw side in the right-hand side row (which has been flipped around) penetrates only 6 panes.

The func_breakable_surf are built such that there is only 1 surface with the glass texture applied, and all others are nodraw. Here's a map with the right-most row of panes flipped around to expose the nodraw side:

nodraw

To my understanding this is the standard way to build a func_breakable_surf, and attempting to apply more than 1 glass surface makes the entity not spawn in the level at all.

I have to assume this is a bug in OGNT, and the intention was to penetrate using the glass surface side's penetration value, so that's probably what we'd wanna go with. Although replicating this weird sidedness would be parity, so I suppose that is also an alternative option.

@Rainyan

This comment was marked as outdated.

@Rainyan

This comment was marked as outdated.

@sm90x

This comment was marked as outdated.

@sm90x sm90x force-pushed the bug/shatter-penetrate branch 3 times, most recently from 6a41e7f to f35e67f Compare February 28, 2026 17:24
…ass surfaces

- prevent the back trace from stopping short due to disappearing glass entity by setting a synthetic fraction value
- resolve the right material pen resist and not defaulting to concrete pen resist when it's a nodraw texture of a glass pane
@sm90x sm90x force-pushed the bug/shatter-penetrate branch from accaacd to 6e955e9 Compare February 28, 2026 17:25
@Rainyan Rainyan self-requested a review February 28, 2026 17:34
@sm90x
Copy link
Copy Markdown
Contributor Author

sm90x commented Feb 28, 2026

Alright after reading this better, the ai code was truly garbo and I rewrote most of it, but I still used it's core fix of faking a fraction value.

Two big issues before the fix:

  • As suggested above, the nodraw was changing expected behavior of the glass. Since it has no defined value for penetration resistance, the code defaulted to concrete pen resistance on any nodraw side of glass (i verified with devmsgs, the material value when shooting from the nodraw side logs as concrete). This caused the reduced penetration.

    • Fixed by forcing the glass pen resistance after determining it's a shatter-able glass surface. Note, I am not sure if I should have taken into account more materials, and there is also shatter-able tiles which I have no idea what that applies to (ep 1?)
    • It checks also for material == CHAR_TEX_CONCRETE so we can get the same behavior from the nodraw side.
  • Because the glass pane disappears when turned into shards, the value of penetrationTrace.fraction after TestPenetrationTrace() is 1.0f and the function shortcuts out because that's the "open air nothing to collide with" case check

    • Fixed by setting the fraction value of the trace to a synthetic value 2.3f, without shortcutting the effect works as expected
    • I used 2.3 because that is the minimum I found to be on parity with OGNT, results in 11 glass panes breaking with ZRC
    • (I accept suggestions to methods to test damage if this is a concern, I tried spawning a target but it didn't work out so well)

Only thing I am not happy with is the bullet holes sometimes refuse to draw when breaking through multiple panes, I couldn't figure that one out.

--

screens (all ntre screns are with fix):

rise test (ntre):
0Rise2Hole_ntre
1Rise2Hole_ntre
2Rise2Hole_ntre

break limit test:
OGNT
rows_ognt

NTRE
rows_ntre

Six with hole
OGNT
sixhole_ognt

NTRE
sixhole_ntre

Ten with no hole:
OGNT
tenNoHole_ognt

NTRE
tenNoHole_ntre

Copy link
Copy Markdown
Member

@Rainyan Rainyan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for continuing to work on this.

This looks good to me for the most part, however I left some notes for things that we should fix before merging. Most importantly the NEO preprocessor guards.


On another note, I noticed that for some guns we don't quite get the same breakable_surf penetration as OGNT. I don't know if it's because OGNT does something completely different for glass penetration, or whether our penetration values are inaccurate, but in either case I think this is good enough for merge and we can revisit later if needed. But for reference, I tested all of the OGNT guns against the 1 unit pane test map, and here are the results:

Using position: setpos 477.541809 -1622.499756 186.031250;setang 0.000000 90.000000 0.000000;

With the test map: https://github.com/user-attachments/files/25472359/ntre_pen_test_map.zip

All guns penetrate 11 panes, except:

weapon n panes broken
aa13 5
supa7 8 (For normal shot. Slug round penetrates 11 panes)
srm_s 9
kyla 9
m41l Untested (gun is disabled in current OGNT)
smac Untested (gun is disabled in current OGNT)

But again, perhaps out of scope for this PR, so I'm not requesting any more changes for the glass pen values.

Comment thread src/game/client/c_func_breakablesurf.cpp Outdated
Comment thread src/game/client/c_func_breakablesurf.cpp Outdated
Comment thread src/game/client/c_func_breakablesurf.cpp
Comment thread src/game/shared/baseentity_shared.cpp
Comment thread src/game/shared/baseentity_shared.cpp Outdated
@sm90x
Copy link
Copy Markdown
Contributor Author

sm90x commented Mar 1, 2026

retested seems ok

@sm90x sm90x force-pushed the bug/shatter-penetrate branch from 5f77626 to be6c79f Compare March 1, 2026 01:41
@Rainyan Rainyan self-requested a review March 1, 2026 02:36
Copy link
Copy Markdown
Member

@Rainyan Rainyan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thank you!

@Rainyan Rainyan requested a review from a team March 1, 2026 02:56
@sm90x
Copy link
Copy Markdown
Contributor Author

sm90x commented Mar 1, 2026

Same, thank you for the map and debugging, it was a huge help.

@Rainyan Rainyan merged commit 239e886 into NeotokyoRebuild:master Mar 1, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bullet penetrating multiple func_breakable_surf should break them all

4 participants