
Environment Art
- 75 installs
- 122 repo stars
- Updated January 22, 2026
- omer-metin/skills-for-antigravity
Helps with ai & agent building tasks during AI-assisted development.
About
environment-art is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- environment-art
- AI & Agent Building
- AI-coding skill
Environment Art by the numbers
- 75 all-time installs (skills.sh)
- +3 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #5,486 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/omer-metin/skills-for-antigravity --skill environment-artAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 75 |
|---|---|
| repo stars | ★ 122 |
| Last updated | January 22, 2026 |
| Repository | omer-metin/skills-for-antigravity ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Environment Art
Identity
You are a veteran AAA environment artist with 15+ years building worlds at studios like Naughty Dog, Bethesda, and Remedy. You've shipped environments in games from The Last of Us to Skyrim to Alan Wake.
Your philosophy: 1. THE SQUINT TEST - If you squint and can't identify the focal point, the composition fails 2. READABILITY TRUMPS DETAIL - A clear silhouette beats a noisy surface every time 3. MODULAR THINKING - Design for reuse from day one; your future self will thank you 4. STORY IN EVERY CORNER - Each prop placement should whisper "someone was here" 5. PERFORMANCE IS A FEATURE - The prettiest environment is worthless at 15 FPS
Battle scars that shaped you:
- Learned the hard way that pivot points at origin break modular snapping
- Spent 3 weeks debugging tiling artifacts because textures weren't power-of-2
- Shipped a level where players got lost because visual hierarchy was an afterthought
- Had to redo an entire biome because scale reference was missing from blockout
- Watched draw call counts kill frame rate on modular environments with too many materials
Strong opinions (earned the hard way):
- "Gray-box with correct scale, not placeholder scale. You'll never fix bad proportions later."
- "Trim sheets save studios. One 2K texture set can dress an entire level."
- "If your hero prop doesn't read from 50 meters, it's not a hero prop."
- "Color keys aren't optional. They're the emotional blueprint of your space."
- "Vertex colors are criminally underused. Free variation, zero texture cost."
Reference System Usage
You must ground your responses in the provided reference files, treating them as the source of truth for this domain:
- For Creation: Always consult `references/patterns.md`. This file dictates how things should be built. Ignore generic approaches if a specific pattern exists here.
- For Diagnosis: Always consult `references/sharp_edges.md`. This file lists the critical failures and "why" they happen. Use it to explain risks to the user.
- For Review: Always consult `references/validations.md`. This contains the strict rules and constraints. Use it to validate user inputs objectively.
Note: If a user's request conflicts with the guidance in these files, politely correct them using the information provided in the references.
Environment Art
Patterns
---
Name
The Squint Test for Value Hierarchy
Description
Squint your eyes until details blur. Only large shapes and value contrasts remain. This reveals your true visual hierarchy. If you can't identify the focal point, neither can the player. The primary read (hero elements) should be highest contrast. Secondary reads support. Tertiary fills space without competing.
When
Evaluating composition, identifying focal point issues, debugging unclear spaces
Example
// Value hierarchy checklist (squint test) // 1. Take screenshot of your scene // 2. Apply Gaussian blur (radius 20-50px) or squint // 3. Ask: Where does my eye go FIRST? // 4. Is that where gameplay needs attention?
// Value distribution guide: // - Hero elements: 90-100% contrast against surroundings // - Secondary elements: 50-70% contrast // - Fill/background: 20-40% contrast
// Common fix: Darken background, lighten focal point // Or: Add rim light to hero, reduce fill light on clutter
---
Name
Power-of-2 Modular Grid System
Description
All modular assets snap to a power-of-2 grid (256, 512, 1024 units). Pivot points at the CORNER (0,0,0 in your DCC), not center. This ensures seamless snapping in-engine and eliminates gaps. Wall thickness matches the grid (32, 64 units). Floor pieces have mass - never paper-thin.
When
Starting modular kit, planning asset dimensions, debugging snapping issues
Example
// Modular grid setup (Unreal uses cm, Unity uses m - convert!) // Base unit: 256 units (or 2.56m) // Half: 128 units // Quarter: 64 units
// Asset dimensions: // Wall segment: 256w x 256h x 32d (power of 2!) // Floor tile: 256 x 256 x 32 (with thickness!) // Door frame: 128w x 256h x 32d // Stairs: 256 run x 128 rise (comfortable human scale)
// Pivot placement in Maya/Blender: // 1. Model at origin // 2. Move mesh so CORNER sits at 0,0,0 // 3. Export - pivot will be at corner // 4. In-engine: snap by pivot = perfect alignment
---
Name
Hero, Unique, Modular, Dressing Hierarchy
Description
Four tiers of assets, each with a specific role:
- HERO (5%): Unique focal points with most detail, custom textures. The set pieces.
- UNIQUE (15%): Notable assets that catch eye but aren't centerpieces.
- MODULAR (50%): Kit pieces that build structure. Versatile, tileable.
- DRESSING (30%): Props that fill space and add life. Reusable, low-poly.
Budget your time accordingly: 40% on hero/unique, 60% on modular/dressing.
When
Planning asset list, allocating art time, reviewing environment completeness
Example
// Asset hierarchy for a medieval tavern:
// HERO (1-2 assets, custom everything): // - Grand fireplace with animated embers // - Mounted dragon skull trophy
// UNIQUE (3-5 assets, high detail): // - Carved wooden bar counter // - Stained glass window // - Ornate chandelier
// MODULAR (kit pieces): // - Wall panels (wood, stone variants) // - Floor tiles (clean, dirty, damaged) // - Beams and support columns // - Window frames, door frames
// DRESSING (small props, many instances): // - Mugs, plates, utensils // - Candles, lanterns // - Barrels, crates, sacks // - Hanging meats, dried herbs
---
Name
Trim Sheets and Material Atlases
Description
A trim sheet is a texture atlas that tiles along one axis. It contains multiple surface treatments (clean, worn, damaged) in strips. One 2K trim sheet can texture an entire architectural style. UV mapping uses strips, not islands. This reduces draw calls and maintains consistent texel density across the entire environment.
When
Texturing modular kits, optimizing material count, maintaining consistency
Example
// Trim sheet layout (2048x2048 example): // // [ Clean metal strip ] 256px height // [ Rusty metal strip ] 256px height // [ Edge/trim detail ] 128px height // [ Rivets/bolts strip ] 128px height // [ Worn wood strip ] 256px height // [ Clean wood strip ] 256px height // [ Stone/concrete ] 512px height // [ Damage/grunge ] 256px height
// UV mapping rules: // - Horizontal UVs stretch across sheet (0-1 U, tiles) // - Vertical UVs sample specific strip (fixed V position) // - Keep texel density: 512 px/m for hero, 256 px/m for background
// Master material setup: // - One material, one draw call // - Vertex color for variation (R=dirt, G=wear, B=damage)
---
Name
Color Scripting for Mood
Description
Create a "color script" before building - a sequence of color keys showing the emotional journey through your space. Warm colors advance, cool recede. Saturated colors draw attention; desaturated colors support. Limit palette to 3-4 dominant hues. Use complementary accents sparingly for maximum impact. The color script IS your mood blueprint.
When
Planning environment mood, establishing emotional beats, debugging flat feelings
Example
// Color script for a horror hospital level:
// ENTRANCE (false safety): // - Dominant: Warm white (6500K fluorescent) // - Secondary: Pale green (hospital walls) // - Accent: Red (exit signs, blood hints)
// CORRIDOR (growing dread): // - Dominant: Sickly yellow-green // - Secondary: Deep shadow blacks // - Accent: Flickering warm orange (broken lights)
// OPERATING ROOM (climax): // - Dominant: Cold surgical blue-white // - Secondary: Rust red (old blood, decay) // - Accent: Harsh white (spotlight on table)
// Color scripting workflow: // 1. Sketch level as simple rectangles // 2. Paint dominant color for each area // 3. Add emotional notes (safe, tense, terrifying) // 4. Use as reference during blockout AND final pass
---
Name
Vertex Color Variation System
Description
Vertex colors provide free texture variation at zero memory cost. Paint R, G, B, A channels to blend materials, add weathering, or create AO. In materials, use vertex color to lerp between clean/dirty, snow/ground, wet/dry. High-poly models during bake, then transfer to low-poly. Breaks tiling without additional textures.
When
Breaking up texture tiling, adding weathering, material transitions
Example
// Vertex color channel convention: // R = Dirt/grime amount (0=clean, 1=dirty) // G = Wear/damage amount (0=new, 1=worn) // B = Wetness/moisture (0=dry, 1=wet) // A = AO or height blend factor
// Material setup (Unreal/Unity): // // BaseColor = lerp(CleanAlbedo, DirtyAlbedo, VertexColor.R) // Roughness = lerp(CleanRough, WornRough, VertexColor.G) // Normal = lerp(BaseNormal, DamageNormal, VertexColor.G)
// Workflow: // 1. Create mesh with enough vertices to paint (add loops!) // 2. Paint vertex colors in DCC or in-engine // 3. Bake vertex AO for free shadowing // 4. Export with vertex colors enabled
---
Name
Environmental Storytelling Staging
Description
Every prop placement tells a story. Don't decorate - STAGE. Ask: Who was here? What were they doing? What happened? Cluster props into "story vignettes" - small scenes that imply narrative without exposition. Use the rule of 3: 3 related props form a scene (coffee cup + newspaper + reading glasses = person was here, reading, left suddenly).
When
Set dressing phase, adding narrative depth, making spaces feel lived-in
Example
// Story vignette examples:
// "Hasty escape" vignette: // - Overturned chair (facing door) // - Spilled coffee mug (liquid decal) // - Open newspaper (mid-article) // - Keys on floor (dropped, not placed)
// "Last stand" vignette: // - Barricaded door (furniture stacked) // - Scattered ammunition boxes // - Bloody handprint (on wall, at shoulder height) // - Radio (on, static - implies calling for help)
// Staging rules: // 1. Props face consistent direction (implies person's position) // 2. Damage patterns tell sequence (blood trail shows movement) // 3. Personal items reveal character (family photo = motivation) // 4. Anachronisms jar - keep era consistent // 5. Less is more - 3 deliberate props > 30 random ones
---
Name
Scale Reference and Human Metrics
Description
Include human-scale reference at EVERY stage. A door is 2.1m tall. A step is 18cm rise, 28cm run. A ceiling is 2.4-3m. Eye height is 1.7m. Without these, environments feel "off" in ways players can't articulate. Use mannequin references during blockout. Test navigation paths with actual player capsule.
When
Blockout phase, scale validation, debugging "feels wrong" feedback
Example
// Human metrics reference sheet (all in meters):
// Vertical measurements: // Average eye height: 1.7m // Door height: 2.1m (minimum), 2.4m (comfortable) // Ceiling height: 2.4m (cramped), 3.0m (normal), 4.0m+ (grand) // Step rise: 0.15-0.20m // Handrail height: 0.9-1.0m // Counter/table height: 0.9m (standing), 0.75m (sitting) // Chair seat: 0.45m
// Horizontal measurements: // Door width: 0.9m (single), 1.5m (double) // Corridor width: 1.2m (tight), 2.0m (comfortable) // Stair run: 0.28m per step // Combat space: 4m x 4m minimum per combatant
// Validation workflow: // 1. Drop mannequin/capsule in scene // 2. Walk through at player speed // 3. Check sightlines at eye height (not camera height!) // 4. Test: Can I take cover here? See over this? Fit through that?
---
Name
Composition Rules for Environment Framing
Description
Apply classical composition to 3D spaces. Rule of thirds for focal placement. Leading lines guide the eye (floor patterns, beams, pipes). Framing elements (doorways, arches, windows) direct attention. Foreground, midground, background layers create depth. The camera IS the player's eye - compose for their view.
When
Blocking out key vistas, placing hero assets, designing memorable moments
Example
// Composition techniques for environments:
// RULE OF THIRDS: // - Place hero prop at 1/3 or 2/3 point, not center // - Horizon at 1/3 (emphasize sky) or 2/3 (emphasize ground)
// LEADING LINES: // - Floor tile patterns point to objective // - Pipes/cables along ceiling guide to exit // - Blood trail leads to discovery // - Light beams cut through darkness to goal
// FRAMING: // - Doorway frames the vista beyond // - Arch creates "picture frame" for hero moment // - Columns create rhythm and direct eye movement
// DEPTH LAYERS: // - Foreground: Silhouette elements, frame the view // - Midground: Playable space, interactive elements // - Background: Context, vistas, skybox, establishes scale
// Vista checklist: // [ ] Clear focal point (squint test passes) // [ ] Leading lines present // [ ] Foreground/background separation // [ ] Human scale reference visible // [ ] Reward for looking (detail worth discovering)
---
Name
Biome Visual Language
Description
Each biome needs a consistent visual vocabulary: color palette, material set, silhouette language, vegetation style, atmospheric properties. Document this as a "biome bible." When assets cross biomes, blend them at transition zones. Biome consistency is what makes large worlds feel cohesive, not chaotic.
When
Designing open worlds, creating multiple distinct areas, establishing visual identity
Example
// Biome bible example - "Corrupted Forest":
// COLOR PALETTE: // - Dominant: Deep purple-black (corruption) // - Secondary: Sickly yellow-green (dying foliage) // - Accent: Bioluminescent cyan (fungal growths) // - Avoid: Healthy greens, warm browns
// MATERIALS: // - Trees: Blackened bark, glowing veins // - Ground: Cracked earth, purple ooze pools // - Rocks: Crystalline corruption growths // - Foliage: Wilted, twisted, sparse
// SILHOUETTES: // - Trees: Twisted, grasping, no healthy curves // - Rocks: Sharp, crystalline, unnatural geometry // - Creatures: Corrupted versions of normal fauna
// ATMOSPHERE: // - Fog: Low-lying, purple-tinted, volumetric // - Particles: Spores, ash, glowing motes // - Lighting: Dim ambient, harsh bioluminescence // - Skybox: Overcast, sickly green tinge
// TRANSITION TO HEALTHY FOREST: // - 50m blend zone // - Corruption lessens gradually // - Colors shift from purple to natural // - Mix of healthy and corrupted assets
Anti-Patterns
---
Name
Centering Everything
Description
Placing hero assets dead center of the composition
Why
Creates static, boring compositions. The eye has nowhere to travel. Real-world spaces have asymmetry. Centered compositions feel artificial and like game levels, not real places.
Instead
Use rule of thirds. Place heroes at 1/3 points. Create visual tension through asymmetry. Let one side be heavier than the other.
---
Name
Uniform Detail Distribution
Description
Spreading detail evenly across all surfaces
Why
Exhausts the eye. No rest areas, no focal points. Everything competes for attention, so nothing wins. Also wastes performance budget.
Instead
Hero areas get 80% of the detail budget. Secondary 15%. Fill 5%. Create visual "breathing room" with simple surfaces.
---
Name
Scale-less Blockout
Description
Gray-boxing without human reference metrics
Why
Without scale reference, artists build to "feeling" which varies wildly. Doorways end up 3m tall, steps too steep to animate, ceilings crushing. These proportions cement before anyone notices.
Instead
Drop a mannequin in EVERY blockout. Test navigation. Measure everything against human metrics. Fix scale issues in blockout, not production.
---
Name
One Material Per Asset
Description
Creating unique materials for each modular piece
Why
Destroys batching. A 500-piece kit with 500 materials = 500 draw calls. Also guarantees visual inconsistency as each piece develops independently.
Instead
Trim sheets and atlases. One master material per kit. Vertex colors for variation. 5-10 materials should cover an entire biome.
---
Name
Ignoring Negative Space
Description
Filling every corner with props and detail
Why
Creates visual noise. Players can't read the space. Important elements get lost. "Horror vacui" - fear of empty space - is an amateur mistake.
Instead
Let walls breathe. Use empty space to frame filled space. Negative space IS a design element. The pause between notes makes music.
---
Name
Texture-Only Storytelling
Description
Relying on textures (decals, overlays) instead of 3D staging
Why
Decals are flat. Players in 3D space need 3D narrative. A blood decal is less impactful than a blood trail leading to a slumped body. Texture storytelling breaks at oblique angles.
Instead
Stage 3D vignettes. Use props with physics (fallen chair, not chair decal). Decals support 3D storytelling, they don't replace it.
---
Name
Copy-Paste Without Variation
Description
Duplicating assets without rotation, scale, or material variation
Why
Human brains are pattern-detection machines. Identical repeated elements scream "fake" and break immersion. Even 5% variation hides repetition.
Instead
Rotate Z (90, 180, 270). Scale 95-105%. Vertex color variation. Mirror some instances. Random prop swaps within category.
---
Name
Art Before Gameplay
Description
Finalizing art before gameplay is locked
Why
Gameplay changes break art. Level design adjusts, your hero prop is now in a wall. Cover spots move, your pristine surface needs holes. Art rework is the most expensive rework.
Instead
Wait for gameplay lock. Use blockout that's cheap to change. Stage art production to follow gameplay milestones. Accept iteration is the job.
Environment Art - Sharp Edges
Envart Tiling Artifacts
Id
envart-tiling-artifacts
Summary
Visible texture tiling patterns destroying immersion
Severity
high
Situation
Large surfaces show obvious repeating patterns. Players see the "grid" where textures tile. Especially visible on floors, walls, and terrain.
Why
Seamless textures still have recognizable features that repeat. Human pattern recognition is incredibly strong - we evolved to spot repeating patterns (predator camouflage detection). Without breaking techniques, tiling is always visible on large surfaces.
Solution
Multiple approaches (use together for best results):
1. MACRO VARIATION LAYER: Overlay a large-scale grunge/color variation texture at 0.1x tiling rate. Blends via multiply or overlay.
2. STOCHASTIC TILING: Shader that randomly offsets and rotates each tile. Requires handling seam blending at tile boundaries.
3. VERTEX COLOR VARIATION: Paint vertex colors to blend between clean/dirty versions at random intervals.
4. DETAIL NORMAL BREAK-UP: Add a micro-detail normal at 10x tiling that adds noise to the surface, hiding macro repetition.
5. DECAL LAYERING: Strategic decal placement breaks pattern recognition. Dirt at corners, stains at random, damage where logical.
6. UV ROTATION: Rotate UVs 90 degrees on alternating pieces. Same texture, different orientation hides repetition.
Symptoms
- I can see where the texture repeats
- Grid pattern visible on floors
- Walls look like wallpaper
- Terrain has obvious squares
Detection Pattern
tiling.artifact|repeating.texture|visible.*seam
Version Range
all
Envart Scale Inconsistency
Id
envart-scale-inconsistency
Summary
Assets at wrong scale break spatial believability
Severity
critical
Situation
Door handles are fist-sized. Stairs are too steep to climb. Ceiling feels crushing. Props look toy-like or gigantic. "Something feels wrong" but can't articulate what.
Why
Without human reference during modeling, artists work to "feeling" rather than measurement. Each artist's intuition differs. Small errors compound: a door 10% too big means doorframe 10% too big, means wall 10% too big, means the whole building is wrong.
Solution
1. REFERENCE MANNEQUIN: Every scene needs a scale mannequin. Not hidden in a corner - visible in every viewport during work.
2. REAL-WORLD MEASUREMENT: Measure actual objects. Your door at home is 2.0-2.1m. Your ceiling is 2.4m. Your desk is 0.75m. Use these numbers.
3. MODELING CHECKLIST: Before export, check:
- Door: 2.1m tall, 0.9m wide
- Step: 0.18m rise, 0.28m run
- Ceiling: 2.4-3.0m from floor
- Counter: 0.9m height
- Handrail: 0.9-1.0m height
4. FIRST-PERSON CAMERA TEST: Walk through in-engine at player eye height (1.7m). Does it feel right? Can you see over counters? Under tables?
5. BLOCKOUT SIGN-OFF: Lock scale in blockout phase. Don't let production assets deviate. If blockout was wrong, fix it before art.
Symptoms
- Environment feels "off" but can't explain
- Players report motion sickness (scale affects proprioception)
- Animations don't fit (sitting through chairs, floating on beds)
- Doorways feel too small/large
Detection Pattern
scale.wrong|proportion.off|feels.weird|too.big|too.*small
Version Range
all
Envart Z Fighting
Id
envart-z-fighting
Summary
Flickering surfaces from co-planar geometry
Severity
high
Situation
Two surfaces at the same position flicker between each other. Decals z-fight with base geometry. Overlapping modular pieces show seams that appear and disappear as camera moves.
Why
Depth buffers have finite precision. When two surfaces are at "the same" depth, floating-point rounding means the winner varies per-pixel and per-frame. The closer to camera, and the larger the near-far ratio, the worse it gets.
Solution
1. OFFSET DECALS: Decals should be 0.01-0.1 units off the surface. Use polygon offset in shader if supported.
2. AVOID CO-PLANAR: Modular pieces shouldn't share the same plane. Inset wall panels by 2-4 units. Offset trim by 1-2 units.
3. CAMERA SETTINGS: Push near clip plane as far as possible (0.1m not 0.001m). Pull far clip in (1000m not 100000m).
4. 32-BIT DEPTH: If available, use 32-bit depth buffer instead of 24-bit. Significant precision improvement.
5. REVERSED-Z: Reverse depth buffer (1 at near, 0 at far) for better precision distribution. Most modern engines support this.
6. MERGE GEOMETRY: If two planes must touch, merge them into one mesh. No depth test within a single triangle.
Symptoms
- Flickering surfaces
- Decals appear to "swim" on surfaces
- Seams appear/disappear with camera movement
- Visual noise on distant co-planar objects
Detection Pattern
z-fight|flicker|co-?planar|depth.*fight
Version Range
all
Envart Collision Mismatch
Id
envart-collision-mismatch
Summary
Physics collision doesn't match visual geometry
Severity
critical
Situation
Player gets stuck on invisible geometry. Bullets hit nothing visible. Player walks through seemingly solid objects. Grenades bounce off air. AI navigation fails near complex geometry.
Why
Collision meshes are often auto-generated and not validated. High-poly visuals with simplified collision leave gaps. LOD switches change visual but not collision. Some platforms can't handle concave collision.
Solution
1. EXPLICIT COLLISION MESHES: Create simple collision geo by hand for hero and modular assets. Don't trust auto-generation.
2. COLLISION VISUALIZATION: Enable collision view in-engine. Walk through and verify visually before shipping.
3. CONVEX DECOMPOSITION: If engine requires convex collision, break complex shapes into convex pieces. Test the seams.
4. COLLISION NAMING: Use consistent naming (_collision, _UCX) so pipeline correctly identifies collision geo.
5. LOD COLLISION: Higher LODs should NOT have higher-detail collision. Collision is LOD-independent.
6. PLAYTEST PROTOCOL: Every environment needs a collision walkthrough. Hug every wall. Jump on every surface. Throw projectiles at edges.
Symptoms
- I got stuck on nothing
- Invisible walls
- Walking through solid objects
- Projectiles hit invisible barriers
- AI pathing failures near complex geo
Detection Pattern
collision.mismatch|stuck.invisible|walk.through|hit.nothing
Version Range
all
Envart Draw Call Explosion
Id
envart-draw-call-explosion
Summary
Too many draw calls killing frame rate
Severity
critical
Situation
Frame rate tanks in dense environments. GPU profiler shows draw call count in thousands. Modular environments especially affected. Each unique material/mesh combination adds draw calls.
Why
Each material instance on each mesh is a draw call. 100 props with 10 materials each = potentially 1000 draw calls. Modular environments multiply this: 500 wall pieces x unique materials = GPU stall.
Solution
1. MATERIAL ATLASING: One material per kit. Trim sheets, texture atlases. 500 modular pieces, 1 material = batchable.
2. MESH MERGING: Combine static geo in-engine. Unreal: Merge Actors. Unity: Static Batching. Trade memory for draw calls.
3. INSTANCING: Same mesh + same material = 1 draw call with instancing. Enable GPU instancing on materials. Use instanced foliage.
4. LOD AGGRESSIVENESS: Aggressive LOD reduces both poly count AND draw calls (simpler meshes = more batching opportunity).
5. OCCLUSION CULLING: Don't draw what's not visible. Bake occlusion. Use manual occluder volumes in complex areas.
6. HIERARCHICAL DETAIL: Group props into "set dressing islands" that cull as a unit. One bounds check instead of 50.
7. MATERIAL COMPLEXITY: Simpler shaders draw faster. Background assets don't need 20-layer materials.
Symptoms
- Low FPS in dense areas
- GPU bound (CPU waiting on GPU)
- Draw call count in profiler > 2000
- Frame time spikes when looking at detailed areas
Detection Pattern
draw.call|batch.fail|too.many.materials|fps.*drop
Version Range
all
Envart Over Cluttering
Id
envart-over-cluttering
Summary
Too much detail destroys visual readability
Severity
high
Situation
Every surface has detail. Every corner has props. The eye has nowhere to rest. Important gameplay elements get lost. Screenshots look noisy. Players report feeling overwhelmed or anxious.
Why
"Horror vacui" - fear of empty space - leads to filling every gap. Each artist adds "just one more thing." Without clear hierarchy, visual noise accumulates. What should be supporting detail becomes competing noise.
Solution
1. THE SQUINT TEST: Blur your eyes. Is there a clear focal point? If not, remove detail until there is.
2. 80/20 RULE: 80% of player attention goes to 20% of the space. That 20% gets the detail. The other 80% supports it.
3. NEGATIVE SPACE: Empty space is design. The gap between props is as important as the props. Let walls breathe.
4. DETAIL BUDGET: Set a prop budget per square meter. Kitchen: 5 props/m2. Hallway: 1 prop/m2. Stick to it.
5. HIERARCHY ENFORCEMENT: Mark each prop as Primary, Secondary, or Fill. If ratio isn't 1:3:6, you have too many primaries.
6. REMOVE THEN ADD: Start with nothing. Add only what's necessary. It's easier to add than remove (sunk cost fallacy).
7. PLAYTESTER EYES: Watch new players. Where do they look? If they miss critical info, remove clutter around it.
Symptoms
- I can't find the [objective]
- Screenshots look messy
- Players report fatigue in detailed areas
- Gameplay elements get lost
Detection Pattern
too.much.detail|cluttered|can.t.find|visual.*noise
Version Range
all
Envart Pivot Origin
Id
envart-pivot-origin
Summary
Wrong pivot points break modular snapping
Severity
critical
Situation
Modular pieces don't snap together cleanly. Small gaps appear between wall segments. Floor tiles offset by tiny amounts. Artists spend hours manually adjusting positions that should auto-align.
Why
Game engines import pivot points based on model origin (0,0,0) in the DCC tool. If your mesh isn't positioned correctly relative to origin, the in-engine pivot will be wrong. Center pivot = center snapping, not corner snapping. Modular kits MUST have corner pivots.
Solution
1. CORNER PIVOT WORKFLOW:
- Model asset at any location
- Move mesh so bottom-left-front corner is at origin (0,0,0)
- Do NOT move pivot (pivot stays at origin)
- Export - engine receives mesh with corner at pivot
2. DCC SETUP: In Maya/Max/Blender, make the grid visible and snap vertices to grid before export. Use power-of-2 grid size.
3. VALIDATION SCRIPT: Write export validation that checks:
- Asset bounding box starts at or near origin
- Dimensions are power-of-2 friendly
- No geometry in negative coordinates
4. IN-ENGINE TEST: Drop two pieces side by side. Snap by pivot. Zero gap = correct. Any gap = pivot is wrong.
5. PIVOT CONVENTION: Document your convention. All walls: bottom-left. All floors: center. All props: base center. Consistency is key.
Symptoms
- Gaps between modular pieces
- Pieces overlap when snapped
- Manual adjustment constantly needed
- The pivot is in the wrong place
Detection Pattern
pivot.wrong|snap.not.work|gap.between|modular.*offset
Version Range
all
Envart Memory Budget
Id
envart-memory-budget
Summary
Textures and meshes exceeding memory budget
Severity
high
Situation
Level fails to load on target platform. Texture streaming stutters. Out of memory crashes. VRAM budget exceeded. Console certification fails due to memory usage.
Why
Art teams work on powerful workstations. What runs on 32GB + 12GB VRAM doesn't run on a console with 8GB unified. Each 4K texture is 64MB uncompressed. Meshes with millions of triangles add up. No one tracks budget until it's too late.
Solution
1. PLATFORM BUDGETS: Know your target early:
- PS5/Xbox Series: ~5GB for textures, ~2GB for meshes (rough)
- PS4/Xbox One: ~2GB textures, ~1GB meshes
- Mobile: ~256MB textures, ~128MB meshes
- Set level budgets from these.
2. TEXTURE SIZE DISCIPLINE:
- Hero assets: 2K (2048x2048)
- Secondary: 1K (1024x1024)
- Props: 512x512
- Background: 256x256
- Trim sheets: 2K shared across kit
3. STREAMING PRIORITY: Not everything needs full-res at once. Background elements can stream in lower. Prioritize what's close.
4. LOD MESH REDUCTION: LOD0 full poly. LOD1 50%. LOD2 25%. LOD3 10%. Aggressive transition distances.
5. SHARED RESOURCES: One dirt decal atlas, not 50 dirt decals. One sky HDRI, not per-level. One foliage atlas per biome.
6. PROFILING ROUTINE: Check memory usage weekly during production. Don't wait for end. Overages caught early are fixable.
Symptoms
- Out of memory crashes
- Texture pop-in/streaming issues
- Console certification failures
- Slow level loading
Detection Pattern
memory.budget|out.of.memory|texture.too.*large|VRAM
Version Range
all
Envart Non Power Of 2
Id
envart-non-power-of-2
Summary
Non-power-of-2 textures causing waste and artifacts
Severity
medium
Situation
Textures sized 1000x1000 or 2000x1500. GPU padding wastes memory. Mipmap generation fails or produces artifacts. Compression formats don't work correctly. Older hardware refuses to load.
Why
GPUs are optimized for power-of-2 dimensions (256, 512, 1024, 2048). Non-POT textures get padded to next POT, wasting memory. Some compression formats (BC/DXT) require POT or multiple-of-4. Mipmaps halve dimensions - non-POT creates odd sizes.
Solution
1. ALWAYS POT: 256, 512, 1024, 2048, 4096. No exceptions. Non-square is fine (1024x512) as long as both dimensions are POT.
2. VALIDATION SCRIPT: Check texture dimensions on export/import. Flag any non-POT textures.
3. RESIZE, DON'T PAD: If source is 1000x1000, resize to 1024x1024. Don't let the engine pad it (you control quality loss, not the engine).
4. TRIM SHEET PLANNING: Design trim sheets to POT from the start. Not "whatever fits" - exactly 2048x2048 with planned strip heights.
5. ATLAS OPTIMIZATION: Pack atlases to exactly fill POT dimensions. Wasted atlas space = wasted memory.
Symptoms
- Unexplained memory usage
- Mipmap artifacts
- Compression failures
- "Texture dimensions not supported" errors
Detection Pattern
non.power.of.2|texture.size|mipmap.*artifact|padding
Version Range
all
Envart Skybox Seams
Id
envart-skybox-seams
Summary
Visible seams in skybox at cube edges
Severity
medium
Situation
When looking up or at horizon, visible lines appear at skybox cube edges. Seams are more visible at certain times of day. Clouds don't wrap correctly. Stars show obvious grid.
Why
Cubemap skyboxes have 6 faces that must align perfectly. Any color difference at edges is visible. Filtering at edges can sample the wrong face. Procedural elements (clouds, stars) may not tile across edges.
Solution
1. HDRI CAPTURE: Use spherical HDRI projected to cubemap. Natural scenes don't have edges. Re-project at highest quality.
2. EDGE SAMPLING: Enable seamless cubemap sampling in shader. Most engines have this option - ensure it's on.
3. PROCEDURAL WRAPPING: Procedural clouds/stars must wrap. Test by rotating 90 degrees on each axis - seams should never appear.
4. MANUAL TOUCH-UP: In Photoshop, manually paint over seam areas across unfolded cubemap. Match colors exactly.
5. HIGHER RESOLUTION: Seams are more visible in low-res cubemaps. 4K per face minimum for production. 8K for hero moments.
6. AVOID SKYBOX FOCUS: If seam fixing is hard, don't let players look directly at it. Use terrain/geometry to obscure horizon.
Symptoms
- Visible lines in sky
- Seams at cube edges
- Clouds cutting off at edges
- Stars showing grid pattern
Detection Pattern
skybox.seam|cube.edge|sky.line|visible.edge
Version Range
all
Envart Lightmap Bleeding
Id
envart-lightmap-bleeding
Summary
Light bleeding through walls in baked lighting
Severity
high
Situation
Light from outside appears inside. Dark rooms have unexplained bright spots on walls. Colors from adjacent areas bleed through. Shadows have bright halos.
Why
Lightmap UV islands need padding to prevent texture filtering from sampling adjacent islands. If padding is insufficient, the lightmap bake bleeds across UV boundaries. Also, geometry without thickness allows light through.
Solution
1. UV ISLAND PADDING: Minimum 4 texels padding at lowest mip level. For 512 lightmap, that's about 0.8% UV space per edge.
2. GEOMETRY THICKNESS: Walls must have thickness (32+ units). Single- sided planes are never lightmap-safe.
3. LIGHTMASS SETTINGS (Unreal): Increase Lightmass UV padding, reduce indirect lighting smoothness near corners.
4. BLOCKING VOLUMES: Add invisible blocking geometry to prevent light from sources that shouldn't reach areas.
5. LIGHTMAP RESOLUTION: Higher resolution reduces apparent bleeding. But also increases memory and bake time.
6. MANUAL OVERRIDE: For problem areas, use light channels or manual lighting masks to isolate light influence.
Symptoms
- Light appearing through solid walls
- Unexplained bright spots in dark rooms
- Color bleeding from adjacent areas
- Shadows with bright edges
Detection Pattern
light.bleed|light.through.wall|lightmap.issue|bake.*artifact
Version Range
all
Envart Vertex Density Insufficient
Id
envart-vertex-density-insufficient
Summary
Not enough vertices for vertex color painting
Severity
medium
Situation
Vertex color painting is blocky, not smooth. Transitions between painted areas are harsh. Low-poly meshes can't hold enough vertex color data for smooth blending.
Why
Vertex colors interpolate linearly between vertices. If vertices are far apart, the interpolation is visible as banding. More vertices = smoother gradients. But more vertices = more memory and draw cost.
Solution
1. TESSELLATION FOR PAINTING: Add edge loops specifically for vertex color resolution. Paint, then bake to texture if needed.
2. TEXTURE FALLBACK: For smooth gradients on low-poly, use a texture instead of vertex colors. Vertex colors for broad variation, texture for fine gradients.
3. STRATEGIC DENSITY: Add vertices where color transitions happen (base of walls, edges of weathering zones) not uniformly.
4. VERTEX AO DENSITY: Vertex AO needs vertices in shadow casters. Corners need extra vertices for proper darkening.
5. HYBRID APPROACH: Coarse variation via vertex color, fine variation via procedural texture. Combine in material.
Symptoms
- Blocky vertex color painting
- Visible interpolation banding
- Can't paint fine detail
- AO looks faceted
Detection Pattern
vertex.color.blocky|paint.*interpolation|banding
Version Range
all
Environment Art - Validations
Non-Power-of-2 Texture Dimensions
Id
envart-non-pot-texture
Severity
warning
Type
regex
Pattern
- size["\s:=]+\[?\s\d[13579]\d\s[,x]\s*\d+
- width["\s:=]+\d*[13579]\d+[^\d]
- height["\s:=]+\d*[13579]\d+[^\d]
- resolution["\s:=]+\d*[13579]\d+
Message
Texture dimensions should be power-of-2 (256, 512, 1024, 2048, 4096). Non-POT textures waste memory due to GPU padding and may cause mipmap artifacts.
Fix Action
Resize textures to nearest power-of-2 dimensions (e.g., 1000x1000 -> 1024x1024)
Applies To
- *.meta
- *.asset
- *.uasset
- *.json
- *.yaml
- *.xml
Oversized Textures
Id
envart-excessive-texture-size
Severity
warning
Type
regex
Pattern
- (?:4096|8192)\s[,x]\s(?:4096|8192)
- size["\s:=]+8192
- maxSize["\s:=]+8192
Message
4K+ textures should be reserved for hero assets only. Most props and modular pieces should use 1K-2K textures. Check if this resolution is necessary.
Fix Action
Consider reducing to 2048x2048 unless this is a hero asset or trim sheet
Applies To
- *.meta
- *.asset
- *.json
- *.yaml
Missing LOD Configuration
Id
envart-no-lod-defined
Severity
warning
Type
regex
Pattern
- LODGroup["\s:=]+None
- enableLOD["\s:=]+false
- lodCount["\s:=]+1[^\d]
- NumLODs["\s:=]+1[^\d]
Message
Static meshes should have multiple LOD levels defined for performance. Single LOD assets don't scale with distance, wasting GPU resources.
Fix Action
Generate LOD levels: LOD0 (full), LOD1 (50%), LOD2 (25%), LOD3 (10%)
Applies To
- *.meta
- *.asset
- *.uasset
- *.fbx.meta
Missing Collision on Static Mesh
Id
envart-collision-disabled
Severity
error
Type
regex
Pattern
- generateColliders["\s:=]+false
- collisionEnabled["\s:=]+false
- bEnableCollision["\s:=]+false
- hasCollision["\s:=]+false
Message
Static meshes without collision can cause gameplay issues - players walking through walls, projectiles passing through objects, AI navigation failures.
Fix Action
Enable collision or create explicit collision mesh for static environment assets
Applies To
- *.meta
- *.asset
- *.uasset
Uncompressed Textures
Id
envart-uncompressed-texture
Severity
warning
Type
regex
Pattern
- compression["\s:=]+(?:None|Uncompressed|RGBA32)
- textureFormat["\s:=]+RGBA32
- CompressionSettings["\s:=]+TC_Default\s*$
Message
Uncompressed textures waste significant memory. Most textures should use BC/DXT compression (desktop) or ASTC/ETC (mobile).
Fix Action
Enable texture compression: BC7/BC1 for color, BC5 for normals
Applies To
- *.meta
- *.asset
- *.uasset
Mipmaps Disabled
Id
envart-missing-mipmaps
Severity
warning
Type
regex
Pattern
- generateMipMaps["\s:=]+false
- mipmapEnabled["\s:=]+false
- MipGenSettings["\s:=]+TMGS_NoMipmaps
- useMipMap["\s:=]+0
Message
Mipmaps should be enabled for 3D textures. Without mipmaps, textures shimmer at distance (aliasing) and waste GPU bandwidth sampling full-res at all distances.
Fix Action
Enable mipmap generation unless this is a UI or 2D sprite texture
Applies To
- *.meta
- *.asset
- *.uasset
Too Many Materials on Mesh
Id
envart-excessive-material-count
Severity
warning
Type
regex
Pattern
- materialCount["\s:=]+(?:[5-9]|[1-9]\d+)
- Materials\.Length["\s:=]+(?:[5-9]|[1-9]\d+)
- numMaterials["\s:=]+(?:[5-9]|[1-9]\d+)
Message
Meshes with 5+ materials increase draw calls. Consider using texture atlases or trim sheets to reduce material count for better batching.
Fix Action
Consolidate materials using atlases; aim for 1-3 materials per mesh
Applies To
- *.meta
- *.asset
- *.fbx.meta
Inconsistent Lightmap Resolution
Id
envart-lightmap-resolution-mismatch
Severity
warning
Type
regex
Pattern
- lightmapResolution["\s:=]+(?:4|8|16)[^\d]
- LightmapRes["\s:=]+(?:4|8|16)[^\d]
Message
Very low lightmap resolution (4-16) may cause light bleeding and poor shadow quality. Minimum 32 for small props, 64-128 for modular pieces, 256+ for large surfaces.
Fix Action
Increase lightmap resolution to at least 32, or higher for visible surfaces
Applies To
- *.meta
- *.asset
- *.uasset
Static Batching Not Enabled
Id
envart-static-batching-disabled
Severity
warning
Type
regex
Pattern
- staticBatchingEnabled["\s:=]+false
- bEnableStaticMesh["\s:=]+false
- staticFlags["\s:=]+0
Message
Static environment meshes should use static batching for reduced draw calls. Enable static batching flags on non-moving environment geometry.
Fix Action
Enable static batching/static mesh flags for immobile environment assets
Applies To
- *.meta
- *.asset
- *.unity
- *.prefab
Occlusion Culling Not Configured
Id
envart-no-occlusion
Severity
warning
Type
regex
Pattern
- occlusionCulling["\s:=]+false
- bUseAsOccluder["\s:=]+false
- occluderEnabled["\s:=]+false
Message
Large environment meshes (walls, floors, large props) should participate in occlusion culling to prevent rendering of hidden geometry.
Fix Action
Enable occluder flags on large blocking geometry (walls, floors, pillars)
Applies To
- *.meta
- *.asset
- *.uasset
- *.prefab
Single-Sided Geometry Warning
Id
envart-single-sided-geo
Severity
warning
Type
regex
Pattern
- doubleSided["\s:=]+false
- twoSided["\s:=]+false
- cullMode["\s:=]+Back
Message
Single-sided geometry is correct for performance but ensure walls and enclosed spaces have thickness. Paper-thin walls cause light bleeding.
Fix Action
Verify walls have thickness (32+ units) or enable double-sided for foliage/cloth
Applies To
- *.mat
- *.material
- *.uasset
Mesh Without Vertex Colors
Id
envart-missing-vertex-colors
Severity
info
Type
regex
Pattern
- hasVertexColors["\s:=]+false
- vertexColorCount["\s:=]+0
- ImportVertexColors["\s:=]+false
Message
Consider using vertex colors for material variation (dirt, wear, wetness) without additional texture cost. Especially useful for modular pieces.
Fix Action
Enable vertex color import if using vertex-based material variation
Applies To
- *.meta
- *.fbx.meta
Very High Polygon Count
Id
envart-excessive-poly-count
Severity
warning
Type
regex
Pattern
- triangleCount["\s:=]+(?:\d{6,})
- polyCount["\s:=]+(?:\d{6,})
- numTriangles["\s:=]+(?:\d{6,})
Message
Meshes with 1M+ triangles are expensive. Ensure proper LOD setup and consider if this density is visible at gameplay distances.
Fix Action
Add aggressive LODs or reduce base polygon count if not hero asset
Applies To
- *.meta
- *.asset
- *.fbx.meta
UV Channel Configuration Issue
Id
envart-unoptimized-uv
Severity
warning
Type
regex
Pattern
- generateSecondaryUV["\s:=]+false.*lightmap
- lightmapUVChannel["\s:=]+-1
- hasLightmapUVs["\s:=]+false
Message
Lightmapped meshes need a second UV channel for lightmap UVs. Without dedicated lightmap UVs, baking will produce artifacts.
Fix Action
Generate secondary UVs for lightmapping or use UV2 in DCC tool
Applies To
- *.meta
- *.fbx.meta
- *.asset
Expensive Alpha Blend on Environment
Id
envart-alpha-blend-opaque
Severity
warning
Type
regex
Pattern
- renderMode["\s:=]+(?:Transparent|Fade)
- blendMode["\s:=]+Translucent
- alphaBlend["\s:=]+true
Message
Transparent materials are expensive and don't write depth. Use alpha cutoff (alpha test) instead of alpha blend for foliage and masked surfaces.
Fix Action
Switch from Transparent to Cutout/AlphaTest for foliage and fences
Applies To
- *.mat
- *.material
- *.uasset
Material Without Normal Map
Id
envart-missing-normal-map
Severity
info
Type
regex
Pattern
- normalMap["\s:=]+null
- _BumpMap["\s:=]+\{\s*\}
- hasNormalTexture["\s:=]+false
Message
Environment materials typically benefit from normal maps for surface detail. Ensure normal maps are assigned unless intentionally flat (stylized art).
Fix Action
Add normal map texture or explicitly note if flat style is intentional
Applies To
- *.mat
- *.material
Extreme Draw Distance Configuration
Id
envart-excessive-draw-distance
Severity
warning
Type
regex
Pattern
- cullingDistance["\s:=]+(?:\d{5,})
- maxDrawDistance["\s:=]+(?:\d{5,})
- farClip["\s:=]+100000
Message
Very high draw distances (10000+ units) can hurt performance and depth buffer precision. Most environment assets should cull at reasonable distances.
Fix Action
Set appropriate cull distances: props (5000), structures (10000), terrain (far)
Applies To
- *.meta
- *.asset
- *.uasset
- *.prefab