First-party C++23 code lives in src/: entry points in src/wrapper/, runtime coordination in src/manager/, user-facing behavior in src/features/, version profiles and game layouts in src/game/, feature knobs in src/config/, reusable helpers in src/utils/. Host tests live in tests/, packaging files in module/, build/analysis scripts in scripts/, and notes in docs/. Detailed layouts: docs/project-structure.md, docs/architecture/, docs/offsets/.
Dependencies are git submodules under third_party/. Never edit a submodule — git submodule update --init --recursive wipes local changes, and that command is in our own docs. To change a dependency's behavior, add a module in the top-level Android.mk that compiles it differently (see how build.ps1 patches LSPlt into a throwaway build/generated/ copy).
Do not reinvent the wheel. Search src/utils/, third_party/, and the Internet first, then reuse established parsing, hooking, hashing, archive, and memory components.
- Target C++23, but the usable feature set is set by the standard library, not the compiler.
src/is built against the vendoredthird_party/libcxx(LLVM 19 fork,-fno-exceptions -fno-rtti); host tests compile the same sources against MSVC STL. Writesrc/against the vendored libcxx column. Never infer availability from a clang version number — run the probes inscripts/(capability_probe.cpp,refactor_probe.cpp; they deliberately carry no version guards, so a missing feature fails the build) or checkdocs/cpp/feature-matrix.md. - Before using a new library feature, add it to
scripts/refactor_probe.cppand compile both sides:sh scripts/check-one.sh <file>or the conformance sweep insidetests/run_host_tests.py. - Do not over-design. Apply the deletion test and introduce a new module, seam, adapter, or abstraction only when it removes real duplication or gives callers a smaller, deeper interface.
- Host tests use the NDK clang++ with
-target x86_64-pc-windows-msvc. Do not switch them back to a MinGW target — clang's MinGW driver needs GCC'slibgcc_eh/libgcc_s, which no NDK ships, so the link cannot succeed.
Toolchain locations (NDK, Visual Studio, Windows SDK, zlib) are discovered at runtime, never hard-coded. All discovery lives in tests/toolchain_probe.py — it is shared by run_host_tests.py, run_arcpkg_corpus.py, scripts/check-one.sh, and scripts/verify_linked_symbols.py, so there is exactly one place to fix. Override with environment variables when the default search misses: ANDROID_NDK_ROOT / ANDROID_NDK_HOME / ANDROID_SDK_ROOT / ANDROID_HOME, MSVC_INSTALL, WINDOWS_SDK_DIR, ZLIB_ROOT. Run python tests/toolchain_probe.py <name> (see PROBES in that file) to see what any of them resolves to.
Do not write absolute paths, drive letters, usernames, or toolchain version directories into scripts, docs, or tests.
git submodule update --init --recursiveinitializes the pinned dependencies../build.ps1produces a debug arm64 build; it requires NDK r30 or newer and picks the newest NDK under the resolved search root. NDK r29 and older are rejected../build.ps1 --relbuilds, strips, and packagesbuild/ArcHelperModule.zip../build.ps1 --rebuild --relforces a clean release build.build.ps1 --helplists the rest.python tests/run_host_tests.pycompiles every host test with the newest installed NDKclang++and validates hashing, JSON, logging, hooks, memory patching, AFF normalization, chart importing, image resampling, and a full-source production-conformance sweep. A clean run prints 21 green lines in about 2.5 minutes; fewer lines means it died partway. Hard prerequisite: at least 7 sample packages under the siblingArcCreaterepository (../ArcCreate/arcpkg-samples/*.arcpkgand../ArcCreate/raw-zip-samples/*.zip) — the script exits otherwise.g++compatibility is not a test target.python tests/run_arcpkg_corpus.py [dir]imports real.arcpkg/.zippackages (default.tmp/arcpkg) and reports per-chart diagnostics. SetARC_OFFICIAL_APKto a local Arcaea Infinity APK to also run the official AFF grammar pass; without it that pass is reported as skipped. There is no in-repo default for the APK because it is not redistributable.python tests/verify_profile.pychecks pinned offsets for 6.16.2c, 6.16.8c, 7.0.0c, and 7.0.1c against../<version>/libcocos2dcpp.so, verifying each binary's exact SHA-256, thesetAppVersion/__cxa_throwdynamic symbols, function prologues, and runtime patch sites. It also verifies the FMOD provider'sloadBGMsymbol if.tmp/arcaea_6.16.2c_arc_helper_diag.apkis present. Versions whose.sois missing are reported as skipped, not failed.bash scripts/check-one.sh <src files...>compile-checks individual files against both standard libraries in seconds.python scripts/verify_linked_symbols.py <unstripped .so>audits the built module's remaining external dependencies; passbuild/obj/local/arm64-v8a/libarc_helper.so(thebuild/libs/copy is stripped and is rejected). Run it after any change that touches templates or cross-TU symbols.python scripts/port_match.pylocates relocated ARM64 functions across game versions when porting offsets. See its module docstring for the workflow.- Notes on the C++ baseline, toolchain, and the four build blind spots:
docs/cpp/index.md.
Use four-space indentation and follow the surrounding C++ style. Types and public methods use PascalCase; local variables and private fields use snake_case, with private members ending in _; constants use kPascalCase. Pair implementation files as Name.hpp and Name.cpp, keep code in namespace arc_helper, and prefer bounded parsing plus explicit validation for untrusted runtime data. The build disables exceptions and RTTI, so use status values and error strings instead. Treat warnings as failures (-Wall -Wextra -Werror).
Add focused host coverage for portable logic, naming new files *_host_test.cpp. Pure algorithms that only touch caller-supplied memory can be lifted from an anonymous namespace into a header-only inline function to gain host coverage — see src/utils/memory/ByteScanner.hpp; functions that read live game objects cannot be host-tested and need manual review plus a production compile. For hook profiles or layout changes, verify signatures, offsets, struct assertions, the matching game binary hash, and an arm64 release build. No coverage percentage is enforced; regressions in parsing, archive safety, configuration defaults, and unsupported-version behavior require tests.
History favors short, imperative subjects, sometimes with feat: or fix: prefixes. Keep each commit scoped. Pull requests should describe affected game versions and features, list commands run, link relevant issues, and include device logs or screenshots for runtime-visible behavior. Document new offsets and never commit game binaries, generated build/ output, or personal config.json files.