pixelsmokefx
Real low-poly 3D smoke on every bullet hit - no particles, no assets, generated at runtime. Your shots always render; enemy shots only on-screen within 200 m. One DLL for BepInEx 5.x.Pixel Smoke Fx
Low-poly 3D smoke for bullet hits in Ravenfield (EA29+). Zero particles, zero assets, zero external files - the smoke mesh is generated at runtime inside the plugin.
Built for BepInEx 5.x on Ravenfield EA29 and newer (Unity 2020.3-era builds; verified on EA35).
What it does
Every bullet hit (non-explosive weapons) leaves a burst of three round low-poly smoke puffs that expand fast, shrink exponentially, and fade to nothing - pure code, no particle systems, no texture files. Since v1.1.0 the puffs are damage-sized (sniper hits billow big, shotgun pellets stay tiny) and styled as a black anime/soot cloud: smooth round profile (subdivision-3 icosphere, gentle displacement), per-face vertex colors baked in three discrete brightness bands (bright top / mid / dark bottom - classic cel shading), no flat black silhouette.
hit -> SpawnDecal hook -> pool slot (no Instantiate/Destroy churn)
-> icosphere mesh (generated once, shared by all slots)
-> damage -> size factor (clamped) -> expand (0.04 -> 1.0 in 0.15s)
-> exp shrink -> alpha fade -> back to pool
Key behaviors
| Behavior | Default | cfg key |
|---|---|---|
| Master switch | on | [General] Enabled |
| Player shots render ALWAYS (no distance/frustum culling for your own fire) | on | [General] AlwaysRenderPlayer |
| Other shots render only when on screen | - | frustum culling |
| Other shots render only when closer than 200 m | 200 m | [Performance] HalfDist |
| Full size under 60 m, half size beyond | 60 m | [Performance] FullDist |
| Pool slots (concurrent smoke cap) | 120 | [Performance] PoolSize |
| Same-gun burst window (all shotgun pellets render) | 0.08 s | [Performance] BurstWindow |
| Min gap between bursts (global / per gun) | 0.005 / 0.02 s | [Performance] GlobalCooldown / GunCooldown |
| Blob lifetime | 1.5 s | [Performance] Lifetime |
| Expand window / shrink rate / master size | 0.15 / 2.2 / 0.7 | [Fx] ExpandTime / DecayRate / BaseScale |
| Damage that maps to size factor 1.0 | 40 | [Fx] DamageRef |
| Min / max damage size factor | 0.5 / 1.5 | [Fx] MinSizeFactor / MaxSizeFactor |
| Low-damage pellet floor (shotguns) | 0.25 | [Fx] ShotgunFactor |
Why it's fast
- No particles: one static mesh per puff (1280 triangles, flat-shaded), shared across all slots.
- Pooled: objects are reused, nothing is Instantiate/Destroyed per hit.
- Culled early: off-screen non-player shots skip before any work; renderers outside the frustum skip per-frame pushes.
- Zero garbage: cached components, cached reflection, zero allocation hot path.
- 360 renderers absolute worst case (120 slots x 3 puffs) - trivial for this engine.
Requirements
- Ravenfield EA29+ (any Unity 2020.3-era build; verified on EA35, Steam or standalone)
- BepInEx 5.x (install to
<game>/BepInEx/)
Installation
- Install BepInEx 5.x into the Ravenfield folder if you have not already (run the game once so BepInEx creates its folders).
- Copy
PixelSmokeFx.dllinto<game>/BepInEx/plugins/. - Launch the game. The plugin logs
Pixel Smoke Fx: harmony hook CONFIRMEDon first boot.
(Folder structure: see INSTALL.txt in the same zip.)
Configuration
All settings live in BepInEx/config/com.local.pixelsmokefx.cfg (auto-created on first boot).
| Section | Option | Meaning |
|---|---|---|
| General | Enabled |
master switch |
| General | TargetWeapon |
only weapons whose name contains this substring; empty = all non-explosive guns |
| General | AlwaysRenderPlayer |
shots fired by YOU always render, regardless of distance inside viewport |
| Performance | PoolSize |
concurrent-smoke cap (down for old PCs, up for long battles) |
| Performance | GlobalCooldown |
min seconds between any two bursts (same-burst hits bypass) |
| Performance | GunCooldown |
min seconds between bursts of the same weapon |
| Performance | BurstWindow |
hits from one weapon within this window count as ONE shot and all render (shotgun-friendly) |
| Performance | FullDist / HalfDist |
size LOD + far cutoff for non-player shots |
| Performance | Lifetime |
seconds each smoke lasts |
| Fx | ExpandTime / DecayRate / BaseScale |
animation feel + master size |
| Fx | DamageRef |
projectile damage that maps to size factor 1.0 (= the old rifle baseline) |
| Fx | MinSizeFactor / MaxSizeFactor |
smallest/largest damage size factor |
| Fx | ShotgunFactor |
floor for low-damage pellets (shotgun bursts stay subtle) |
| Testing | AutoTest |
boot-time visual self-test (writes screenshots to BepInEx/PixelSmokeFxTest/) |
Out-of-range values are silently clamped; corrupted values automatically fall back to defaults (the plugin never crashes the game).
Uninstall
Delete BepInEx/plugins/PixelSmokeFx.dll (+ optionally the cfg). No files outside BepInEx are ever touched.
Compatibility / notes
- No code conflicts: single Harmony prefix on
Projectile::SpawnDecal; everything else is static reflection, pooled, and fail-safe (any mismatch logs a warning and degrades gracefully). - No config conflicts: plugin GUID
com.local.pixelsmokefx. - No 3rd-party dependencies beyond BepInEx + Harmony (both bundled with BepInEx).
- Explosion-type projectiles are skipped on purpose - their own FX remains untouched.
Build from source (optional)
build.ps1 compiles PixelSmokeFx.cs with the system csc (C# 5). Requires the game's BepInEx/core + Ravenfield_Data/Managed references (script resolves them automatically).
License
Free to use, modify, redistribute. No warranty. Not affiliated with SteelRaven7.
