[{"data":1,"prerenderedAt":530},["ShallowReactive",2],{"docs-navigation:en":3,"content-page:docs:eInawAdvbfotzWx0yhwqGc75ogndCE1Gzp-6hUqcibY":195,"content-page-surround:docs:eInawAdvbfotzWx0yhwqGc75ogndCE1Gzp-6hUqcibY":525},[4,54,74],{"title":5,"page":6,"canonicalKey":7,"locale":8,"id":9,"draft":6,"icon":10,"sidebar":11,"children":12},"Guides",false,"1","en","content:en:1.docs:1.guides:.navigation.yml","lucide:route","section",[13,19,26,33,40,47],{"title":14,"id":15,"canonicalKey":16,"locale":8,"draft":6,"icon":17,"path":18},"Install Guild Wars on Mac","content:en:1.docs:1.guides:1.install.md","1\u002F1","lucide:download","\u002Fdocs\u002Fguides\u002Finstall",{"title":20,"id":21,"canonicalKey":22,"locale":8,"draft":6,"navigation":23,"icon":24,"path":25},"Accounts & mobile linking","content:en:1.docs:1.guides:2.accounts.md","1\u002F2",{"title":20},"lucide:key-round","\u002Fdocs\u002Fguides\u002Faccounts",{"title":27,"id":28,"canonicalKey":29,"locale":8,"draft":6,"navigation":30,"icon":31,"path":32},"Play on Mac: options","content:en:1.docs:1.guides:3.play-guild-wars-on-mac.md","1\u002F3",{"title":27},"lucide:scale","\u002Fdocs\u002Fguides\u002Fplay-guild-wars-on-mac",{"title":34,"id":35,"canonicalKey":36,"locale":8,"draft":6,"navigation":37,"icon":38,"path":39},"Performance","content:en:1.docs:1.guides:4.performance.md","1\u002F4",{"title":34},"lucide:gauge","\u002Fdocs\u002Fguides\u002Fperformance",{"title":41,"id":42,"canonicalKey":43,"locale":8,"draft":6,"navigation":44,"icon":45,"path":46},"Templates","content:en:1.docs:1.guides:5.templates.md","1\u002F5",{"title":41},"lucide:bookmark","\u002Fdocs\u002Fguides\u002Ftemplates",{"title":48,"id":49,"canonicalKey":50,"locale":8,"draft":6,"navigation":51,"icon":52,"path":53},"Troubleshooting","content:en:1.docs:1.guides:6.troubleshooting.md","1\u002F6",{"title":48},"lucide:wrench","\u002Fdocs\u002Fguides\u002Ftroubleshooting",{"title":55,"page":6,"canonicalKey":56,"locale":8,"id":57,"draft":6,"icon":58,"sidebar":59,"children":60},"Project","2","content:en:1.docs:2.project:.navigation.yml","lucide:shield-check","group",[61,67],{"title":62,"id":63,"canonicalKey":64,"locale":8,"draft":6,"navigation":65,"icon":58,"path":66},"Safety & account risk","content:en:1.docs:2.project:1.safety.md","2\u002F1",{"title":62},"\u002Fdocs\u002Fproject\u002Fsafety",{"title":68,"id":69,"canonicalKey":70,"locale":8,"draft":6,"navigation":71,"icon":72,"path":73},"About & credits","content:en:1.docs:2.project:2.about.md","2\u002F2",{"title":68},"lucide:users","\u002Fdocs\u002Fproject\u002Fabout",{"title":75,"page":6,"canonicalKey":76,"locale":8,"id":77,"draft":6,"icon":78,"sidebar":11,"children":79},"For ArenaNet","3","content:en:1.docs:3.upstream:.navigation.yml","lucide:send",[80,87,94,120,146,158,177],{"title":81,"id":82,"canonicalKey":83,"locale":8,"draft":6,"navigation":84,"icon":85,"path":86},"Introduction","content:en:1.docs:3.upstream:1.introduction.md","3\u002F1",{"title":81},"lucide:book-open-check","\u002Fdocs\u002Fupstream\u002Fintroduction",{"title":88,"id":89,"canonicalKey":90,"locale":8,"draft":6,"navigation":91,"icon":92,"path":93},"Request summary","content:en:1.docs:3.upstream:2.request-summary.md","3\u002F2",{"title":88},"lucide:list-checks","\u002Fdocs\u002Fupstream\u002Frequest-summary",{"title":95,"page":6,"canonicalKey":96,"locale":8,"id":97,"draft":6,"icon":98,"sidebar":59,"children":99},"File system","3\u002F3","content:en:1.docs:3.upstream:3.filesystem:.navigation.yml","lucide:folder-x",[100,106,113],{"title":101,"id":102,"canonicalKey":103,"locale":8,"draft":6,"navigation":104,"icon":98,"path":105},"File routines (UR-01…04)","content:en:1.docs:3.upstream:3.filesystem:1.unimplemented-routines.md","3\u002F3\u002F1",{"title":101},"\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Funimplemented-routines",{"title":107,"id":108,"canonicalKey":109,"locale":8,"draft":6,"navigation":110,"icon":111,"path":112},"RemoveExtension (UR-05)","content:en:1.docs:3.upstream:3.filesystem:2.path-remove-extension.md","3\u002F3\u002F2",{"title":107},"lucide:scissors","\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Fpath-remove-extension",{"title":114,"id":115,"canonicalKey":116,"locale":8,"draft":6,"navigation":117,"icon":118,"path":119},"File::Open mode (UR-06)","content:en:1.docs:3.upstream:3.filesystem:3.file-open-mode.md","3\u002F3\u002F3",{"title":114},"lucide:file-plus-2","\u002Fdocs\u002Fupstream\u002Ffilesystem\u002Ffile-open-mode",{"title":121,"page":6,"canonicalKey":122,"locale":8,"id":123,"draft":6,"icon":124,"sidebar":59,"children":125},"Input","3\u002F4","content:en:1.docs:3.upstream:4.input:.navigation.yml","lucide:mouse-pointer-click",[126,132,139],{"title":127,"id":128,"canonicalKey":129,"locale":8,"draft":6,"navigation":130,"icon":124,"path":131},"Double-click (UR-07)","content:en:1.docs:3.upstream:4.input:1.double-click-flag.md","3\u002F4\u002F1",{"title":127},"\u002Fdocs\u002Fupstream\u002Finput\u002Fdouble-click-flag",{"title":133,"id":134,"canonicalKey":135,"locale":8,"draft":6,"navigation":136,"icon":137,"path":138},"Key labels (UR-08)","content:en:1.docs:3.upstream:4.input:2.key-labels.md","3\u002F4\u002F2",{"title":133},"lucide:keyboard","\u002Fdocs\u002Fupstream\u002Finput\u002Fkey-labels",{"title":140,"id":141,"canonicalKey":142,"locale":8,"draft":6,"navigation":143,"icon":144,"path":145},"Cursor re-test (UR-09)","content:en:1.docs:3.upstream:4.input:3.cursor-re-evaluation.md","3\u002F4\u002F3",{"title":140},"lucide:pointer","\u002Fdocs\u002Fupstream\u002Finput\u002Fcursor-re-evaluation",{"title":147,"page":6,"canonicalKey":148,"locale":8,"id":149,"draft":6,"icon":150,"sidebar":59,"children":151},"Runtime","3\u002F5","content:en:1.docs:3.upstream:5.runtime:.navigation.yml","lucide:cpu",[152],{"title":153,"id":154,"canonicalKey":155,"locale":8,"draft":6,"navigation":156,"icon":150,"path":157},"Heap maximum (UR-10)","content:en:1.docs:3.upstream:5.runtime:1.heap-maximum.md","3\u002F5\u002F1",{"title":153},"\u002Fdocs\u002Fupstream\u002Fruntime\u002Fheap-maximum",{"title":159,"page":6,"canonicalKey":160,"locale":8,"id":161,"draft":6,"icon":162,"sidebar":59,"children":163},"Interface proposals","3\u002F6","content:en:1.docs:3.upstream:6.proposals:.navigation.yml","lucide:plug",[164,171],{"title":165,"id":166,"canonicalKey":167,"locale":8,"draft":6,"navigation":168,"icon":169,"path":170},"Build identity (UR-11)","content:en:1.docs:3.upstream:6.proposals:1.build-identification.md","3\u002F6\u002F1",{"title":165},"lucide:fingerprint","\u002Fdocs\u002Fupstream\u002Fproposals\u002Fbuild-identification",{"title":172,"id":173,"canonicalKey":174,"locale":8,"draft":6,"navigation":175,"icon":162,"path":176},"Host interface (UR-12)","content:en:1.docs:3.upstream:6.proposals:2.platform-host-interface.md","3\u002F6\u002F2",{"title":172},"\u002Fdocs\u002Fupstream\u002Fproposals\u002Fplatform-host-interface",{"title":178,"page":6,"canonicalKey":179,"locale":8,"id":180,"draft":6,"icon":181,"sidebar":59,"children":182},"Reference","3\u002F7","content:en:1.docs:3.upstream:7.reference:.navigation.yml","lucide:microscope",[183,189],{"title":184,"id":185,"canonicalKey":186,"locale":8,"draft":6,"navigation":187,"icon":52,"path":188},"Our workarounds","content:en:1.docs:3.upstream:7.reference:1.our-workarounds.md","3\u002F7\u002F1",{"title":184},"\u002Fdocs\u002Fupstream\u002Freference\u002Four-workarounds",{"title":190,"id":191,"canonicalKey":192,"locale":8,"draft":6,"navigation":193,"icon":181,"path":194},"Verification method","content:en:1.docs:3.upstream:7.reference:2.verification-method.md","3\u002F7\u002F2",{"title":190},"\u002Fdocs\u002Fupstream\u002Freference\u002Fverification-method",{"title":196,"ref":197,"description":198,"icon":169,"updated":199,"navigation":200,"body":201,"type":510,"id":166,"canonicalKey":167,"draft":6,"partial":6,"locale":8,"collection":511,"navigationFile":6,"file":512,"route":518,"resolution":522},"UR-11: publish build identity and a symbol map","docs\u002Fupstream\u002Fproposals\u002Fbuild-identification","Keep the build_id section and the assert strings, and publish the function name map that the build already produces. No runtime change, and it saves hours per client update.","2026-08-04",{"title":165},{"type":202,"children":203,"toc":492},"root",[204,212,223,230,235,240,247,253,307,313,318,323,329,334,421,426,432,437,443,448,454,486],{"type":205,"tag":206,"props":207,"children":208},"element","p",{},[209],{"type":210,"value":211},"text","This request doesn't correct a defect. It asks ArenaNet to keep three things\nthe build already produces, and to publish one of them. Two of the three items\nare \"change nothing\"; the third is publishing an artifact that already exists.",{"type":205,"tag":206,"props":213,"children":214},{},[215,221],{"type":205,"tag":216,"props":217,"children":218},"strong",{},[219],{"type":210,"value":220},"Fix:",{"type":210,"value":222}," low effort, no blast radius at runtime — the published module doesn't\nchange, only the set of published files grows.",{"type":205,"tag":224,"props":225,"children":227},"h2",{"id":226},"the-problem-this-solves",[228],{"type":210,"value":229},"The problem this solves",{"type":205,"tag":206,"props":231,"children":232},{},[233],{"type":210,"value":234},"The published module is stripped: about 17,600 functions, no names, each one\nidentified only by its index. Every recompile moves those indices — add one\nfunction and every index after it changes. Static data addresses move too, and\nnot by one common offset; we measured this on build 38797, and the addresses\nshare no single delta.",{"type":205,"tag":206,"props":236,"children":237},{},[238],{"type":210,"value":239},"Any host that needs to locate something inside the client repeats that work\nafter every update. For us it's the single largest cost of the project.",{"type":205,"tag":241,"props":242,"children":244},"info",{"title":243},"Why we can't solve this alone",[245],{"type":210,"value":246},"We can find code by shape — a function by its exact body bytes and caller set,\nwith proof that the surrounding code didn't change. That survives updates. A\nplain number has no shape: nothing in the module says \"this global is the\ncontext root\", so every memory address has to be measured by hand, on each\nbuild.",{"type":205,"tag":224,"props":248,"children":250},{"id":249},"what-we-ask-for",[251],{"type":210,"value":252},"What we ask for",{"type":205,"tag":254,"props":255,"children":257},"steps",{"mode":256},"numbered",[258,265,270,276,289,295],{"type":205,"tag":259,"props":260,"children":262},"h3",{"id":261},"what-we-ask-for-keep-the-build_id-custom-section",[263],{"type":210,"value":264},"Keep the build_id custom section",{"type":205,"tag":206,"props":266,"children":267},{},[268],{"type":210,"value":269},"The module carries a custom section with a build identifier. We use it to gate\nevery build-specific decision, and we refuse to run any transform on an\nunknown build.",{"type":205,"tag":259,"props":271,"children":273},{"id":272},"what-we-ask-for-keep-the-assert-strings-and-the-source-paths",[274],{"type":210,"value":275},"Keep the assert strings and the source paths",{"type":205,"tag":206,"props":277,"children":278},{},[279,281,287],{"type":210,"value":280},"The data section holds assert messages and original source paths, for example\n",{"type":205,"tag":282,"props":283,"children":284},"code",{},[285],{"type":210,"value":286},"p:\\code\\gw\\ui\\game\\party\\ptsearch.cpp",{"type":210,"value":288},". They come from the source, not the\ncompiler, so they survive recompiles that move every index. They're the most\nstable anchors in the binary — the Windows tool community has leaned on them\nfor twenty years.",{"type":205,"tag":259,"props":290,"children":292},{"id":291},"what-we-ask-for-publish-the-function-name-map",[293],{"type":210,"value":294},"Publish the function name map",{"type":205,"tag":206,"props":296,"children":297},{},[298,300,305],{"type":210,"value":299},"The build already produces a name map: the module references\n",{"type":205,"tag":282,"props":301,"children":302},{},[303],{"type":210,"value":304},"external_debug_info",{"type":210,"value":306},", and an earlier build shipped with names. Publishing\nthat map as a separate file per build solves the problem outright.",{"type":205,"tag":224,"props":308,"children":310},{"id":309},"the-name-map-in-detail",[311],{"type":210,"value":312},"The name map, in detail",{"type":205,"tag":206,"props":314,"children":315},{},[316],{"type":210,"value":317},"A name map turns our hardest problem into a table lookup.",{"type":205,"tag":206,"props":319,"children":320},{},[321],{"type":210,"value":322},"We already carry names forward between builds with a correlator that compares\nan older named build against the new stripped one, using nine heuristics. On\none build pair it mapped 17,302 of 17,739 functions automatically, left 433\nuncertain, and 4 unmapped. That's a good result — and still a guess. A\npublished map makes it exact.",{"type":205,"tag":259,"props":324,"children":326},{"id":325},"the-name-map-in-detail-acceptable-forms",[327],{"type":210,"value":328},"Acceptable forms",{"type":205,"tag":206,"props":330,"children":331},{},[332],{"type":210,"value":333},"We don't need full debug information. Any of these works:",{"type":205,"tag":335,"props":336,"children":337},"table",{},[338,362],{"type":205,"tag":339,"props":340,"children":341},"thead",{},[342],{"type":205,"tag":343,"props":344,"children":345},"tr",{},[346,352,357],{"type":205,"tag":347,"props":348,"children":349},"th",{},[350],{"type":210,"value":351},"Form",{"type":205,"tag":347,"props":353,"children":354},{},[355],{"type":210,"value":356},"Content",{"type":205,"tag":347,"props":358,"children":359},{},[360],{"type":210,"value":361},"Our result",{"type":205,"tag":363,"props":364,"children":365},"tbody",{},[366,385,403],{"type":205,"tag":343,"props":367,"children":368},{},[369,375,380],{"type":205,"tag":370,"props":371,"children":372},"td",{},[373],{"type":210,"value":374},"A full name section",{"type":205,"tag":370,"props":376,"children":377},{},[378],{"type":210,"value":379},"Index to name for every function",{"type":205,"tag":370,"props":381,"children":382},{},[383],{"type":210,"value":384},"Exact",{"type":205,"tag":343,"props":386,"children":387},{},[388,393,398],{"type":205,"tag":370,"props":389,"children":390},{},[391],{"type":210,"value":392},"A partial map",{"type":205,"tag":370,"props":394,"children":395},{},[396],{"type":210,"value":397},"Index to name for exported and asserted functions only",{"type":205,"tag":370,"props":399,"children":400},{},[401],{"type":210,"value":402},"Almost exact",{"type":205,"tag":343,"props":404,"children":405},{},[406,411,416],{"type":205,"tag":370,"props":407,"children":408},{},[409],{"type":210,"value":410},"A hash map",{"type":205,"tag":370,"props":412,"children":413},{},[414],{"type":210,"value":415},"Index to a stable hash of the mangled name",{"type":205,"tag":370,"props":417,"children":418},{},[419],{"type":210,"value":420},"Exact matching, no readable names",{"type":205,"tag":206,"props":422,"children":423},{},[424],{"type":210,"value":425},"The third form discloses the least and still solves the problem — we only need\nto know that function 2469 in the new build is the same function as 2461 in\nthe old one.",{"type":205,"tag":259,"props":427,"children":429},{"id":428},"the-name-map-in-detail-what-we-dont-ask-for",[430],{"type":210,"value":431},"What we don't ask for",{"type":205,"tag":206,"props":433,"children":434},{},[435],{"type":210,"value":436},"No source code, no private build-system symbols, no debug build.",{"type":205,"tag":224,"props":438,"children":440},{"id":439},"a-fourth-optional-item-announce-a-build",[441],{"type":210,"value":442},"A fourth, optional item: announce a build",{"type":205,"tag":206,"props":444,"children":445},{},[446],{"type":210,"value":447},"We poll the patch manifest every fifteen minutes to notice a new build.\nThat's polite, but wasteful for both sides. A field in the manifest, or a\nsmall feed, would let us react to a signal instead of a timer. Optional — the\npolling works, and we keep it under one request per quarter hour.",{"type":205,"tag":224,"props":449,"children":451},{"id":450},"acceptance-criteria",[452],{"type":210,"value":453},"Acceptance criteria",{"type":205,"tag":455,"props":456,"children":457},"ul",{},[458,471,476,481],{"type":205,"tag":459,"props":460,"children":461},"li",{},[462,464,469],{"type":210,"value":463},"The ",{"type":205,"tag":282,"props":465,"children":466},{},[467],{"type":210,"value":468},"build_id",{"type":210,"value":470}," custom section is present in the published module.",{"type":205,"tag":459,"props":472,"children":473},{},[474],{"type":210,"value":475},"The assert strings and the source paths stay in the data section.",{"type":205,"tag":459,"props":477,"children":478},{},[479],{"type":210,"value":480},"A name map, in one of the three forms above, is published with each build,\nat a stable URL.",{"type":205,"tag":459,"props":482,"children":483},{},[484],{"type":210,"value":485},"The map covers the functions in the code section of the same build.",{"type":205,"tag":241,"props":487,"children":489},{"title":488},"Why this matters for reports like these",[490],{"type":210,"value":491},"Every report in this section exists because the assert strings are in the\nbinary — they're what lets us map a finding to a translation unit. A stable\nplatform host keeps reporting defects with function indices, byte offsets, and\nreproducible measurements.",{"title":493,"searchDepth":494,"depth":494,"links":495},"",4,[496,498,504,508,509],{"id":226,"depth":497,"text":229},2,{"id":249,"depth":497,"text":252,"children":499},[500,502,503],{"id":261,"depth":501,"text":264},3,{"id":272,"depth":501,"text":275},{"id":291,"depth":501,"text":294},{"id":309,"depth":497,"text":312,"children":505},[506,507],{"id":325,"depth":501,"text":328},{"id":428,"depth":501,"text":431},{"id":439,"depth":497,"text":442},{"id":450,"depth":497,"text":453},"markdown","docs",{"source":513,"path":514,"stem":515,"dir":516,"extension":517},"content","en\u002F1.docs\u002F3.upstream\u002F6.proposals\u002F1.build-identification.md","en\u002F1.docs\u002F3.upstream\u002F6.proposals\u002F1.build-identification","proposals","md",{"requestedPath":170,"resolvedPath":170,"alternates":519},[520],{"locale":8,"path":170,"source":521},"variant",{"requested":523,"resolved":524,"usedFallback":6},{"locale":8},{"locale":8},{"previous":526,"next":528},{"title":153,"id":154,"canonicalKey":155,"locale":8,"draft":6,"navigation":527,"path":157},{"title":153},{"title":172,"id":173,"canonicalKey":174,"locale":8,"draft":6,"navigation":529,"path":176},{"title":172},1786362929303]