Skip to content

NSP script: the build folder's shader folder is named shader.noindex, so Spotlight leaves the files a shader build writes alone - #1438

Closed
PucaVaz wants to merge 1 commit into
seedds:mainfrom
PucaVaz:nsp-build-noindex
Closed

PucaVaz wants to merge 1 commit into
seedds:mainfrom
PucaVaz:nsp-build-noindex

Conversation

@PucaVaz

@PucaVaz PucaVaz commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

What and why

After a full Ocarina of Time build, mds_stores stayed at 100–156% CPU for more than 40 minutes with nothing else running, and mdfind found the build folder's .metal sources (measurement on #1355). Spotlight indexes each file the shader step writes, and reads the text of the .metal sources: b-<chain>/ holds a file per shader variant until the step packs them into one, 195,157 for Ocarina of Time. On macOS 27 only a folder whose name ends in .noindex keeps Spotlight out; a .metadata_never_index file inside does not, as @lunks found in #1355, which names the temporary folder tmp.noindex.

The shader folder is now shader.noindex (SHADER). A shader/ from before moves there before any step reads it: a rename keeps every file and its times, and no step's key holds the folder's path, so the split, the libraries and the compile cache are reused and nothing is translated again. The first build after the move packs the Mac app again, since pack_app.py's key names its inputs' paths. When both names exist (an older checkout made shader/ again), shader/ stays and a [NOTE] line names it. bench.py, regress.py and bug_report.py read either name.

This is independent of #1355: it is based on main and does not touch the temporary folder. @lunks will rebase #1355 on whichever lands first; a trial merge of the two branches (git merge-tree) has no conflict.

Which folders Spotlight spends its time on

MacBook Air M4, 24 GB, macOS 27.2. APFS clones of the subfolders of that Ocarina of Time build folder went into a folder Spotlight indexes (~/nxnative-spotlight-test, never the real build folder), one at a time. The figure is the CPU of mds, mds_stores and mdworker_shared above their idle level, sampled each second until the minute's mean was back at idle. mdfind found every entry of the shader, pso/, logs/ and extract/ clones afterwards. The two shader samples are the files whose names start with 0, a sixteenth.

Folder Files Spotlight CPU Whole folder
shader/cache/b-<chain>/, a sixteenth 11,973 152 s, up to 772% 195,157 files, about 2,500 s
the same files deleted 11,973 under 1 s
shader/cache/cas/ (before cas.db), a sixteenth 19,839 210 s, up to 540% 311,903 files, about 3,300 s
pso/ 1,162 33 s
patched_v131072/, profile/, tools/, font/, app/ 45 4 s
logs/ (one log of 277 MB) 15 3 s
extract/ (a 26 GB RomFS.img) 7 2 s

About 5,800 s for the shader files of a build folder from before the one-file libraries and cache: an hour or more at 100–156%, which covers the more than 40 minutes seen. On main the libraries and cache are one file each at rest, but a shader build still writes b-<chain>/, about 2,500 s of indexing for Ocarina of Time. Every other folder together took 42 s, so they keep their names; logs/ and profile/ are also the paths docs/frontends.md gives front ends. Importers (mdimport -t): .metal, .tsv and .log go through the RichText importer, which reads their text; .json, .metallib, .mtl4a and RomFS.img get none. A game benchmark ran in another session during most of the measurement.

Checked

  • Tests: CI's tool-test loop, every dm/tools/tests/test_*.py, dm/ios/tests/test_*.py and dm/gfx/tests/test_*.py with DM_GAME=010015100B514000 and DMSH_TEST_XLATE set: 154 files, all pass but test_tree_tar.py's test_packs_a_quiet_folder_and_keeps_its_attributes, which fails the same on main on this Mac (the 14 dm/gfx/tests files that compile Metal ran with Xcode 27.2's DEVELOPER_DIR, as the selected Xcode beta has no Metal toolchain). New: test_nsp_chain.py Spotlight (the move keeps contents and times, the new name wins over a leftover, a link is left alone, no work / 'shader' left in the script, bench.py reads the same name), test_nsp_work_dir.py test_shader_folder_from_before_moves_first (main moves it before any step), test_bench.py test_shader_folder; test_bug_report.py, test_regress.py and test_nsp_mac_app.py follow the name. lint_python.py with the pinned ruff 0.17.2 and pyright 1.1.414: no new finding.
  • The real folder: the shader package (516 MB) and keys of that Ocarina of Time build, cloned: its pkg.outputs.key matches split_output_key before and after move_to_noindex.
  • Games run: none. No build was run with this change: a full Ocarina of Time shader build takes about two hours here, so the reuse after the move is shown by the keys, not by a build.
  • Devices and OS: MacBook Air M4, 24 GB, macOS 27.2.
  • No chain, host or shader tool change. regress.py only finds the shader folder by either name now (its tests pass); regress.py check was not run.

Front ends

Front-ends: interface: the build folder's shader folder is shader.noindex/ instead of shader/ (cache/, ios/, vk/, gl/, pkg/ and the keys inside it, and the Mac run command's DM_MSL_DIR); a shader/ from before moves there at the next build.

Docs

  • The finding is in its docs/reference/<subsystem>.md entry (Spotlight indexes the files a shader build writes), and python3 dm/tools/docs_symptoms.py was run (the symptom index). docs/development.md, the bug report form and the two game notes that named shader/ follow the name.
  • A chain tool changed: not applicable
  • No game files, keys or data extracted from a game in the change or the attachments

Drafted with Claude; reviewed by me.

🤖 Generated with Claude Code

…leaves the files a shader build writes alone

After a full Ocarina of Time build, mds_stores stayed at 100-156% CPU for
more than 40 minutes with nothing else running, and mdfind found the build
folder's .metal sources. Spotlight indexes every file under the home folder
and reads the text of the .metal sources. The shader step writes a file per
shader variant into shader/cache/b-<chain>/ before it packs them into one:
195,157 for Ocarina of Time, 42,850 of them .metal. That build was made
before the libraries and the compile cache became one file each, so its
folder kept them, with 311,903 more files in the cache. On macOS 27 only a
folder whose name ends in .noindex keeps Spotlight out; a
.metadata_never_index file inside does not (lunks, PR seedds#1355, which names the
temporary folder so).

The shader folder is SHADER = 'shader.noindex'. A shader/ from before moves
there before any step reads it. A rename keeps every file and its times,
and no step's key holds the folder's path, so the split, the libraries and
the compile cache are reused and nothing is translated again. The first
build after the move packs the Mac app again, as pack_app.py's key names its
inputs' paths. When both names exist (an older checkout made shader/
again), shader/ stays and a [NOTE] line names it. bench.py, regress.py and
bug_report.py read either name.

Measured on a MacBook Air M4, macOS 27.2, with APFS clones of that build
folder's subfolders in a folder Spotlight indexes, as the CPU of mds,
mds_stores and mdworker_shared above idle until it settled:
- a sixteenth of b-<chain>/ (11,973 files): 152 s, at up to 772%; about
  2,500 s for the whole folder a shader build writes. Deleting them: under 1 s.
- a sixteenth of the old compile cache (19,839 files): 210 s; about 3,300 s
  for the whole.
- pso/ (1,162 files) 33 s; patched_*/, profile/, tools/, font/ and app/
  (45 files) 4 s; logs/ (15 files, one of 277 MB) 3 s; extract/ (a 26 GB
  RomFS.img) 2 s.
So the shader folder is where the indexing is, and the other folders keep
their names: logs/ and profile/ are also paths front ends read. A game
benchmark ran in another session during most of this.

Checked: CI's tool-test loop passes but for test_tree_tar.py's
test_packs_a_quiet_folder_and_keeps_its_attributes, which fails the same on
main on this Mac; lint_python.py has no new finding. The shader package
and keys of that build, cloned: pkg.outputs.key matches split_output_key
before and after the move. No build was run with this change.

Front-ends: interface: the build folder's shader folder is shader.noindex/ instead of shader/ (cache/, ios/, vk/, gl/, pkg/ and the keys inside it, and the Mac run command's DM_MSL_DIR); a shader/ from before moves there at the next build.

_Drafted with Claude; reviewed by me._
@github-actions github-actions Bot added packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts) docs Documentation ci Continuous integration and repository settings (.github) game: 010014E00DB56000 Digimon Story Cyber Sleuth: Complete Edition game: 0100535012974000 Hades labels Nov 6, 2026
fpedrolucas95 added a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
…lder is named shader.noindex, so Spotlight leaves the files a shader build writes alone
gnosticgeek pushed a commit to gnosticgeek/nxforge that referenced this pull request Nov 6, 2026
…rina of Time, with the reasons

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qteK29T18U8p1c9LsVY8g
gnosticgeek pushed a commit to gnosticgeek/nxforge that referenced this pull request Nov 6, 2026
# Conflicts:
#	docs/agents/symptoms.md
#	docs/development.md
#	docs/reference/packing.md
#	scripts/bench.py
#	scripts/build_ipa_from_nsp.py
#	scripts/regress.py
@PucaVaz

PucaVaz commented Nov 7, 2026

Copy link
Copy Markdown
Contributor Author

Closing: since 9c2fb0c a build no longer keeps the per-shader files this measured (195,157 in b-<chain>/, which kept mds_stores at 100–156% CPU for over 40 minutes after a full Ocarina of Time build); what's left is short-lived and unmeasured here.

@PucaVaz PucaVaz closed this Nov 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Continuous integration and repository settings (.github) docs Documentation game: 0100535012974000 Hades game: 010014E00DB56000 Digimon Story Cyber Sleuth: Complete Edition packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant