[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7CS0MMQC50RNWEKSS85KG6T":3,"skill-same:01M7CS0MMQC50RNWEKSS85KG6T":50},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":27,"commitSha":28,"skillDirectory":29,"forksCount":30,"repositoryHtmlUrl":31,"repositoryHomepageUrl":32,"ownerHtmlUrl":33,"ownerBlogUrl":6,"ownerDescription":34,"updatedAt":35,"install":36,"resources":49},"01M7CS0MMQC50RNWEKSS85KG6T","game-asset-pipeline",null,"Use when adding, importing, moving or loading textures, models, audio or scenes - per-platform compression, atlases, LODs, async loading per engine, engine metadata files (.meta, .import, .uid, .uasset), Git LFS, and asset validation tests.","makifbaysal\u002Ftasktrooper","makifbaysal","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F25031940?v=4","01M7CRG3ZCSYZSSEVDMW3DEYC8","Mehmet Akif Baysal","01M7CRG401FJ8YAXH5ER730XYV",122,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fgame-developer\u002Fskills\u002Fgame-asset-pipeline\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: game-asset-pipeline\ncategory: assets\ndescription: Use when adding, importing, moving or loading textures, models, audio or scenes - per-platform compression, atlases, LODs, async loading per engine, engine metadata files (.meta, .import, .uid, .uasset), Git LFS, and asset validation tests.\ntech_stack: Game core\nsource: informed by the Unity, Godot, Unreal, three.js, Babylon.js and Khronos KTX\u002FglTF docs; own wording\n---\n# Game Asset Pipeline\n\n## Overview\n\nAssets are most of a game's size, most of its load time and most of its memory. They also come with engine metadata that silently breaks references when it is lost: a Unity `.meta` regenerated with a new GUID unhooks every prefab that used the asset. Treat assets like code — reviewed import settings, committed metadata, validated by tests.\n\n**Core principle:** Compressed for the target platform, loaded asynchronously, committed with its metadata, and never moved outside the engine that owns its references.\n\n## Metadata files — commit them, never orphan them\n\n| Engine | Files | Rule |\n|---|---|---|\n| Unity | `\u003Casset>.meta` (GUID + import settings) beside every asset and folder | Commit with the asset; move\u002Frename inside the Editor or move the `.meta` with it; never delete and regenerate |\n| Godot 4 | `\u003Casset>.import` beside imported assets; `.uid` beside scripts and shaders (4.4+); `.godot\u002F` cache | Commit `.import` and `.uid`; ignore `.godot\u002F` |\n| Unreal | `.uasset` \u002F `.umap` (binary, references by path) | Move\u002Frename only in the Editor, then \"Fix Up Redirectors\"; lock binaries (LFS `lockable`) |\n| Web \u002F Bevy | none | Paths are code — update every reference in the same change |\n\nMoving a file with `mv` in a Unity or Unreal project without its metadata (or outside the editor) is a broken-reference bug even if the build is green.\n\n## Git LFS\n\n- Check `.gitattributes` first; follow the patterns it already has. Typical: `*.png *.psd *.fbx *.glb *.wav *.ogg *.uasset *.umap filter=lfs diff=lfs merge=lfs -text`, with `lockable` for Unreal binaries.\n- A new binary type the repository does not track yet gets its pattern added in the same change — not a 40 MB `.fbx` committed as a regular blob.\n- `git lfs ls-files` shows what is tracked; if `git lfs` is not installed here, say so instead of committing pointers by hand.\n\n## Textures\n\n| Target | Format |\n|---|---|\n| Desktop \u002F console | BC7 (colour), BC5 (normal maps), BC4 (single channel) |\n| Modern mobile | ASTC (block size by quality: 4×4 UI, 6×6–8×8 world) |\n| Android fallback | ETC2 |\n| Web | KTX2 \u002F Basis Universal (transcoded per GPU at load), WebP\u002FAVIF for UI and 2D |\n\n- Unity: per-platform overrides in the importer; max size per platform; mipmaps on for world textures, off for UI and pixel art; Sprite Atlas for 2D.\n- Godot: \"VRAM Compressed\" for 3D (enable ETC2\u002FASTC import in project settings for mobile), \"Lossless\" with filtering off for pixel art; AtlasTexture\u002FTileSet for 2D.\n- Unreal: texture groups and compression settings (`TC_Default`, `TC_Normalmap`, `TC_Masks`), LOD bias per platform.\n- Web: KTX2 via three.js `KTX2Loader` \u002F Babylon's KTX2 support; packed atlases (TexturePacker JSON) for Phaser\u002FPixiJS.\n- Power-of-two sizes where mipmaps or block compression need them; no 4K texture on a 64-pixel prop.\n\n## Meshes and scenes\n\n- LODs for anything seen at a distance: Unity `LODGroup`, Godot automatic mesh LOD on import, Unreal Nanite for static meshes where the platform supports it and classic LODs elsewhere (skeletal meshes, mobile).\n- Web: glTF\u002FGLB with Draco or meshopt geometry compression and KTX2 textures — `npx @gltf-transform\u002Fcli optimize in.glb out.glb` is a quick win; check the repository's pipeline first.\n- Colliders are simplified shapes, not render meshes.\n\n## Audio\n\n- Compressed (Vorbis\u002FOpus\u002FAAC); music streamed, short frequent SFX decompressed on load.\n- Unity: Load Type per clip (Streaming for music, Decompress On Load for short SFX); Godot: `.ogg` for music, `.wav` for short SFX; web: a format every target browser decodes, and an audio-unlock on the first user gesture.\n\n## Loading without hitches\n\n```csharp\n\u002F\u002F ❌ synchronous load mid-gameplay: a visible hitch, and Resources\u002F ships everything\nvar prefab = Resources.Load\u003CGameObject>(\"Enemies\u002FBoss\");\n\n\u002F\u002F ✅ async, released when done (Addressables)\nvar handle = Addressables.LoadAssetAsync\u003CGameObject>(\"enemies\u002Fboss\");\nvar prefab = await handle.Task;\n\u002F\u002F ... later, when the level unloads:\nAddressables.Release(handle);\n```\n\n```gdscript\n# Godot: threaded load at a loading screen or ahead of need\nResourceLoader.load_threaded_request(LEVEL_PATH)\n# poll in _process:\nif ResourceLoader.load_threaded_get_status(LEVEL_PATH) == ResourceLoader.THREAD_LOAD_LOADED:\n    var scene: PackedScene = ResourceLoader.load_threaded_get(LEVEL_PATH)\n```\n\n- Unreal: soft references (`TSoftObjectPtr`, `TSoftClassPtr`) with `UAssetManager` \u002F `FStreamableManager::RequestAsyncLoad`; avoid hard references in Blueprints that pull whole asset graphs into memory.\n- Web: Phaser's loader in a preload scene, PixiJS `Assets.loadBundle`, three.js `LoadingManager`; code-split per level.\n- Bevy: `AssetServer::load` returns a handle immediately; gate the state change on the load state (or the repository's loading plugin).\n\n## Validating assets in tests\n\nAn import-settings test fails the build when someone drops in an uncompressed 4K texture:\n\n```csharp\n[Test] public void WorldTextures_AreCompressedAndCapped() {\n    foreach (var guid in AssetDatabase.FindAssets(\"t:Texture2D\", new[] { \"Assets\u002F_Project\u002FArt\u002FWorld\" })) {\n        var path = AssetDatabase.GUIDToAssetPath(guid);\n        var importer = (TextureImporter)AssetImporter.GetAtPath(path);\n        Assert.That(importer.maxTextureSize, Is.LessThanOrEqualTo(2048), path);\n        Assert.That(importer.textureCompression, Is.Not.EqualTo(TextureImporterCompression.Uncompressed), path);\n    }\n}\n```\n\nThe same idea elsewhere: a Godot test reading `.import` files under `res:\u002F\u002Fart\u002Fworld`, a Node script checking `public\u002F` sizes and formats, a data-validation rule in Unreal.\n\n## Common Mistakes\n\n- Moving or renaming assets with `mv` and losing `.meta` GUIDs or Unreal references.\n- Committing Godot's `.godot\u002F` cache or Unreal's `Intermediate\u002F`, `Saved\u002F`, `DerivedDataCache\u002F`, `Binaries\u002F`.\n- Uncompressed or oversized textures; mipmaps on UI sprites.\n- `Resources.Load` \u002F synchronous `load()` during gameplay.\n- Loaded assets never released (Addressables handles, three.js textures) — memory grows every level.\n\n## Red Flags\n\n- A new binary file in the diff that is not covered by `.gitattributes` LFS patterns the repo uses.\n- An asset in the diff without its `.meta` \u002F `.import`, or a `.meta` with a changed GUID.\n- A hitch report and a synchronous load in the same code path.\n","# Game Asset Pipeline\n\n## Overview\n\nAssets are most of a game's size, most of its load time and most of its memory. They also come with engine metadata that silently breaks references when it is lost: a Unity `.meta` regenerated with a new GUID unhooks every prefab that used the asset. Treat assets like code — reviewed import settings, committed metadata, validated by tests.\n\n**Core principle:** Compressed for the target platform, loaded asynchronously, committed with its metadata, and never moved outside the engine that owns its references.\n\n## Metadata files — commit them, never orphan them\n\n| Engine | Files | Rule |\n|---|---|---|\n| Unity | `\u003Casset>.meta` (GUID + import settings) beside every asset and folder | Commit with the asset; move\u002Frename inside the Editor or move the `.meta` with it; never delete and regenerate |\n| Godot 4 | `\u003Casset>.import` beside imported assets; `.uid` beside scripts and shaders (4.4+); `.godot\u002F` cache | Commit `.import` and `.uid`; ignore `.godot\u002F` |\n| Unreal | `.uasset` \u002F `.umap` (binary, references by path) | Move\u002Frename only in the Editor, then \"Fix Up Redirectors\"; lock binaries (LFS `lockable`) |\n| Web \u002F Bevy | none | Paths are code — update every reference in the same change |\n\nMoving a file with `mv` in a Unity or Unreal project without its metadata (or outside the editor) is a broken-reference bug even if the build is green.\n\n## Git LFS\n\n- Check `.gitattributes` first; follow the patterns it already has. Typical: `*.png *.psd *.fbx *.glb *.wav *.ogg *.uasset *.umap filter=lfs diff=lfs merge=lfs -text`, with `lockable` for Unreal binaries.\n- A new binary type the repository does not track yet gets its pattern added in the same change — not a 40 MB `.fbx` committed as a regular blob.\n- `git lfs ls-files` shows what is tracked; if `git lfs` is not installed here, say so instead of committing pointers by hand.\n\n## Textures\n\n| Target | Format |\n|---|---|\n| Desktop \u002F console | BC7 (colour), BC5 (normal maps), BC4 (single channel) |\n| Modern mobile | ASTC (block size by quality: 4×4 UI, 6×6–8×8 world) |\n| Android fallback | ETC2 |\n| Web | KTX2 \u002F Basis Universal (transcoded per GPU at load), WebP\u002FAVIF for UI and 2D |\n\n- Unity: per-platform overrides in the importer; max size per platform; mipmaps on for world textures, off for UI and pixel art; Sprite Atlas for 2D.\n- Godot: \"VRAM Compressed\" for 3D (enable ETC2\u002FASTC import in project settings for mobile), \"Lossless\" with filtering off for pixel art; AtlasTexture\u002FTileSet for 2D.\n- Unreal: texture groups and compression settings (`TC_Default`, `TC_Normalmap`, `TC_Masks`), LOD bias per platform.\n- Web: KTX2 via three.js `KTX2Loader` \u002F Babylon's KTX2 support; packed atlases (TexturePacker JSON) for Phaser\u002FPixiJS.\n- Power-of-two sizes where mipmaps or block compression need them; no 4K texture on a 64-pixel prop.\n\n## Meshes and scenes\n\n- LODs for anything seen at a distance: Unity `LODGroup`, Godot automatic mesh LOD on import, Unreal Nanite for static meshes where the platform supports it and classic LODs elsewhere (skeletal meshes, mobile).\n- Web: glTF\u002FGLB with Draco or meshopt geometry compression and KTX2 textures — `npx @gltf-transform\u002Fcli optimize in.glb out.glb` is a quick win; check the repository's pipeline first.\n- Colliders are simplified shapes, not render meshes.\n\n## Audio\n\n- Compressed (Vorbis\u002FOpus\u002FAAC); music streamed, short frequent SFX decompressed on load.\n- Unity: Load Type per clip (Streaming for music, Decompress On Load for short SFX); Godot: `.ogg` for music, `.wav` for short SFX; web: a format every target browser decodes, and an audio-unlock on the first user gesture.\n\n## Loading without hitches\n\n```csharp\n\u002F\u002F ❌ synchronous load mid-gameplay: a visible hitch, and Resources\u002F ships everything\nvar prefab = Resources.Load\u003CGameObject>(\"Enemies\u002FBoss\");\n\n\u002F\u002F ✅ async, released when done (Addressables)\nvar handle = Addressables.LoadAssetAsync\u003CGameObject>(\"enemies\u002Fboss\");\nvar prefab = await handle.Task;\n\u002F\u002F ... later, when the level unloads:\nAddressables.Release(handle);\n```\n\n```gdscript\n# Godot: threaded load at a loading screen or ahead of need\nResourceLoader.load_threaded_request(LEVEL_PATH)\n# poll in _process:\nif ResourceLoader.load_threaded_get_status(LEVEL_PATH) == ResourceLoader.THREAD_LOAD_LOADED:\n    var scene: PackedScene = ResourceLoader.load_threaded_get(LEVEL_PATH)\n```\n\n- Unreal: soft references (`TSoftObjectPtr`, `TSoftClassPtr`) with `UAssetManager` \u002F `FStreamableManager::RequestAsyncLoad`; avoid hard references in Blueprints that pull whole asset graphs into memory.\n- Web: Phaser's loader in a preload scene, PixiJS `Assets.loadBundle`, three.js `LoadingManager`; code-split per level.\n- Bevy: `AssetServer::load` returns a handle immediately; gate the state change on the load state (or the repository's loading plugin).\n\n## Validating assets in tests\n\nAn import-settings test fails the build when someone drops in an uncompressed 4K texture:\n\n```csharp\n[Test] public void WorldTextures_AreCompressedAndCapped() {\n    foreach (var guid in AssetDatabase.FindAssets(\"t:Texture2D\", new[] { \"Assets\u002F_Project\u002FArt\u002FWorld\" })) {\n        var path = AssetDatabase.GUIDToAssetPath(guid);\n        var importer = (TextureImporter)AssetImporter.GetAtPath(path);\n        Assert.That(importer.maxTextureSize, Is.LessThanOrEqualTo(2048), path);\n        Assert.That(importer.textureCompression, Is.Not.EqualTo(TextureImporterCompression.Uncompressed), path);\n    }\n}\n```\n\nThe same idea elsewhere: a Godot test reading `.import` files under `res:\u002F\u002Fart\u002Fworld`, a Node script checking `public\u002F` sizes and formats, a data-validation rule in Unreal.\n\n## Common Mistakes\n\n- Moving or renaming assets with `mv` and losing `.meta` GUIDs or Unreal references.\n- Committing Godot's `.godot\u002F` cache or Unreal's `Intermediate\u002F`, `Saved\u002F`, `DerivedDataCache\u002F`, `Binaries\u002F`.\n- Uncompressed or oversized textures; mipmaps on UI sprites.\n- `Resources.Load` \u002F synchronous `load()` during gameplay.\n- Loaded assets never released (Addressables handles, three.js textures) — memory grows every level.\n\n## Red Flags\n\n- A new binary file in the diff that is not covered by `.gitattributes` LFS patterns the repo uses.\n- An asset in the diff without its `.meta` \u002F `.import`, or a `.meta` with a changed GUID.\n- A hitch report and a synchronous load in the same code path.\n",{"name":5,"source":24,"category":25,"tech_stack":26,"description":7},"informed by the Unity, Godot, Unreal, three.js, Babylon.js and Khronos KTX\u002FglTF docs; own wording","assets","Game core","main","910394a0b6db9fc8c9a8f36328ec421d3ebd8b38","catalog\u002Fagents\u002Fgame-developer\u002Fskills\u002Fgame-asset-pipeline",18,"https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper","https:\u002F\u002Ftasktrooper.ai","https:\u002F\u002Fgithub.com\u002Fmakifbaysal","Senior Software Developer","2026-11-15 04:50:29",{"source":8,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add makifbaysal\u002Ftasktrooper --skill game-asset-pipeline",{"tool":42,"command":43},"bunx","bunx skills add makifbaysal\u002Ftasktrooper --skill game-asset-pipeline",{"tool":45,"command":46},"pnpm","pnpm dlx skills add makifbaysal\u002Ftasktrooper --skill game-asset-pipeline","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fgame-developer\u002Fskills\u002Fgame-asset-pipeline\u002FSKILL.md",true,[],[51,57,64,71,78,85],{"skillNo":52,"name":53,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":56,"publishedAt":19},"01M7CSVEPQW6J6TD6CS2T5FPNZ","visual-craft","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fui-designer\u002Fskills\u002Fvisual-craft\u002FSKILL.md",[],[],{"skillNo":58,"name":59,"nameZh":6,"description":60,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":19},"01M7CSVAQG91ETHQ0HBNZDG5FR","ux-copy","Use when you write any words a user reads in a mockup or a hand-off - content language and voice, buttons, labels, errors, empty states, confirmations, numbers and dates, and the longest-string check","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fui-designer\u002Fskills\u002Fux-copy\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M7CSV6H0J38659NDXHJQ8396","screen-mockup-html","Use when you draw screens as the design task's HTML mockup - ONE canvas document holding every screen and every variant side by side, the sanitizer-safe recipe, phone and wide frames, the states grid, static control states, and the loopback self-check with screenshots at 375, 768 and 1440 attached to the task","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fui-designer\u002Fskills\u002Fscreen-mockup-html\u002FSKILL.md",[],[],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M7CSV3JFRF3BM3XK52M7YEYR","performance-awareness","How the performance score moves for your role. Use when the score context shows a declining trend, or before handing off work you have not self-checked against every criterion.","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fui-designer\u002Fskills\u002Fperformance-awareness\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M7CSTZDH00YRF5SCT7BRT9QD","design-variants","Use when a screen design needs variants - how many, variants as side-by-side rows on the one canvas, what makes two variants genuinely different, recommending one, how the human's choice is read, and narrowing to the chosen one in revision","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fui-designer\u002Fskills\u002Fdesign-variants\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M7CSTV6P3SM3PAE28DB0RF77","design-system-authoring","Use when you derive, change or extend a design system - where tokens live per stack, the DTCG token tree, role-based names for both themes, base vs layer vs drift, the DESIGN.md section order, the inventory format, the contrast check and the lint every proposal returns","https:\u002F\u002Fgithub.com\u002Fmakifbaysal\u002Ftasktrooper\u002Fblob\u002Fmain\u002Fcatalog\u002Fagents\u002Fui-designer\u002Fskills\u002Fdesign-system-authoring\u002FSKILL.md",[],[]]