momentary_door blocking ai nodes freezes game, & workaround Created 1 year ago2022-10-04 14:51:37 UTC by kimilil kimilil

Created 1 year ago2022-10-04 14:51:37 UTC by kimilil kimilil

Posted 1 year ago2022-10-04 14:51:37 UTC Post #346933

Problem statement

As I was making my bspguy edits through the entire Half-Life campaign, I hit a perplexing issue: The game freezes on "the" apprehension map (c2a3d). At first I just assume it's a one-off occurrence, but as I revisited the map it's becoming apparent that this is a 100% recurring issue.

After adding -condebug to launch options and observing the qconsole output, it appears that the game is grinding to a halt with an error spam: Unhandled Ent in Path momentary_door. So I searched that string in halflife's github, and it appears to be emitted from the AI node file dlls/nodes.cpp, line 283.

So, the AI system is detecting that the node path is blocked by an entity that it can't handle. It should have handled momentary_door in the same block as func_door but it doesn't.

But then how come this map worked at all in vanilla half-life, but tanks when the same map is in a mod? Not just the map with a minor edit, even the unedited c2a3d tanks it, if it creates a new node graph.

Troubleshooting

My first attempt is to force the mod to use the original node file. I copied the .nod file from valve to <modname> and set it to read only. The problem is that in the mod's grapth folder there are also .nrp files, which is curiously absent from valve's graphs folder. Even when the game can't edit the nod file (it's read only on FS level) it's still creating the nrp file, and seems to be relying on it. It seems to me that the AI system that uses the nod/nrp map combo is causing this problem, as the original game has no nrp files and it works fine.
Also, using the original bsp/nod pair works but that defeats the exercise of me wanting to edit the bsp.

Suspecting that maps saved by bspguy compels the engine to produce this problematic node formats, I resorted to ripent-ing the props I wanted to add (VHLT's). This failed, the problematic graph formats are generated, and the same freeze happens.

My final effort is to edit the momentary doors and make them slightly ajar (16u). That seems to work. I tried to follow up by having a pair of doors, a non-solid shut door, and a solid ajar one, which move in unison; but that failed again. I recalled the code doesn't check if the entity's solid.

I guess I had to have the doors ajar. For folks who has played this game a gazillion times it probably wouldn't matter (if they even noticed this change).

Afterword

The question still remain as to how the vanilla game (vanilla BSP and NOD combo) works when the new bsp/nod/nrp combo doesn't. Both vanilla and my mod is using vanilla code, so it's just something in the old nod file format that prevents this check from failing the way it does with modern formats.

Hope to see solokiller's unified sdk fix this by including momentary_door and/or passable flag to the logic check. I might also raise this issue to valve's github later.
Posted 1 year ago2022-10-04 17:25:30 UTC Post #346934
The problem is that in the mod's grapth folder there are also .nrp files, which is curiously absent from valve's graphs folder. Even when the game can't edit the nod file (it's read only on FS level) it's still creating the nrp file, and seems to be relying on it. It seems to me that the AI system that uses the nod/nrp map combo is causing this problem, as the original game has no nrp files and it works fine.
The NRP file is basically a "report" file (or log if you prefer) giving stats about nodes, links and more. It has no relation to the NOD file containing the actual data and thus can be wiped out when shipping/releasing maps and mods.

As you probably saw when reading the code, you might have noticed that the code assumes that all func_door and func_door_rotating entities are moveable while everything else is static (including func_train, momentary_door and such). This is bad because it causes the situation you described to happen. An approach that requires a test to be validated would be to replace these hardcoded classnames checks by checking if the entity's pev->movetype is something else than MOVETYPE_NONE.
Suspecting that maps saved by bspguy compels the engine to produce this problematic node formats, I resorted to ripent-ing the props I wanted to add (VHLT's). This failed, the problematic graph formats are generated, and the same freeze happens.
The NOD file has a header and one of it's entries is the BSP's CRC checksum at the time the node graph was generated. Since you ripent-ed the BSP, the original CRC checksum is lost and thus a new one is generated (same checksum is used in multiplayer games to make sure the clients have the same map as the server). When the node graph loading code detect that the BSP's CRC checksum is different than the one that was stored while generating the graph, it assumes that the map changed and thus the old node graph is deleted to generate a new one. In other words, you can't use the original NOD file on a modified BSP.
Posted 1 year ago2022-10-04 18:34:06 UTC Post #346936
The NOD file has a header and one of it's entries is the BSP's CRC checksum at the time the node graph was generated. Since you ripent-ed the BSP, the original CRC checksum is lost and thus a new one is generated (same checksum is used in multiplayer games to make sure the clients have the same map as the server). When the node graph loading code detect that the BSP's CRC checksum is different than the one that was stored while generating the graph, it assumes that the map changed and thus the old node graph is deleted to generate a new one.
I highly suspected this to be the case, so I once tried editing on bspguy with the CRC hack enabled. Not sure if it works like it's supposed to, considering node graphs are being regenerated regardless. It probably doesn't.

I also attempted locking the nod file on the filesystem level by setting read-only, but it could be the case that the engine regenerated a new one in memory and use it, only not saving it to file.

The big question still remains...
Posted 1 year ago2022-10-04 20:15:30 UTC Post #346937
The game does have trouble with that code, the log spam can seriously slow down node graph generation. Having developer mode enabled causes it to take much longer due to having to format and print the error message.

But the game does eventually continue, you just have to wait it out.
You must be logged in to post a response.