Bicycle Extreme Rider 3D - Mobile Technical Art & Optimization
A live stunt-cycling game on Unity's Built-in Render Pipeline had grown to ~600K shader variants, a ~450 MB build and a ~1.6 GB project. I audited where that weight came from, moved the project off heavier, general-purpose shader usage and onto a controlled lightweight shader library, migrated content onto it batch by batch, adapted the third-party shaders that stayed, and cleaned the asset base - without changing the shipped look.
Bicycle Extreme Rider 3D is an EONEvolve title - my own studio - so this work can be shown in full. Figures below are the recorded before/after values from the optimization pass - variant count from the build log, build size from the Unity Build Report, project size from the Assets folder on disk. Approximate where noted.
Context
Bicycle Extreme Rider 3D is a live, shipped stunt-cycling game for mobile: physics-driven riding across BMX, Fixie and MTB style content, spread over multiple environments. It runs on Unity's Built-in Render Pipeline and has been updated over time by a small studio team, with new bikes, cosmetics and environments arriving update after update.
That is the good problem to have and the source of the bad one. Every new bike, track and cosmetic added materials, shaders, textures and source files. Nobody added them carelessly, but a content roster that grows for years without a periodic technical pass accumulates debt in exactly the places players never see and the whole team pays for: variant counts, build size, and project size.
Problem
Three measurements framed the work:
- Shader variant count - roughly 600K. The number is not cosmetic: shader variants drive how much compilation work exists, how much shader data has to be packaged and kept around, and how much of that weight ships to a phone that will only ever use a fraction of it.
- Bloated build - around 450 MB. On mobile, download size is a conversion problem before it is a technical one. A large APK/IPA loses installs on mobile data, on limited storage, and on the exact low-end devices this genre sells well on.
- Oversized project - a ~1.6 GB Assets folder. That is a team-velocity problem: slower imports, slower reimports, heavier version-control operations, and more places for duplicate or dead content to hide from whoever touches the project next.
Worth being precise about what these numbers are and are not. They are project, build and variant measurements. They are not a claim about frame rate, memory or launch time - that work is a separate, ongoing effort and I am not going to attach numbers to it that I have not measured.
Constraints
- Live title, real players. The look could not regress. Any change that made an existing bike or environment read differently was a failure, regardless of what it saved.
- Built-in Render Pipeline. Migrating the project to URP was out of scope - it is a large, risky rewrite for a shipped game, and the goal was to fix the debt inside the pipeline the game already uses.
- Small team. No dedicated optimization strike force. The work had to fit alongside normal production.
- Content had to keep shipping. The game could not go into a freeze while the cleanup happened, so everything had to be incremental and reversible.
- Wide device range. A large share of the audience is on low- and mid-tier Android hardware, which is what makes install size and shader compilation cost matter more here than on a flagship-only title.
Technical Audit
Inventory before surgery. Before touching a single material I wanted to know where the weight actually lived, because the intuitive answer on a project this age is usually wrong.
- Shader and material usage. Which shaders were actually in use across the content roster, and how many materials pointed at each one.
- Asset inventory. A pass over the Assets folder for duplicates, orphaned content nothing referenced any more, and oversized source files - uncompressed or oversized textures, and import settings that had never been reviewed after the asset was dropped in.
- Build composition. Measuring what the build was actually made of, so decisions were driven by what ships rather than by what feels heavy in the project window.
[ Live content roster ]
|
+--> shader / material audit ---> where do the variants come from?
+--> Assets folder inventory ---> duplicate / unused / oversized
+--> build composition ---> what actually ships
|
v
[ Lightweight shader library ] -> incremental material migration
|
v
[ Third-party shader adaptation ] -> asset + import cleanup
|
v
[ Re-measure: variants / build size / project size ]
Shader Strategy
The audit pointed in one direction: the project was leaning on heavy, general-purpose shaders for content that did not need them.
The change was a migration away from that usage and onto a controlled, lightweight shader library built for this specific Built-in RP project - a small set scoped to what the game actually renders. After the migration the recorded variant count was roughly 100K, down from roughly 600K.
I built and scoped that library in Amplify Shader Editor, which supports the Built-in Render Pipeline this project ships on, and integrated it into the project.
Material Migration
A new shader library is worth nothing until the content is on it. I migrated the appropriate material and shader usage across the existing roster onto the new library, matching the shipped look for each case rather than accepting "close enough" - the visual result players already knew was the acceptance criterion.
This ran incrementally, in batches, with the live game continuing to build and ship throughout. Migrating a group at a time meant every step could be checked in isolation and rolled back on its own if something read wrong, instead of one large switchover that would have been impossible to review or unwind on a title with an active player base.
Third-Party Shader Adaptation
Not everything in the project was written in-house. Some third-party shaders were doing real work and ripping them out wholesale would have meant rebuilding functionality for no gain. Instead I adapted and tuned them so they fit the project's mobile budget and matched the new library's conventions, rather than sitting outside the system as exceptions.
Asset / Build Cleanup
The second half of the weight was content, not shaders. This pass covered:
- Removing duplicate assets - the same source content imported more than once over the years under different names or folders.
- Removing unused assets that nothing in the shipped game referenced any more.
- Correcting import settings - compression, max size and platform overrides that had never been revisited after the asset first landed.
- Replacing oversized source content with versions sized for what the game actually displays on a phone screen.
This is the work that took the Assets folder from roughly 1.6 GB to roughly 800-900 MB, and together with the shader pass it is what brought the build from roughly 450 MB down to roughly 270 MB.
UI / Workflow Improvements
Alongside the optimization pass I handled UI implementation work on the game, and cleaned up prefabs and the workflows around them. That part matters for a reason that is easy to undersell: a cleanup is only valuable if the project stays clean afterwards. Tidier prefabs and clearer conventions for adding content mean the next bike, track or cosmetic goes in the right way by default, so the smaller, tidier project does not quietly grow back to where it started.
Results
Before
- ~600K shader variants
- ~450 MB build
- ~1.6 GB Assets folder
- Heavy, general-purpose shader usage, duplicate and unused content
After
- ~100K shader variants
- ~270 MB build
- ~800-900 MB Assets folder
- A small, purpose-built shader library and reviewed import settings
These are the recorded project, build and variant figures from the optimization pass, all approximate. They are deliberately the only numbers on this page: runtime performance and lighting work on the title are ongoing, so I am not going to claim frame-rate, memory or launch-time wins I have not measured and cannot show.
What follows from those figures - a smaller download, less shader data to compile and ship, and a project a small team can move around in - is the expected benefit of the change, not a separately measured result. The part I can evidence is the three numbers above, achieved on a live title without a pipeline migration.
Evidence / Media
Links / Credits
Bicycle Extreme Rider 3D is an EONEvolve team title. My role on it is Co-Founder & Technical Artist; the work described here is the technical art and optimization side.