Welcome to arguably the most critical, installment of our Metruvia Content Creator Anti-Rejection Transport Fever 2 Mod.io distribution guide. If you have mastered the file hygiene of Article 1 and the cloud logistics of Article 2, you are now facing the final boss of cross-platform modding: Console Certification.
In the Wild West of the Steam Workshop, optimization is a courtesy. If a PC player downloads an unoptimized 800MB locomotive with 4K textures and zero Levels of Detail (LODs), their game might drop to 5 frames per second, but the responsibility lies with the player.
On PlayStation 5 and Xbox Series X|S, optimization is a legal and technical mandate. Sony and Microsoft enforce strict performance budgets on all User Generated Content (UGC). If a mod causes a memory leak, crashes the console OS, or drops the framerate below acceptable thresholds, Urban Games takes the blame. Therefore, the “Console Compatible” badge on Mod.io is guarded by a rigorous QA (Quality Assurance) process.
As we prepare for the ecosystem of Transport Fever 3 later in 2026, these optimization standards are becoming even stricter. This 3,000+ word masterclass will tear down the engine’s rendering pipeline. We will explore the mathematics of polygon budgets, the architecture of DDS texture compression, the dark art of Draw Call reduction, and the absolute necessity of LODs. Master this, and your mods will never face a rejection notice again.
1. The Anti-Rejection Philosophy of the Performance Budget
Before opening Blender or your code editor, you must adopt a “budgeting” mindset. Consoles utilize Unified Memory Architecture (UMA). Unlike a PC, which has separate System RAM and dedicated GPU VRAM, a PlayStation 5 shares its pool of memory between the CPU and the GPU.
When a console player boots up a late-game save file in the year 2050, with massive sprawling cities and hundreds of active vehicles, the memory pool is already stretched to its absolute limit by the vanilla game. Your mod must sip from this remaining pool, not gulp from it.
1.1 The 200MB Absolute Limit (Unpacked)
Mod.io enforces a hard limit of 200 Megabytes per mod. Crucially, this is the unpacked size on the disk, not the compressed .zip size during upload. If your folder contains a single uncompressed 8K texture map or a forgotten .psdPhotoshop file, you will blow past this budget and be automatically rejected by the API before a human even looks at your mod.
1.2 The “Yard Test” Scenario
When Urban Games QA testers evaluate your vehicle mod, they do not just place one train on a track. They perform the “Yard Test.” They will spawn a massive rail depot and place 50 to 100 instances of your mod on the screen simultaneously.
If your mod is beautifully detailed but unoptimized, rendering 50 of them will crash the game.
Your goal is not just to make one model look good; it is to make fifty of them render efficiently at varying distances.
2. Masterclass in Level of Detail (LOD)
The single most frequent reason for Mod.io console rejection is a failure to implement proper Levels of Detail (LODs).
An LOD system swaps out high-quality 3D meshes for lower-quality versions as the in-game camera moves further away. If a train is 2 kilometers in the distance, it occupies only 10 pixels on the TV screen. Rendering the intricate bolts on the wheels at that distance is a catastrophic waste of GPU resources.
2.1 The Minimum Requirement: Three LODs
To pass console certification, every 3D asset you create must have a minimum of three distinct geometric models.
LOD 0 (Hero Distance: 0m to 150m): This is the high-detail model viewed when the player zooms in close.
Triangle Budget: 20,000 to 40,000 triangles (for a large locomotive).
Features: Modeled handrails, 3D bogeys, interior cabin details.
LOD 1 (Mid Distance: 150m to 500m):
Triangle Budget: 3,000 to 8,000 triangles.
Features: Interior is deleted. 3D handrails become flat textured planes. Small geometric details (like bolts and hinges) are removed and baked into the normal map.
LOD 2 (Far Distance: 500m to 2000m+):
Triangle Budget: 100 to 500 triangles.
Features: A basic “shoebox” silhouette of the vehicle. Wheels are usually turned into flat cylinders or removed entirely if hidden by a chassis.
2.2 The “1MB Blob File” Rule
When you export your .msh (mesh) files, the game compiles them into binary .blob files to be loaded into memory.
Urban Games explicitly mandates that the .blob file for your final, lowest LOD must be under 1 Megabyte in size. If your LOD 2 blob is 2MB, it means your “low-poly” model is still too complex, and the mod will be rejected.
2.3 Implementing LODs in the .mdl File
You define the transition distances in your Lua .mdl (Model) file. You must explicitly tell the engine at what camera distance to swap the meshes.
lods = {
{
— LOD 0 (High Detail)
node = {
children = {
{
materials = { “vehicle/train/my_train_main.mtl”, },
mesh = “vehicle/train/my_train_lod0.msh”,
— Matrix data here
},
},
},
static = false,
visibleFrom = 0,
visibleTo = 150, — Swaps out at 150 meters
},
{
— LOD 1 (Medium Detail)
node = { … },
static = false,
visibleFrom = 150,
visibleTo = 500, — Swaps out at 500 meters
},
{
— LOD 2 (Low Detail Shoebox)
node = { … },
static = false,
visibleFrom = 500,
visibleTo = 2500, — Renders out to 2.5 kilometers
},
},
Pro Tip for Console Success: Ensure there are no “gaps” in your visibleFrom and visibleTo values. If LOD 0 ends at 149 and LOD 1 begins at 151, your train will flicker completely out of existence for one meter, failing visual QA.
3. Texture Engineering & Memory Management
3D meshes take up very little space on a hard drive. Textures are the actual memory hogs. A single uncompressed 4K texture can consume 64MB of VRAM. If you have four of those on your train, you have already broken the console budget.
3.1 The DDS Mandate
As established in Article 1, you cannot use PNG, JPG, or TGA files for console mods. You must use DDS (DirectDraw Surface). DDS is a container format that holds pre-compressed texture data. The console GPU can read this data directly without needing the CPU to decompress it first.
3.2 Navigating Block Compression (BC) Formats
When exporting your DDS textures from Photoshop, GIMP, or Substance Painter, you must choose the correct compression algorithm. Choosing the wrong one ruins your visuals or bloats your file size.
| Texture Type | Required Compression | Explanation | Color Space |
| Albedo (Color) | BC1 / DXT1 | Used for opaque textures. Squeezes the image to 1/6th its original size. | sRGB |
| Albedo with Transparency | BC3 / DXT5 | Used if your train has glass windows. The extra data channel preserves smooth transparency gradients. | sRGB |
| Metal/Gloss/AO (MGA) | BC1 / DXT1 | The engine combines Metalness (Red), Gloss/Roughness (Green), and Ambient Occlusion (Blue) into one file. | Linear / RAW |
| Normal Maps | BC5 / ATI2 | A special format that only saves the Red and Green channels (calculating the Blue channel on the fly) to preserve high-fidelity depth data without blocky artifacts. | Linear / RAW |
Fatal Error Warning: If you save your MGA or Normal map in the sRGB color space instead of Linear, the game engine will apply gamma correction to mathematical data. Your shiny metal train will suddenly look like it is made of matte plastic, and the normal map shadows will render inverted.
3.3 Mipmaps: The Silent Console Killer
A Mipmap is a sequence of progressively smaller, pre-rendered versions of your texture bundled inside the .dds file.
Base: 2048×2048
Mip 1: 1024×1024
Mip 2: 512×512
Mip 3: 256×256…
Why are they mandatory?
If a console attempts to display a 2048×2048 texture on an LOD 2 model that is 2 kilometers away, the GPU experiences “texture aliasing” (a horrible shimmering effect) and the memory bandwidth is choked.
When you export your DDS files, you must check the “Generate Mipmaps” box. Urban Games runs an automated script on Mod.io submissions. If your .dds file lacks a mipmap chain, the system automatically strips the “Console Compatible” tag.
3.4 Texture Resolution Scaling
For Transport Fever 2 console mods, realistic texture scaling is required:
Main Body / Fuselage: Max 2048×2048. (4K textures are almost always rejected unless the vehicle is exceptionally massive, like an ocean liner).
Bogeys / Wheels: Max 1024×1024.
Small Details / Interiors: Max 512×512.
4. Draw Calls and Material Optimization
This is the secret weapon of elite modders. A Draw Call is a command sent from the CPU to the GPU saying, “Hey, draw this specific mesh with this specific material.”
Consoles handle raw polygon counts incredibly well. What kills console performance is a high number of Draw Calls. Every time the engine has to switch to a different material or a different mesh, it causes a micro-stutter in the CPU pipeline.
4.1 The “Too Many Materials” Trap
Imagine you are modeling a boxcar. You create one material for the wood planks, one material for the metal roof, one material for the wheels, and one material for the rusty bolts. That is 4 materials, which results in 4 draw calls per boxcar. During the “Yard Test” with 50 boxcars, that is 200 draw calls.
4.2 Texture Atlasing
To pass console certification easily, you must practice Texture Atlasing. This means UV-unwrapping your wood planks, metal roof, wheels, and bolts onto one single 2048×2048 texture sheet.
By assigning the entire boxcar to one .mtl (material) file, you reduce the rendering cost to 1 draw call per boxcar. In the Yard Test, 50 boxcars only cost 50 draw calls. The console GPU will render this flawlessly.
4.3 Mesh Merging
Do not export your locomotive from Blender as 30 separate .msh files (e.g., door.msh, window.msh, roof.msh). Every .msh file triggers a draw call.
Before exporting, combine all static parts of your vehicle into one master mesh (e.g., body_main.msh).
The only elements that should be separated into their own meshes are animated parts:
Wheels (they need to spin).
Pistons/Connecting rods on steam trains.
Doors (if you have scripted them to open at stations).
Bogeys (they need to pivot on curves).
5. Polygon Limits and Topography
While draw calls are the primary bottleneck, poly-count still matters for the 200MB file size limit.
5.1 Quads vs. Triangles
When modeling in Blender or Maya, you work in Quads (four-sided polygons). However, the Transport Fever 2 engine—like all game engines—only understands Triangles. When you export, every quad is split into two triangles.
Always monitor your Triangle (Tri) count, not your Face/Quad count.
5.2 The Smoothing Group / Hard Edge Multiplier
Here is a highly technical nuance that causes modders to fail the “1MB Blob File” rule without understanding why.
In a 3D engine, a single vertex can only face one direction (its “normal”). If you have a cube, and you set the edges to be “Hard” (creating sharp 90-degree corners), the game engine must physically split the vertices along that edge to render the sharp lighting correctly.
A perfectly smooth cylinder might have 100 vertices.
That exact same cylinder, if all edges are set to “Hard/Flat Shading”, will export with 300 vertices.
Optimization Rule: Use “Smooth Shading” on as much of your model as possible. Rely on your Normal Map .ddstexture to create the illusion of sharp panel gaps and hard edges. This keeps your exported .blob files incredibly small and guarantees you stay under the console file-size limits.
6. Audio Optimization: The Hidden Bloat
Modders often focus entirely on the visual, completely forgetting that sound files can bloat a mod past the 200MB limit.
6.1 Mono vs. Stereo
The Transport Fever 2 engine uses a 3D spatial audio system. If the camera is to the left of the train, the horn plays in your left speaker.
To do this, the engine requires Mono audio files.
If you upload a Stereo .wav file for a train engine, you are wasting 50% of the memory footprint. The game is going to force it into mono space anyway, but the console RAM still has to load both empty channels.
6.2 Sample Rates
For ambient sounds (like the hum of an electric tram), a 44.1kHz sample rate is unnecessary overkill. Downsample ambient looping sounds to 22.05kHz. The player will not hear the difference over the background music, but you will cut the audio memory budget in half, making the QA testers very happy.
7. The Urban Games QA Process: What Happens After You Click Publish?
When you check the “Console Compatible” box in the Mod.io publishing tool, your mod does not go live on the PlayStation or Xbox networks immediately. It enters the Urban Games manual QA queue.
7.1 Automated Checks (Day 1)
First, a script runs over your upload:
Is the total size under 200MB?
Are all textures DDS with Mipmaps?
Are all files strictly lowercase?
Is the severityRemove parameter present in the mod.lua? If your mod fails any of these, it is instantly rejected and stripped of the console tag. It remains available for PC players.
7.2 Manual QA (Days 2-14)
If it passes the script, a human tester at Urban Games downloads the mod onto console dev-kits. They perform:
The Yard Test: Checking for memory crashes under heavy load.
The Zoom Test: They zoom in and out rapidly to ensure your LODs transition smoothly without flickering.
The IP Check: They inspect the textures closely for trademarked logos (We will cover this extensively in Article 4).
The Stability Test: They add the mod to a save game, buy the vehicle, save, exit to the menu, and reload the save to ensure no initialization crashes occur.
7.3 Handling Rejection
If a human tester rejects your mod, you will receive a generic notification via Mod.io stating it failed certification. Unfortunately, due to the volume of submissions, detailed feedback is rarely provided.
If this happens, you must rely on this guide:
Check your LOD blob sizes (Is LOD 2 under 1MB?).
Check your material count (Did you use too many draw calls?).
Check your audio sample rates.
8. Summary: The Console Certification Checklist
Before you ever click the “Publish” button, run your mod through this definitive 2026 checklist:
[ ] Polygon Budget: Is LOD 0 under 40k tris? Is LOD 2 under 500 tris?
[ ] Blob Size: Is the .msh.blob for my lowest LOD strictly under 1MB?
[ ] Draw Calls: Have I atlased my textures to use as few .mtl files as possible per asset?
[ ] Texture Format: Are all textures saved as DDS? Are Color maps saved as BC1/BC3? Are Normal maps saved as BC5?
[ ] Mipmaps: Did I generate mipmaps for every single texture file?
[ ] Audio: Are all my custom .wav files rendered in Mono?
Optimization is not a restriction; it is an art form. By adhering to these strict performance budgets, you ensure that your creations can be enjoyed by hundreds of thousands of players across all platforms, flawlessly maintaining the illusion of a bustling, living transport empire.


