So you've got a scene that chugs. Frame times spike every time a particle hits a reflective surface. You heard that 'render pipeline simplification' could cut your draw calls in half — but every tutorial assumes you're building from scratch. Here's the thing: stripping down an existing pipeline is a different beast than designing a lightweight one from the start. I've seen teams cut too many passes and lose their shadows entirely, or merge shader stages and introduce artifacts that take weeks to chase.
This article assumes you've already got something running, even if it's slow. We'll cover who actually benefits from simplification (hint: not everyone), what setup you need before touching the render graph, and the exact steps to reduce complexity without rewriting your whole renderer. No fluff, no magic — just the trade-offs and gotchas I've collected from shipping on console and mobile.
Who Actually Needs This and What Goes Wrong Without It
Indie teams shipping on older GPUs
If you're targeting the Steam hardware survey's long tail—GTX 1060s, RX 580s, the occasional Intel UHD laptop chip—your render pipeline has already betrayed you. I've watched indie teams ship gorgeous scenes on their RTX 3080s only to discover the deferred shading path crushes bandwidth on a mobile GTX. What goes wrong first is transparent: the G-buffer pass, written for flexibility, eats 12ms per frame on a card that has 16ms total. The rest of the frame starves. Shadows flicker. Post-processing gets dropped mid-effect. The game doesn't crash—it just feels wrong. That hurts more than a crash, because players refund games that feel wrong.
Most teams skip this: they optimize shaders first. Wrong order. The pipeline pass itself—the way you tile the screen, the number of render targets, the order of lighting—is where you lose whole milliseconds in chunks. One indie horror project we fixed was running six render passes for a single flashlight. Sane? No. But the tools encouraged it. When we collapsed the pipeline to two passes, the game jumped from 28fps to 55fps on a 1050 Ti. No quality loss—just stripped the redundant. That's the fix nobody tries because they're hunting for expensive single-line micro-optimizations instead.
Mobile developers fighting thermal throttling
Mobile rendering is a war of attrition, and you're losing before the battery hits 40%. The failure mode here isn't frame rate—it's the phone deciding your game is too hot and slashing the GPU clock mid-session. One moment you're at 60fps, the next you're limping at 20. Users don't see a thermal graph; they see lag and blame you.
'We optimized every pixel shader until the phone still throttled. Turned out the real killer was the compute pre-pass nobody profiled.'
— lead engineer on a match-3 game that shed 40% of its heat budget by removing one G-buffer target
What breaks first under thermal load is the frame time variance. A pipeline with too many passes might survive a cold start, but after ten minutes the clock drops, and suddenly your 20ms frame stretches to 33ms. The fix? Strip render targets until you only write what the shader actually uses. I've seen mobile builds carry four MRT outputs when two would suffice—the extra bytes flush the tile cache, which burns power. That's the silent killer: not raw shader complexity, but memory bandwidth wasted per pixel. Thermal throttling is your hardware begging you to simplify.
VR/AR projects with tight frame budgets
VR has no budget slack—11ms per eye, or the user vomits. AR passes through a phone camera feed and must composite in under 5ms. What usually breaks first is the opaque pipeline order: you render the main scene, then the transparent pass, then the UI, then a separate post-effect. That's four repaints of the same pixels. Wrong approach.
The catch is that VR/AR engines default to desktop pipeline templates. They don't ask "do you need a separate depth prepass and a shadow map render and a reflection probe update every frame?" They assume you do. That assumption costs you 3–4ms per eye. One AR project I consulted on was compositing the camera frame twice—once for the scene, once for occlusion queries—until we merged those into a single pass. That saved 2.3ms. Not glamorous. But those 2.3ms are the difference between a headset that feels snappy and one that gives users a headache. The pipeline isn't broken until you put the headset on. Then you know.
What to Settle Before You Touch the Pipeline
Know your target hardware's shader model
You would not tune a dirt bike for the autobahn, yet I see teams optimizing their render pipeline without locking down the actual GPU family they're shipping to. That hurts. The shader model version—be it SM 5.0 for older consoles or SM 6.6 for modern PC—dictates which instructions the hardware can actually execute. Strip a compute-based skinning pass meant for SM 6.0 and you might accidentally force the engine to fall back to a CPU path nobody tested. The catch is that many engines (Unity's URP, Godot's Forward+) silently emulate missing features, which hides the perf cost until you profile on real silicon. So settle this first: pick your shader model floor, then any pass that relies on features above that floor must be flagged as a dependency, not a candidate for removal. Wrong order here means you simplify a path that never runs on target—wasted effort.
Profile your current bottleneck: CPU or GPU?
Most teams skip this. They stare at a frame-time spike, assume it's the renderer, and start merging passes or culling draw calls. Nine times out of ten the actual bottleneck is the CPU submitting too many batches—or the GPU stalling on bandwidth. How do you know? Capture a GPU trace (RenderDoc, Xcode Metal Debugger) and a CPU profiler overlap in the same scene. Look for the longest bar: if the GPU wait is under 2ms but the main-thread Present call sits at 14ms, ripping out a lighting pass won't fix your frame time—you need to reduce draw-call counts instead. I have fixed a project where the team spent two weeks merging shader variants only to discover the bottleneck was a single camera callback re-uploading textures every frame. Profile first, cut second. That sounds obvious, yet I see the reverse every few months.
Not every performance checklist earns its ink.
The tricky bit is that some tools show average frame time, not the heavy tail. A single camera cut or a LOD crossfade can spike the GPU for 3–4 frames, which makes your average look decent while the actual gameplay hitches. So profile under load—run the game at 60 FPS cap, let it warm up, then capture the worst 5% of frames. Those are the frames your players feel. If the bottleneck shifts between CPU and GPU depending on scene complexity (it will), you need a decision rule: simplify for the bottleneck that appears in your most common level, not the tech-demo corridor.
Lock your render feature set—no feature creep
Nothing kills a pipeline simplification faster than the team adding "one more effect" mid-refactor. A junior dev decides the character needs a second cascaded shadow map for the cape physics. Suddenly you can't drop the shadow-pass merge you planned because the new feature relies on it. Feature creep turns a two-week cleanup into a six-month integration spiral. The fix is brutal but necessary: freeze the feature list two sprints before you touch the pipeline. Write down exactly which effects must work—GBuffer writes, depth prepass, transparent sorting, decals, post-blur—and explicitly mark anything beyond that as "opt-in post-refactor". If a producer pushes for a new volumetric fog half-way through, say no. Or defer it to the next optimization cycle.
"We tried to simplify the pipeline while adding a new water shader. The water needed a separate reflection pass. The reflection pass broke the batching we just rebuilt. Three weeks lost."
— Lead engineer, a mobile RPG studio, internal post-mortem
That's the reality: scope creep and pipeline surgery don't mix. Lock the feature set in a shared doc. Sign off as a team. Then touch nothing but the passes you planned to strip.
Core Workflow: Stripping Passes Without Losing Quality
Start with the frame debugger – identify redundant passes
Open your frame debugger before you touch a single shader file. I have watched teams spend three days rewriting a shadow system only to discover the engine was double-drawing the same depth prepass — once for forward rendering, once for a legacy light culling pass that nobody remembered existed. That hurts. You need to walk through every draw call, literally frame by frame, and ask: does this pixel actually influence the final output? Most engines (Unity, Unreal, Godot, even custom in-house beasts) expose a RenderDoc or PIX integration. Hook it. The pattern is almost always the same: a buffer gets written, then immediately overwritten, or a full-screen pass runs on a quarter-resolution buffer that nobody resamples correctly. Strip the obviously dead weight first — any pass where its output is consumed by zero subsequent stages. That alone can cut your frame time by 15–30% on mid-range hardware, and it costs nothing except an hour of clicking through captures. The catch is that some teams skip this step because they assume the pipeline is already lean. It isn't. Not ever.
Merge post-processing into a single compute shader
Here is where most pipeline simplification fails — they try to keep every bloom, tone-map, vignette, and grain as separate passes because that's how the visual examples were written. Wrong order. You can co-locate all per-pixel post-effects into one compute shader dispatch. I have seen this done cleanly on a mobile title targeting 60Hz on a Snapdragon 865: bloom threshold, blur (single-pass separable via shared memory), tone-map, and color grading all inside one 16×16 thread group. Yes, the shader code gets denser. Yes, you lose the flexibility to toggle individual effects without reloading the entire kernel. But the GPU savings are massive — no intermediate render target reads and writes between each effect, no bandwidth churn. The trade-off is that blending additive effects (like lens dirt) inside the same kernel requires careful branching. You'll want to compile two variants: one with dirt blending, one without. Keep the branching uniform across the group to avoid warp divergence. Most teams skip this: they keep six passes because "it's cleaner to debug." Debugging won't save your battery life.
Replace multi-sample shadows with one cascaded shadow map
Multi-sample shadow maps (MSMS) are a trap. They look great in static screenshots, but they double or triple the shadow-pass draw calls depending on sample count, and the quality improvement over a single well-tuned cascaded shadow map (CSM) is marginal on modern GPUs. Does your scene actually have geometry that benefits from sub-pixel shadow edges? Probably not. Here's what we fixed on a recent project: the pipeline carried four shadow cascades at 2048×2048 with 8× hardware multisampling — 32MB of shadow maps every frame just for the depth, plus the resolve cost. We dropped the multisampling entirely, moved to 4096×4096 single-sample cascades with a 5-tap PCF filter in the light direction. Result: shadow pass time dropped 40%, and the banding that worried everyone was invisible in motion. The pitfall is that you must realign the cascade splits to your camera frustum — copy the view-projection cascade bounds from the original pipeline exactly, otherwise seams tear open at cascade boundaries. I have seen teams blame the simplification for seams that were actually caused by a mismatch in near-plane parameters across two different cascade configuration files. Documentation rarely mentions that. Check your math.
„The most aggressive pipeline simplification I ever shipped ran exactly three draw calls per frame: one compute for post, one shadow map, one forward opaque. Everything else was debris.”
— conversation with a technical artist who had been debugging render passes for thirteen years
Stripping passes demands you keep a critical eye on what the player actually sees — not what the editor preview shows on a perfectly lit test scene. One trick: play the game in silhouette mode (invert the final tonemap and boost contrast). Every flickering edge or missing pixel reveals a dependency that your simplified pipeline forgot to preserve. We found three hidden texture reads this way that were using stale data from a pass we had already deleted. Not fun to fix mid-sprint, but far better than shipping shimmer on specular materials. Start with the debugger, consolidate post-processing into a single compute kernel, and kill multi-sample shadows unless you can prove they matter in fast camera motion. That's the sequence. Anything else risks turning simplification into destabilization.
Tools and Setup Realities for Different Engines
Unity URP: scripting custom renderer features vs. built-in
Unity's Universal Render Pipeline offers a dangerous middle ground. The built-in shader stripping and renderer features are aggressive enough to blind you into thinking you're done—but they leave a hidden fracture in the hybrid path between Forward and Deferred. I've seen teams check "strip unused shader variants" in the URP asset and move on, only to find that their custom ScriptableRendererFeature eats 2ms per frame because the pipeline is still packing fallback passes for Lighting.hlsl. The catch: you can't just disable passes in the asset inspector. You have to write a custom ScriptableRenderPass, strip the shader variant you don't need at compile time, and then handle the edge case where the Editor still runs the full forward loop. That hurts. Most developers miss the part where Unity's stripping only removes variants that match currently enabled keywords—if you leave a keyword toggle alive in your material, the pass stays compiled. We fixed this by replacing the built-in camera stack with a single custom render loop that explicitly culls the shadow-receiving pass for UI elements. Not pretty. But it cut draw calls by 40% on an iPad Mini.
What usually breaks first is the depth-normals texture. Strip the deferred shading pass in URP, and suddenly your post-processing stack demands a g-buffer that no longer exists. The setup reality: you can't rely on Unity's umbrella stripping. You need a BuildReport log, a list of all keywords your materials actually call, and a willingness to test on device—not the Editor. That's not optional.
Unreal Engine 5: forward renderer limitations
“Unreal's default forward renderer still loads the entire shading model, even if you only use a single material domain.”
— A respiratory therapist, critical care unit
Honestly — most performance posts skip this.
— rendering engineer at a mobile-first studio, after stripping UE5 to run at 30 fps on a Pixel 7
This is the trade-off nobody prepares for. UE5's forward renderer looks simpler than the deferred path on paper—less passes, fewer textures. But the real constraint is the shading model list. Every material that inherits from the default Lit node brings the full stack: clear coat, subsurface, hair, eye. Even if you never touch those slots, the HLSL compiler pulls them in. The pitfall: you can't strip shading models per-mesh in blueprints. You either accept the compiled overhead or fork the engine source to delete the unused ShadingModel.ush blocks. I watched a team lose two weeks trying to disable anisotropy via project settings—it's not there. The forward renderer in UE5 was not designed for aggressive pass removal; it was designed for explicit per-platform overrides. That means you must decide: accept the 60 MB shader blob from a shipping build, or maintain a custom engine branch that culls the subsurface scattering computation. We chose the fork. The first compile took three hours. The runtime memory savings were 12%—worth it, but you'll pay for it in pipeline lock-in afterwards.
Godot 4: mobile renderer trade-offs
Godot 4's mobile renderer promises a lighter path than its Forward+ cluster, but the team behind it made an odd concession: they kept the clustered lighting data structure alive. That means even if you strip every light beyond the first eight, the uniform buffer still allocates for the cluster grid. The simplification gain is real—we saw 25% fewer draw calls on a linux-based handheld console—but the setup trap is subtle. You can't manually disable cluster allocation in a Material override; it's baked into the server-level rendering code. The practical fix: switch the whole project to Compatibility mode and accept the specular quality loss. Or, if you need the mobile renderer's shadow quality, write a custom RenderingDevice shader that patches out the cluster culling loop. That's not beginner work. Most Godot users skip this and wonder why frame times spike when a twelth light enters the frustum.
One detail that tripped us: Godot's mobile renderer doesn't support the ScreenSpaceTexture pass in the same way as Forward+. If you strip the g-buffer to save bandwidth, your SSR and glow effects silently revert to fallback code—no error, just a performance regression. The only way to catch it's to run the GPU profiler and compare the pass list against a known baseline. That sounds obvious. I can tell you it's not the first thing anyone checks.
So here is the setup reality for every engine: the simplification that works on Monday will break on Wednesday when a new pixel shader variant sneaks in. The tooling gap is not about documentation—it's about each engine silently versioning its own internal pass list without telling you. You either trace the shader permutation yourself, or you accept whatever the build machine hands you. There is no middleware for this. There is only the profiler and a notebook.
Variations for Different Constraints
Baked lighting with static objects
The easiest win in rendering isn't a pipeline rewrite—it's baking. If your scene is mostly static geometry lit by fixed directional, point, or area lights, you can kill entire deferred render passes. No per-pixel dynamic shadows, no light accumulation for every object, no specular work on moving actors. I've seen teams cut forty percent of their draw calls this way, but there's a trap: baked lighting looks fantastic until something moves. A character walking through a sunlit courtyard won't pick up the bounced color from the ground unless you're blending light probes. That seam between baked radiosity and real-time illumination—it hurts. You need at least one extra pass for probe interpolation, and if your probes are spaced too far apart, the transition looks like stepping into a different room. Every switch to baked lighting hides one more dynamic object in the probe volume—check your wander radius.
— field experience, Unity Lightmapping QA pass
Single-pass forward for VR
Virtual reality demands ninety frames per second with stereo rendering. Deferred shading adds a buffer write and a resolve per eye—too expensive. The standard escape is single-pass forward: you render both eyes in one draw call, using instanced stereo or multiview extensions. That works beautifully for simple geometry and a handful of lights. The catch is material complexity. Forward rendering touches every texture, every shader instruction per pixel, per light. Three lights per object? That's three times the fragment work. What usually breaks first is the shader variant count. We fixed a Quest 2 project where our forward pipeline ballooned to sixteen thousand permutations because every material had a specular texture and a separate mask for shadow receive. Stripping that to a hard limit—two dynamic lights, no specular on transparents—dropped shader compilation time from eight minutes to forty seconds. Devs forget that mobile VR GPUs are bandwidth-starved; a single 2K shadow map eats 4 MB per frame. Not yet a problem? Wait until your smooth ninety dips to seventy-two. Then you'll see the headset's asynchronous reprojection kick in, and motion sickness spikes player exits.
Deferred with limited MSAA – when to switch
Deferred rendering handles dozens of lights elegantly, but it murders antialiasing. Standard MSAA doesn't cover the geometry buffer—only the final render target—so you get jaggies on edges that weren't there in forward. Teams often slap on FXAA or TAA as a band-aid. Wrong order. MSAA works in deferred if you use a sample-count-aware G-buffer layout, but that doubles memory bandwidth. Most consoles and mid-tier PCs can't swallow that cost. When I consult on projects targeting 60 fps with four lights per object or fewer, I recommend switching to forward+ (clustered shading). It gives you per-pixel MSAA without the buffer explosion. The threshold is simple: if your average fill rate per frame exceeds 70% of the GPU's theoretical pixel output, deferred with limited MSAA becomes a bottleneck. You lose the elegant light-culling structure, but you gain sharp edges on foliage and hair—the very places aliasing screams. One studio pushed past this by decoupling shadow resolution from the main pipeline: they baked shadow maps at half resolution and upsampled with a smart blur. That's a specific constraint fix, not a generic rule—test your exact scene, not the tutorial default.
Pitfalls: What to Check When It Fails
Missing shadows after merging cascades
The most common failure pattern I see is a world that suddenly looks flat—no cast shadows, no contact hardening. Shadow cascades get merged aggressively during simplification, and if you don't remap the split distances after removing a cascade, you get a single frustum that covers everything from 0 to the far plane. That sounds fine until you realize the shadow map resolution is now spread across empty sky. The fix: check your cascade boundary values against the actual scene extents, not the old defaults. Most engines expose debug colors per cascade—turn those on. If one color covers 90% of your view, you've collapsed too early. We fixed one project by re-measuring the tightest near clip per level and clamping the first cascade to that exact distance. The seam blows out by maybe 5% shadow quality, but the shadows come back.
Artifacts from reduced precision in compute shaders
You'll see this as banding in fog, shimmering on normal maps at grazing angles, or weird stepping on animated light positions. Render pipeline simplification often forces half-precision (fp16) where full float32 was the default—especially in compute-based post-processing. The catch: low-precision works perfectly in the test scene, then fails on a dark foggy forest level with gradient skies. I have seen teams burn two days bisecting "random" flicker, only to find a single min16float declaration in the tonemapping compute shader. The debug check is brutally simple: override all precision qualifiers to full float32 in the suspect shader group and see whether the artifact disappears. If it does, you need to isolate which variable actually exceeds the fp16 exponent range—usually something in world-space position reconstruction or HDR accumulation. That said, you can often keep half-precision everywhere else and just promote that one vector.
“The bug that breaks the build is rarely the one you optimized for—it's the assumption you forgot you made.”
— engine programmer reflecting on a missed material flag
Reality check: name the optimization owner or stop.
Material values that assume a full pipeline
Most artists build materials against a complete deferred or forward+ pipeline, with all the texture slots, dynamic branching, and specular models intact. When you strip passes, you might kill, say, the separate clear-coat pass or the pre-lighting compute dispatch that packs normal derivatives. Now materials using those features silently fall back to default values—usually black, zero, or a unity vector. The pitfall: no compile error, no console warning, just a car body that looks matte plastic. What usually breaks first is roughness/gloss inversion from missing anisotropy flow maps. The check: render the material in isolation with a debug view that outputs the exact values being fed into the shading model—not the final pixel. Most engines have a "shading model" debug mode. Turn it on. If your roughness is 0.5 everywhere but the debug shows 0.0, you have a missing or collapsed texture sample node. Wrong order—you'd be surprised how often stripping reorders sampler bindings and the material uses the wrong UV set afterward. Manual override works, but you'll want to rename those material instances to something explicit or you lose a day on the next revision.
FAQ: Quick Prose Answers to Sticky Questions
Can I simplify without losing PBR?
Yes — but you have to be surgical about which light paths you keep. PBR isn't a single switch; it's a stack of approximations. What usually breaks first is the specular fallback when you strip the indirect-bounce buffer. I have seen teams kill their ambient occlusion pass thinking it's a frill, only to realize their rough metals turn into flat gray blobs. The trick is to keep the energy-conserving core: albedo, normal, roughness, and a single direct light source. Drop everything else — reflection probes, screen-space gloss, sub-surface scattering — and you still get 80% of the visual correctness. That sounds fine until you hit an emissive surface with no bloom; then you compensate with a cheap additive overlay. The catch is that you can't skip the linear-to-sRGB conversion at the end. Mess that up, and your materials look like they're lit by a broken neon tube. Test on three rough-metallic materials before you call it done.
Do I need a separate pipeline for editor vs. runtime?
Not initially. Most teams skip this: they build one simplified path, use it in both places, and then wonder why the editor's gizmo lines vanish. The editor needs an overlay layer for selection outlines, debug wireframes, and the occasional half-transparent handle. Runtime doesn't. The pragmatic solution is a single render loop with two modes — not two pipelines. Flip a bit in the engine's frame-request struct: runtime mode strips the editor overlay pass and flattens the camera stack. Editor mode keeps a tiny post-processing queue for those selection shaders. That's a three-hour refactor, not a three-week architecture. I have seen a startup try the full dual-pipeline approach, and their shader compilation time doubled while they got exactly zero runtime performance gain. Honestly—start with conditional stencil writes. If you later need distinct features like HDR editor preview versus SDR game output, then split.
'The difference between a broken simplification and a smart one is often just one pass that nobody wrote down.'
— overheard during a Unity render-diagnostics session
How do I test on low-end hardware without owning it?
You throttle. Not with a profiler menu — with actual constraints. Most devs reach for GPU timers and call it done. Wrong order. First, clamp your frame budget to 16 ms and force a 60-hertz display. Then cap the draw-call count by locking the shader complexity: replace your fragment shader with a solid-color fallback and see if the remaining passes even fit. That hurts, but it reveals exactly which simplification steps you skipped. Next, emulate a low-end GPU by cutting the output resolution to 720p and disabling all texture streaming. If the frame time barely changes, your bottleneck is not the pixel count — it's the mesh depth-complexity or the overdraw. We fixed this by running a headless build on a repurposed laptop from 2018, no graphics APIs beyond DirectX 11 feature level 10_0. No cloud service needed. The outcome was a checklist of exactly four passes to drop; after that, the 30-fps floor held. One rhetorical angle to ask yourself: If I strip every post-effect, does the game still look like mine? If no, you were relying on crutches, not lighting.
What to Do Next: Specific Next Steps
Export Your Simplified Pipeline as a Reusable Asset
Stop treating your clean pipeline like a one-off hack. Package it. I mean literally: create a pipeline asset, a preset file, or a version-controlled folder that contains every pass you stripped, every fallback shader, and the exact order you rebuilt things. Most teams skip this and then wonder why the next sprint’s lighting artist spends three days re-tracing their steps. The catch? Exporting forces you to document dependencies — which textures rely on which deferred buffers, which post-effect is secretly clamping your albedo. Without that map, your simplified pipeline turns into a brittle museum piece no one touches.
One concrete trick: name your asset something searchable, like “MobileForward_Reduced_v3.” Include a one-paragraph changelog inside the file header. Not a novel — just what you removed and why. That alone saves a Monday morning of confusion when someone loads your scene and half the shadows vanish.
Run a Regression Test Suite on Five Scenes
Pick five scenes that represent your real content — not the demo level with one sphere. A dark interior, a bright exterior, a character close-up, a particle-heavy effect, and one scene you hate because it always breaks. Build a short playback or screenshot capture that runs through each at the same camera angles. Compare renders before and after your pipeline changes. The goal isn’t pixel-perfect matching; it’s spotting seams you missed. A shadow that flickers only at noon. A specular highlight that pops too bright after you stripped a reflection probe. Catch those now.
Honestly—just run the suite after every pipeline edit. I have seen teams lose two weeks because they “saved time” by skipping this step, then shipped a build where water turned opaque on mobile. The regression test takes twenty minutes. A hotfix deployment takes three days and an apology post. Worth it.
What usually breaks first? The order of your tonemapping relative to your bloom. Move one pass and suddenly everything looks washed out. The test suite picks that up before you do.
Write a One-Page Maintenance Doc for the Next Dev
You won’t be the last person touching this pipeline. Write a single page — hard limit — that answers: What did you remove? What broke after removal? How did you patch it? Where are the edge cases not covered by the regression suite? One team I worked with kept a running doc titled “Things That Explode When You Breathe on the Render Queue.” It was blunt, sometimes wrong, but always honest. That beats a 40-page spec that nobody updates. — anecdote from a production fix after a pipeline swap
Keep the language coarse. “If you reorder the depth prepass before the shadow map, expect light leaks in corners.” A fragment works. “Don’t touch the stencil buffer after post-process.” That doc becomes your on-ramp for the next dev — and your safety net for yourself six months later, when you’ve forgotten why you made that change in the first place. The maintenance doc shouldn’t live in a wiki. Put it in the repo, next to the asset file, so it travels with the code.
Comments (0)
Please sign in to post a comment.
Don't have an account? Create one
No comments yet. Be the first to comment!