[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBS0C2W2MA6RZF8FEDC26M":3,"skill-same:01M6CBS0C2W2MA6RZF8FEDC26M":54},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":13,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":6,"ownerDescription":28,"updatedAt":29,"install":30,"resources":43},"01M6CBS0C2W2MA6RZF8FEDC26M","21-bundle-build",null,"devwinsoft\u002Fdevian","devwinsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F22570160?v=4","01M6C6RR8W05NH8NPKQNCE3Q72","maoshy","01M6C6RRDJ5TJJCZXRTY801YDH",0,"MIT","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F70-build-operation\u002F21-bundle-build\u002FSKILL.md",[],[18],"21 bundle build","2026-11-10 10:12:30",false,"# 21-bundle-build — Addressable Bundle Build\n\nStatus: ACTIVE\nAppliesTo: v1\nType: Component Specification\n\n## 목적\n\nAddressables 번들을 빌드한다. 특정 group을 제외하는 기능을 포함.\nPipeline 탭의 `Build Addressable Bundles` 체크박스가 활성화되어 있을 때 앱 빌드 전에 실행한다.\n\n## 파일 위치 (SSOT)\n\n- `com.devian.foundation\u002FSamples~\u002FMobilePackage\u002FEditor\u002FBuildAutomation\u002FBundleBuildRunner.cs`\n\n## Public API\n\n```csharp\nnamespace Devian\n{\n    public static class BundleBuildRunner\n    {\n        \u002F\u002F\u002F \u003Csummary>\n        \u002F\u002F\u002F Addressables 번들을 빌드한다.\n        \u002F\u002F\u002F excludedGroupNames에 포함된 group은 빌드에서 제외한다.\n        \u002F\u002F\u002F \u003C\u002Fsummary>\n        \u002F\u002F\u002F \u003Cparam name=\"excludedGroupNames\">제외할 group 이름 목록\u003C\u002Fparam>\n        \u002F\u002F\u002F \u003Creturns>성공 시 빌드 산출물 경로, 실패 시 null\u003C\u002Freturns>\n        public static string Run(List\u003Cstring> excludedGroupNames);\n    }\n}\n```\n\n## 실행 흐름\n\n```\n1. AddressableAssetSettingsDefaultObject.Settings 로드\n2. EnsureActiveProfile — activeProfileId가 유효하지 않으면 첫 번째 프로필로 폴백\n3. CleanNullGroups — null group 참조 정리 (Addressables 내부 NRE 방지)\n4. SyncRemoteLoadPath — remoteCdnUrl 기반으로 Addressables Profile Remote.LoadPath 동기화\n   - 형식: {remoteCdnUrl}\u002Fv[UnityEditor.PlayerSettings.bundleVersion]\u002F[BuildTarget]\n5. excludedGroupNames에 해당하는 group의 BundledAssetGroupSchema.IncludeInBuild = false 설정\n   - 변경 전 원본 값을 Dictionary\u003Cgroup, bool>에 백업\n6. AddressableAssetSettings.BuildPlayerContent() 호출\n7. 백업에서 원본 IncludeInBuild 값 복원 (try-finally)\n8. 빌드 결과 로그 출력\n```\n\n## Group 제외 메커니즘\n\n```csharp\n\u002F\u002F 제외 처리 (빌드 전)\nvar backup = new Dictionary\u003CAddressableAssetGroup, bool>();\nforeach (var group in settings.groups)\n{\n    if (excludedGroupNames.Contains(group.Name))\n    {\n        var schema = group.GetSchema\u003CBundledAssetGroupSchema>();\n        if (schema != null)\n        {\n            backup[group] = schema.IncludeInBuild;\n            schema.IncludeInBuild = false;\n        }\n    }\n}\n\n\u002F\u002F 빌드 실행\nAddressableAssetSettings.BuildPlayerContent();\n\n\u002F\u002F 복원 (빌드 후, 반드시 finally에서 실행)\nforeach (var kv in backup)\n{\n    var schema = kv.Key.GetSchema\u003CBundledAssetGroupSchema>();\n    if (schema != null)\n        schema.IncludeInBuild = kv.Value;\n}\n```\n\n## 제외 group 설정\n\n`BuildAutomationSettings.excludedAddressableGroups`에 group 이름 목록으로 저장한다.\nEditorWindow Settings 탭의 \"Exclude Addressable Groups\" 드롭리스트에서 선택.\n\n## EditorWindow 연동\n\nPipeline 탭에서 `☑ Build Addressable Bundles` 체크박스로 활성화.\n앱 빌드(`RunBuild`) 실행 시 체크되어 있으면 `BundleBuildRunner.Run()` 먼저 호출.\n\n## Hard Rules\n\n- 제외 처리는 `IncludeInBuild` 플래그만 사용한다. group 삭제\u002F이동하지 않는다.\n- 빌드 후 반드시 원본 값을 복원한다 (try-finally).\n- `AddressableAssetSettingsDefaultObject.Settings`가 null이면 에러 로그 후 중단.\n- 로그는 `BuildAutomationLogger` 경유.\n\n## Implementation Location (3-path mirror)\n\n| 경로 | 역할 |\n|------|------|\n| `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FEditor\u002FBuildAutomation\u002FBundleBuildRunner.cs` | UPM (정본) |\n| `framework-cs\u002Fapps\u002FUnityExample\u002FPackages\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FEditor\u002FBuildAutomation\u002FBundleBuildRunner.cs` | Packages (sync) |\n| `Assets\u002FSamples\u002FDevian Foundation\u002F{version}\u002FMobilePackage\u002FEditor\u002FBuildAutomation\u002FBundleBuildRunner.cs` | Assets\u002FSamples (import) |\n\n## Reference\n\n- Parent: `skills\u002Fdevian-unity\u002F50-mobile-package\u002F70-build-operation\u002F00-overview\u002FSKILL.md`\n- Settings: `skills\u002Fdevian-unity\u002F50-mobile-package\u002F70-build-operation\u002F10-settings\u002FSKILL.md`\n- EditorWindow: `skills\u002Fdevian-unity\u002F50-mobile-package\u002F70-build-operation\u002F50-editor-window\u002FSKILL.md`\n",{},"main","8cb5bd877a3a7004867d2f55697cb9e4ff2f1734","skills\u002Fdevian-unity\u002F50-mobile-package\u002F70-build-operation\u002F21-bundle-build","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft","Kim Hyong Joon","2026-04-12 18:44:10",{"source":7,"skillName":5,"commands":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add devwinsoft\u002Fdevian --skill 21-bundle-build",{"tool":36,"command":37},"bunx","bunx skills add devwinsoft\u002Fdevian --skill 21-bundle-build",{"tool":39,"command":40},"pnpm","pnpm dlx skills add devwinsoft\u002Fdevian --skill 21-bundle-build","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F70-build-operation\u002F21-bundle-build\u002FSKILL.md",true,[44,50],{"path":45,"resourceType":46,"resourceTypeDesc":47,"sizeBytes":48,"sourceHtmlUrl":49},"SOURCE.md","REFERENCE","参考文档",180,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdefi\u002Fcomposai-able\u002FSOURCE.md",{"path":51,"resourceType":46,"resourceTypeDesc":47,"sizeBytes":52,"sourceHtmlUrl":53},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdefi\u002Fcomposai-able\u002FTRUST.auto.yaml",[55,61,69,77,86,93],{"skillNo":56,"name":57,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":19},"01M6CBX3K2JJV38ANHVGCAT8A0","devian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002FSKILL.md",[],[57],{"skillNo":62,"name":63,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":66,"publishedAt":19},"01M6CBX210BFMM8AMN770J9WY8","90-project-archive","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F90-project-archive\u002FSKILL.md",[],[67,68],"archive","90 project archive",{"skillNo":70,"name":71,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":19},"01M6CBWZSGRR9R3YJZB3177667","30-env-management","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F30-env-management\u002FSKILL.md",[],[75,76],"management","30 env management",{"skillNo":78,"name":79,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":19},"01M6CBWYD3TGWBQV7V35551THF","19-page-push-send","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F19-page-push-send\u002FSKILL.md",[],[83,84,85],"push","page","19 page push send",{"skillNo":87,"name":88,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M6CBWWRQ05A7604GHJKTPJTF","18-page-savedata","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F18-page-savedata\u002FSKILL.md",[],[84,92],"18 page savedata",{"skillNo":94,"name":95,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":19},"01M6CBWVH4S2VF1V7B2GBTESCT","17-page-deobfuscate","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F17-page-deobfuscate\u002FSKILL.md",[],[84,99],"17 page deobfuscate"]