[{"data":1,"prerenderedAt":845},["ShallowReactive",2],{"docs-doc-en-ccm-package":3,"docs-list-en":747},{"doc":4,"locale":744,"available":745},{"id":5,"title":6,"body":7,"description":733,"extension":734,"group":735,"meta":736,"navigation":737,"order":738,"path":739,"section":735,"seo":740,"stem":741,"updated":742,"__hash__":743},"docs_en\u002Fdocs\u002Fccm-package.md","CCM package standard",{"type":8,"value":9,"toc":721},"minimark",[10,34,51,54,59,66,76,173,176,228,232,238,259,263,277,379,399,403,410,448,452,458,548,554,558,561,592,596,681,684,688],[11,12,15],"callout",{"color":13,"icon":14},"success","i-lucide-lightbulb",[16,17,18,22,23,27,28,33],"p",{},[19,20,21],"strong",{},"New works should be packaged to the SCNexus standard."," CCM is documented here for compatibility with older works: SCNexus can recognise and install them, but the format cannot express a type, launcher map, cover or documents, and the install location can only be inferred from ",[24,25,26],"code",{},"title",". Packaging to the ",[29,30,32],"a",{"href":31},"\u002Fdocs\u002Fscnexus-package","SCNexus package standard"," instead gives you an explicit JSON manifest with fields that map one-to-one onto install targets. Works already published in CCM do not need to be redone.",[16,35,36,42,43,46,47,50],{},[29,37,41],{"href":38,"rel":39},"https:\u002F\u002Fgithub.com\u002F7thAce\u002FSC2CCM",[40],"nofollow","CCM"," (SC2 Campaign Manager) is another tool for managing StarCraft II campaign packages. It describes a work in a ",[24,44,45],{},"metadata.txt"," file and puts campaigns under the game's ",[24,48,49],{},"Maps\u002FCustomCampaigns"," directory. Both importing and scanning in SCNexus can read these packages and install them following CCM's conventions, so the same work can serve both tools.",[16,52,53],{},"This page covers the CCM side of the agreement and the decisions SCNexus adds when reading it.",[55,56,58],"h2",{"id":57},"the-metadatatxt-format","The metadata.txt format",[16,60,61,62,65],{},"The file is one ",[24,63,64],{},"key=value"," pair per line, with the key always in lower case:",[67,68,74],"pre",{"className":69,"code":71,"language":72,"meta":73},[70],"language-text","title=Retribution\ndesc=A three-chapter single-player campaign with a custom mod\nauthor=Example Author\nversion=1.2.0\ncampaign=WOL\n","text","",[24,75,71],{"__ignoreMap":73},[77,78,79,95],"table",{},[80,81,82],"thead",{},[83,84,85,89,92],"tr",{},[86,87,88],"th",{},"Key",[86,90,91],{},"Required",[86,93,94],{},"Description",[96,97,98,111,124,136,148],"tbody",{},[83,99,100,105,108],{},[101,102,103],"td",{},[24,104,26],{},[101,106,107],{},"yes",[101,109,110],{},"Work name; also decides the installation directory name",[83,112,113,118,121],{},[101,114,115],{},[24,116,117],{},"desc",[101,119,120],{},"no",[101,122,123],{},"Short description, empty by default",[83,125,126,131,133],{},[101,127,128],{},[24,129,130],{},"author",[101,132,120],{},[101,134,135],{},"Author, empty by default",[83,137,138,143,145],{},[101,139,140],{},[24,141,142],{},"version",[101,144,120],{},[101,146,147],{},"Version, empty by default",[83,149,150,155,157],{},[101,151,152],{},[24,153,154],{},"campaign",[101,156,107],{},[101,158,159,160,163,164,163,167,163,170],{},"One of ",[24,161,162],{},"WOL",", ",[24,165,166],{},"HOTS",[24,168,169],{},"LOTV",[24,171,172],{},"NCO",[16,174,175],{},"Parsing rules:",[177,178,179,202,205,208,222],"ul",{},[180,181,182,183,186,187,190,191,193,194,197,198,201],"li",{},"Lines are read one at a time and split at the ",[19,184,185],{},"first"," ",[24,188,189],{},"=",", with whitespace on both sides trimmed, so a value may contain ",[24,192,189],{}," (",[24,195,196],{},"desc=x=y"," reads as the description ",[24,199,200],{},"x=y",").",[180,203,204],{},"Keys are case-sensitive and must be lower case; unknown keys are ignored without an error.",[180,206,207],{},"The file is decoded as UTF-8 and may carry a BOM; when it is not valid UTF-8 it is decoded again as GB18030, so packages saved with GBK in the early days still read. If neither decoding works the manifest is treated as corrupt.",[180,209,210,211,213,214,217,218,221],{},"The filename is ",[24,212,45],{}," (case-insensitive), a single file may not exceed 1 MiB, and it may not sit inside a ",[24,215,216],{},".SC2Map"," \u002F ",[24,219,220],{},".SC2Mod"," component directory.",[180,223,224,225,227],{},"A missing ",[24,226,154],{},", or one outside the four values, makes the whole package invalid: the CCM format describes campaigns and nothing else.",[55,229,231],{"id":230},"directory-layout","Directory layout",[67,233,236],{"className":234,"code":235,"language":72,"meta":73},[70],"Retribution.zip\n├─ metadata.txt\n├─ Campaign.SC2Map            # entry map\n├─ Mission01.SC2Map\n├─ Mission02.SC2Map\n├─ evolution\u002F                 # Heart of the Swarm only\n│  └─ Evolution01.SC2Map\n└─ Mods\u002F\n   └─ Retribution.SC2Mod\n",[24,237,235],{"__ignoreMap":73},[177,239,240,245,256],{},[180,241,242,244],{},[24,243,45],{}," sits next to the map files, in the archive root.",[180,246,247,248,251,252,255],{},"Maps sit directly in the root — no extra ",[24,249,250],{},"Maps\u002F"," level — and mods go in ",[24,253,254],{},"Mods\u002F",".",[180,257,258],{},"As with the SCNexus standard, an extra wrapper folder around the archive is fine: the app looks down and finds the single set of files. Two parallel sets cannot be told apart and are reported as unsupported.",[55,260,262],{"id":261},"how-install-targets-are-derived","How install targets are derived",[16,264,265,266,269,270,273,274,276],{},"When packaging you write no ",[24,267,268],{},"maps"," or ",[24,271,272],{},"mods"," manifest; targets come from the filenames and from ",[24,275,154],{},":",[77,278,279,289],{},[80,280,281],{},[83,282,283,286],{},[86,284,285],{},"Location in the package",[86,287,288],{},"Target",[96,290,291,323,339,353,365],{},[83,292,293,299],{},[101,294,295,298],{},[24,296,297],{},"X.SC2Map"," in the root",[101,300,301,302,304,305,163,308,304,310,163,313,304,315,163,318,304,320],{},"The map region of that campaign: ",[24,303,162],{}," → ",[24,306,307],{},"Maps\u002FCampaign\u002F",[24,309,166],{},[24,311,312],{},"Maps\u002FCampaign\u002Fswarm\u002F",[24,314,169],{},[24,316,317],{},"Maps\u002FCampaign\u002Fvoid\u002F",[24,319,172],{},[24,321,322],{},"Maps\u002FCampaign\u002Fnova\u002F",[83,324,325,334],{},[101,326,327,330,331,333],{},[24,328,329],{},"evolution\u002FX.SC2Map"," in a ",[24,332,166],{}," package",[101,335,336],{},[24,337,338],{},"Maps\u002FCampaign\u002Fswarm\u002Fevolution\u002F",[83,340,341,348],{},[101,342,343,330,346,333],{},[24,344,345],{},"voidprologue\u002FX.SC2Map",[24,347,169],{},[101,349,350],{},[24,351,352],{},"Maps\u002FCampaign\u002Fvoidprologue\u002F",[83,354,355,360],{},[101,356,357,298],{},[24,358,359],{},"X.SC2Mod",[101,361,362,364],{},[24,363,254],{},", keeping the in-package path",[83,366,367,374],{},[101,368,369,371,372],{},[24,370,220],{}," under ",[24,373,254],{},[101,375,376,377],{},"The matching location under ",[24,378,254],{},[177,380,381,389,396],{},[180,382,383,384,269,386,388],{},"A component-form map or mod (a directory ending in ",[24,385,216],{},[24,387,220],{},") is handled as a whole directory; its contents are not examined one by one.",[180,390,391,392,395],{},"Maps in other subdirectories are never planned anywhere, ",[24,393,394],{},"Campaign\u002FLevel1.SC2Map"," for instance; for a map to take effect, put it in the root or in one of the campaign subdirectories above.",[180,397,398],{},"Targets are recognised by extension and filename, so renaming a file moves its target — check the references inside the campaign before renaming a map.",[55,400,402],{"id":401},"where-it-ends-up-after-installation","Where it ends up after installation",[16,404,405,406,409],{},"SCNexus does not write these maps into ",[24,407,408],{},"Maps\u002FCampaign"," as the previous section describes; it installs them by CCM's own conventions:",[177,411,412,426,436,442],{},[180,413,414,415,418,419,421,422,425],{},"The whole package is extracted into a subdirectory under the ",[19,416,417],{},"CCM management directory"," named after ",[24,420,26],{},", keeping the relative paths inside the package. The default location is ",[24,423,424],{},"\u003Cgame directory>\u002FMaps\u002FCustomCampaigns",", which can be changed in Settings.",[180,427,428,429,432,433,435],{},"Mods inside it are ",[19,430,431],{},"additionally copied"," into the game's ",[24,434,254],{},", because the game loads mods by path and leaving them in the management directory does nothing.",[180,437,438,439,441],{},"A CCM package therefore never overwrites the maps of the official campaigns; uninstalling or deactivating only cleans the management directory, and mods already copied into ",[24,440,254],{}," are neither deleted nor restored if they replaced a mod of the same name. The import dialog says so explicitly: CCM installs mods during import, and deactivating or uninstalling later neither deletes nor restores them.",[180,443,444,445,447],{},"Works already sitting in the CCM management directory are recognised again when scanning and show up in campaign management; a single ",[24,446,45],{}," in the directory is enough.",[55,449,451],{"id":450},"the-directory-name-comes-from-title","The directory name comes from title",[16,453,454,455,457],{},"The subdirectory under the management directory is not a verbatim copy of ",[24,456,26],{},": it is cleaned up first so it works across platforms:",[77,459,460,469],{},[80,461,462],{},[83,463,464,467],{},[86,465,466],{},"Step",[86,468,94],{},[96,470,471,483,499,507,540],{},[83,472,473,480],{},[101,474,475,476,479],{},"Strip ",[24,477,478],{},"\u003C>:\"\u002F|?*"," and control characters",[101,481,482],{},"These are unsafe in filenames",[83,484,485,491],{},[101,486,487,488],{},"Trim whitespace and replace inner whitespace with ",[24,489,490],{},"_",[101,492,493,304,496],{},[24,494,495],{},"Retribution 2",[24,497,498],{},"Retribution_2",[83,500,501,504],{},[101,502,503],{},"Strip trailing dots",[101,505,506],{},"Windows does not allow a directory name ending in a dot",[83,508,509,512],{},[101,510,511],{},"Reject reserved names",[101,513,514,163,517,163,520,163,523,163,526,529,530,163,533,529,536,539],{},[24,515,516],{},"con",[24,518,519],{},"prn",[24,521,522],{},"aux",[24,524,525],{},"nul",[24,527,528],{},"com1","–",[24,531,532],{},"com9",[24,534,535],{},"lpt1",[24,537,538],{},"lpt9"," cannot be directory names",[83,541,542,545],{},[101,543,544],{},"Length limit",[101,546,547],{},"At most 255 bytes (UTF-8)",[16,549,550,551,553],{},"When the cleaned name is empty, hits a reserved name or exceeds the length limit, the import fails and says the title cannot form a usable directory name — try another ",[24,552,26],{},". If a subdirectory of that name already exists, it is treated as already installed; uninstall or rename it first.",[55,555,557],{"id":556},"how-scnexus-recognises-these-packages","How SCNexus recognises these packages",[16,559,560],{},"When importing or scanning, the client looks for descriptor files in this order:",[562,563,564,574,580,586],"ol",{},[180,565,566,567,570,571,573],{},"Find the outermost ",[24,568,569],{},"package.json"," and ",[24,572,45],{},". Several descriptors at the same level cannot be told apart and are reported as unsupported.",[180,575,576,577,579],{},"When both exist and declare different work types, you are asked which one to install by; when the types match, ",[24,578,569],{}," wins.",[180,581,582,583,585],{},"With only ",[24,584,45],{},", the package is treated as a CCM package, always as a campaign.",[180,587,588,589,591],{},"With neither, the package is a campaign if it contains a ",[24,590,408],{}," directory and custom content otherwise.",[55,593,595],{"id":594},"how-it-differs-from-the-scnexus-standard","How it differs from the SCNexus standard",[77,597,598,609],{},[80,599,600],{},[83,601,602,605,607],{},[86,603,604],{},"Item",[86,606,32],{},[86,608,6],{},[96,610,611,626,637,648,659,670],{},[83,612,613,616,621],{},[101,614,615],{},"Manifest",[101,617,618,620],{},[24,619,569],{}," (JSON)",[101,622,623,625],{},[24,624,45],{}," (key-value pairs)",[83,627,628,631,634],{},[101,629,630],{},"Work types it can describe",[101,632,633],{},"Campaigns, custom content, shared mod packages",[101,635,636],{},"Campaigns only",[83,638,639,642,645],{},[101,640,641],{},"Install location",[101,643,644],{},"Declared item by item in the manifest",[101,646,647],{},"Derived by convention, under the CCM management directory",[83,649,650,653,656],{},[101,651,652],{},"Version checking",[101,654,655],{},"Structural validation plus a semantic-version check at publish time",[101,657,658],{},"Treated as text, never compared",[83,660,661,664,667],{},[101,662,663],{},"Languages, images, documents",[101,665,666],{},"Supported",[101,668,669],{},"Not supported",[83,671,672,675,678],{},[101,673,674],{},"Editor hints and schema",[101,676,677],{},"Yes",[101,679,680],{},"No",[16,682,683],{},"Reach for the SCNexus standard when you need localised entries, a cover image, documents or dependency packages; when all you want is to hand an existing CCM work to players, leave it as it is.",[55,685,687],{"id":686},"self-check-list","Self-check list",[562,689,690,698,701,713,718],{},[180,691,692,694,695,697],{},[24,693,45],{}," sits next to the maps, its keys are all lower case, and ",[24,696,154],{}," is one of the four values.",[180,699,700],{},"The file is saved as UTF-8; GBK files from older tools still read, but new works should not depend on that.",[180,702,703,704,163,707,710,711,255],{},"Maps are in the root (or ",[24,705,706],{},"evolution\u002F",[24,708,709],{},"voidprologue\u002F",") and mods are in ",[24,712,254],{},[180,714,715,717],{},[24,716,26],{}," contains no path separators or similar characters and does not hit a reserved name.",[180,719,720],{},"After importing, check the planned target files, then confirm in the game that the chapters load.",{"title":73,"searchDepth":722,"depth":722,"links":723},3,[724,726,727,728,729,730,731,732],{"id":57,"depth":725,"text":58},2,{"id":230,"depth":725,"text":231},{"id":261,"depth":725,"text":262},{"id":401,"depth":725,"text":402},{"id":450,"depth":725,"text":451},{"id":556,"depth":725,"text":557},{"id":594,"depth":725,"text":595},{"id":686,"depth":725,"text":687},"How CCM describes a campaign in metadata.txt, the key-value format, the directory layout and install targets, and how SCNexus reads these packages.","md","reference",{},true,20,"\u002Fdocs\u002Fccm-package",{"title":6,"description":733},"docs\u002Fccm-package","2026-11-01","BNsjL5Cqlb6ddLjHLetZCfb0_eRSdz3tVTL1S1ipMQo","en",[744,746],"zh-CN",[748,755,760,764,770,774,776,777,781,785,790,794,799,804,809,814,819,824,829,834,840],{"path":749,"title":750,"description":751,"order":752,"group":753,"section":754,"contentLocale":746},"\u002Fdocs\u002Feditor","创作流程概览","从在《星际争霸II》编辑器中制作，到打包、分发与更新，说明星际枢纽在创作流程里承担的环节。",1,"start","editor",{"path":756,"title":757,"description":758,"order":752,"group":753,"section":759,"contentLocale":744},"\u002Fdocs\u002Foverview","Getting started","SCNexus is a hub app built for the StarCraft community","app",{"path":761,"title":762,"description":763,"order":752,"group":735,"section":735,"contentLocale":744},"\u002Fdocs\u002Freference","Overview","The packaging and source conventions that importing, installing and distributing content depends on.",{"path":765,"title":766,"description":767,"order":768,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fcampaign","Campaign management","Import your own campaigns into the library, activate them in the game, and restore the official campaigns at any time",10,"usage",{"path":771,"title":772,"description":773,"order":768,"group":769,"section":754,"contentLocale":746},"\u002Fdocs\u002Fpackaging","打包安装包","把编辑器产出的地图、模组与 package.json 组织成一个能被星际枢纽自动识别并安装的压缩包。",{"path":31,"title":32,"description":775,"order":768,"group":735,"section":735,"contentLocale":744},"Directory layout, package.json manifest fields, map and mod resource declarations, and how launchers and bundled documents are written for SCNexus work packages.",{"path":739,"title":6,"description":733,"order":738,"group":735,"section":735,"contentLocale":744},{"path":778,"title":779,"description":780,"order":738,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fcustomize","Custom content","Install maps and mods straight into the game, then pick a launcher map and start in one click",{"path":782,"title":783,"description":784,"order":738,"group":769,"section":754,"contentLocale":746},"\u002Fdocs\u002Ftoolbox","创作工具 · 编码转换","把中文等非 ASCII 文本转成 Galaxy 代码里可用的转义写法，可选直接转码、字符串、文本与触发调试四种输出。",{"path":786,"title":787,"description":788,"order":789,"group":735,"section":735,"contentLocale":744},"\u002Fdocs\u002Fgithub-source","GitHub source standard","The manifest and structural requirements a public GitHub repository has to meet to serve as an install source, and how addresses and branches are written.",30,{"path":791,"title":792,"description":793,"order":789,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fweekly-mutations","Weekly mutations","This week's mutation map, mutators and community rating, plus the full mutator reference",{"path":795,"title":796,"description":797,"order":798,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Freplays","Replays","Index replays by StarCraft profile and replay type, with duplicate detection, bulk export and match data",40,{"path":800,"title":801,"description":802,"order":803,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fworkshop","Workshop","Browse community works, open their details and download reviewed releases",50,{"path":805,"title":806,"description":807,"order":808,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fcreator","Creator center and uploads","Create works, maintain their details, upload new versions and track upload tasks",60,{"path":810,"title":811,"description":812,"order":813,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fdownloads","Downloads","Fetch content from GitHub or the Workshop, then install it once you have checked it",70,{"path":815,"title":816,"description":817,"order":818,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Ftools","Creation tools","Local helpers such as the encoding converter; input is never uploaded or stored",80,{"path":820,"title":821,"description":822,"order":823,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fai-assistant","Smart Assistant","A controlled MCP service connecting local data to AI clients on the same machine",90,{"path":825,"title":826,"description":827,"order":828,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Faccount","Account and personal center","Signing in, your profile and level progression, and setting up and maintaining two-step verification",100,{"path":830,"title":831,"description":832,"order":833,"group":769,"section":759,"contentLocale":744},"\u002Fdocs\u002Fsettings","Settings","Language, game directories, feature switches and logging privacy, tab by tab",110,{"path":835,"title":836,"description":837,"order":838,"group":839,"section":759,"contentLocale":744},"\u002Fdocs\u002Fcontributing","Contributing","How to contribute to SCNexus: where the repositories live, how to set up a development environment, what to run before submitting, the code and documentation conventions, the code of conduct, and how to report security issues.",200,"contribute",{"path":841,"title":842,"description":843,"order":844,"group":839,"section":759,"contentLocale":744},"\u002Fdocs\u002Flocalization","Translating the interface","Where the interface translation files live, how keys are named, how to submit changes, how to verify them locally, and what adding a language touches.",210,1793550744913]