Skip to content

Repository files navigation

BeamCrashFix

Fixes a Counter-Strike 2 server crash caused by beam entities whose parent has been removed.

ModSharp CS2 License Stars


BeamCrashFix is a small, passive ModSharp plugin that stops a server crash: when a CBeam (a beam/laser entity) is parented to another entity that then gets removed, the beam is left with a dangling parent — a parent scene node whose owner entity is gone. The next time the engine computes that beam's world position, it dereferences the missing owner and the server crashes. This plugin detours the responsible engine function and, when it detects that dangling state, safely skips the crashing computation. No commands, no config — install it and the crash stops.

🚀 Install

Copy the build output into your ModSharp install (<sharp> = your sharp directory):

From To
.build/modules/BeamCrashFix.Core/ <sharp>/modules/BeamCrashFix.Core/
.build/modules/BeamCrashFix.Core/.assets/gamedata/beamcrashfix.games.jsonc <sharp>/gamedata/beamcrashfix.games.jsonc

Restart the server (or change map) to load. There is nothing to configure.

🧩 Dependencies

None beyond the base ModSharp framework — the plugin only uses ISharedSystem (the hook manager, gamedata, and entity access). No other plugins, no database, no shared contracts.

🔧 How it works

The crash is the same on both platforms, but the fixable code differs by compiler, so the plugin does the right thing for each and picks the correct one at load:

  • Windows — the two CBeam abs-position setters (SetAbsStartPos / SetAbsEndPos) exist as standalone functions. The plugin detours both and, when GetSceneNode()?.GetParent()?.GetOwner() is null (the dangling state), writes the position directly instead of running the transform that would crash. This is the original fix authored by Kxnrl.
  • Linux — GCC inlines those two setters, so there is no standalone function to hook. The crash itself, however, lives in one generic function: CGameSceneNode's parent-relative abs-transform combine (the point where a parented node's world transform is computed). The plugin detours that one function and, when the node's or its parent's owner pointer is null, skips the recompute. The signature was reverse-engineered from libserver.so.

The guard is fail-safe either way: it only triggers when an owner pointer is null, which is an always-invalid, being-torn-down state — it can never fire for a live, valid entity, and the hook never allocates or throws. Note that the Linux hook sits on a generic transform (it runs for any parented entity, not only beams); the guard's null check means it is still a no-op for everything except the crashing case.

Signatures live in beamcrashfix.games.jsonc (per-platform, resolved lazily for the running OS). If a future CS2 update shifts a signature, the hook simply fails to install and logs it — it never mis-resolves.

📦 Build

dotnet build -c Release

Outputs .build/modules/BeamCrashFix.Core/BeamCrashFix.dll and the bundled beamcrashfix.games.jsonc. Requires the .NET 10 SDK.

🙏 Credits

  • Kxnrl — the original Windows crash-fix and the Windows signatures. Runs his servers on Windows, so the Linux side was never checked.
  • yappershq — reverse-engineered the Linux crash site + signature and packaged the standalone cross-platform plugin.

📄 License

Released under the GNU AGPL-3.0, matching the ModSharp module ecosystem this is built on.


Made with ❤️ by yappershq

⭐ Star this repo if you find it useful!

About

Fixes a CS2 server crash from CBeam entities parented to removed entities (ModSharp). Windows fix by Kxnrl, Linux RE by yappershq.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages