DisfiguredEnemies
Enemies spawn stretched, tinted, and eye-glowing - a wrongness pass applied at runtime, no custom models needed. Same look on every client.
About this mod Author’s original text
DisfiguredEnemies
Makes monsters look wrong, at runtime, with no new models or textures.
Built and compiled against game build v0.4.4 (runs on v0.4.4.x).
What this is and isn't
This is a code-only pass, not new art. It can't give an enemy a different
silhouette, extra limbs, or a genuinely different model — that needs actual
3D/texture work, which is outside what a Harmony patch can do. What it CAN do
generically, on every enemy type without needing per-type knowledge of their
rig or shaders:
- Scale distortion — random resize per spawn. Uniform by default (safe);
optional non-uniform height/width variance for gaunt/squat proportions,
with a real caveat (see below).
- Colour tint — every renderer nudged toward a configurable colour
(sickly dark red by default) via a MaterialPropertyBlock, never the
shared material asset.
- Eye glow — a small point light placed near the top of the enemy's
render bounds. An approximation of glowing eyes, not literal eye geometry.
v1.1.0 — a real bug found in testing
The original non-uniform scale (independent height vs width) could produce
Infinity or NaN floating point numbers... Collider errors. Applying
non-uniform scale to a parent transform whose child colliders are rotated
relative to it can create a shear Unity's physics engine can't invert into a
valid matrix. This isn't theoretical — it showed up in a real session on
Bomb Thrower, Head Grabber, Tumbler, and Head, all enemies this mod resizes.
Default scaling is now uniform — one multiplier applied to all three
axes, which is shear-safe no matter what an enemy's collider rig looks like.
Non-uniform is still available via NonUniformScale = true if you want the
gaunt/squat variation, with that risk understood.
The multiplayer problem this had to solve
Each client renders its own copy of an enemy's visuals — only position and
state are network-synced, not the renderer graph. So if the distortion were
randomized independently per client, every player would see a DIFFERENT
disfigurement on the same monster, which would look like a bug, not a
feature.
Fixed by seeding the randomness from Enemy.PhotonView.ViewID — a value
Photon guarantees is identical for a given enemy on every machine. Same seed
in, same stretch/tint/glow out, everywhere, with no custom networking needed.
Works with the rest of this suite unmodified.
Config
BepInEx/config/benjamin.disfiguredenemies.cfg
| Section | Key | Default | Notes |
|---|---|---|---|
| Scale | ScaleDistortion | true | |
| | MinStretch / MaxStretch | 1.0 / 1.35 | Overall size multiplier range |
| | MinSquash / MaxSquash | 0.85 / 1.15 | Width/depth range, only used if NonUniformScale is on |
| | NonUniformScale | false | Independent height/width — see the collider-shear caveat above |
| Tint | ColorTint | true | |
| | TintColor | dark red | |
| | TintStrength | 0.35 | 0 = none, 1 = fully replaced |
| EyeGlow | EyeGlow | true | |
| | GlowColor | red | |
| | GlowIntensity / GlowRange | 1.4 / 1.2 | Kept small so it reads as eyes, not a lamp |
| Debug | Verbose | false | Logs every roll per enemy |
Set MinStretch = MaxStretch = 1.0 (etc.) to disable a specific effect's
variance while leaving the others on.
Worth knowing
- Every renderer on every enemy gets a real Light component if EyeGlow is
on. Shadows are forced off specifically to keep this cheap — a level with
many enemies means many small lights, and shadow-casting lights are the
expensive part.
- The tint touches _Color and _BaseColor — the two names covering the
vast majority of built-in and URP/Standard-derived shaders. An enemy using
neither simply ignores the unused property; this doesn't error, it just
won't visibly tint that specific one.
- Distortion is deterministic per enemy per level (same ViewID = same look
every time within that spawn), not per-frame — an enemy doesn't wobble or
change shape while alive, only differs from other enemies of the same type.
Building
Requires.NET SDK 8.0+. Add the NuGet feeds in nuget.c
Install & use Install: BepInEx plugin
- The archive from playbuff is the mod itself — usually a BepInEx plugin (a .dll or a plugin folder once unzipped).
- Recommended: use a community mod manager (such as r2modman) — pick this game, import the mod, and the manager sets up BepInEx and its dependencies for you.
- Manual route: install the BepInEx loader in the game folder, then drop the unzipped .dll or plugin folder into BepInEx/plugins/.
- Launch the game — the BepInEx console logs every plugin it loads; seeing this mod in the log means it is installed.
Mods with listed dependencies need those installed too, or they will not load. Options are usually changed in-game or in the plugin's config file.
Install these first, or the mod will not work: