Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ xcrun simctl io <device-udid> screenshot /tmp/shot.png # no screen-recording p

Debug builds run the solver and its table generation ~10–30× slower (first-launch table generation: ~20 s debug vs ~0.2 s release). That is not a hang. Always validate performance claims with `-c release`.

Optimal-solver pattern databases are baked in-app (Settings › Solving): the 7-edge tier (~0.5 GB) takes ~2 min on an M5, the 8-edge tier (~5.15 GB) ~75 min, both cached in the app container. The gitignored `Seeds/` folder at the repo root is bundled by a build phase when present (compressed seeds; produced via the in-app bake, synced manually from the container's `Seeds/` export). Tables are reproducible artifacts — never commit them.
Optimal-solver pattern databases are baked in-app (Settings › Solving): the 7-edge tier (~0.5 GB) takes ~2 min on an M5, the 8-edge tier (~5.15 GB) ~75 min, both cached in the app container. The gitignored `Seeds/` folder at the repo root is bundled **only by the `cubeone-seeded` scheme** (its `Release-Seeded` configuration sets `INCLUDE_PDB_SEEDS=YES`); the regular `cubeone` scheme skips the ~2.3 GB copy so daily builds stay small. Archive with `cubeone-seeded` to ship bundled tables. Both schemes are shared (`xcshareddata/xcschemes`) — Xcode no longer auto-generates schemes for this project. Tables are reproducible artifacts — never commit them (the `bake-tables.yml` workflow can rebuild seeds on CI; cross-machine bakes verified byte-identical).

## Architecture

Expand Down
114 changes: 113 additions & 1 deletion cubeone.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Bundle any locally baked pattern-database seeds (gitignored;\n# produced by the in-app Prepare flow and synced via the documented\n# recipe). Missing seeds are fine - the app falls back to generating.\nSEEDS=\"$SRCROOT/Seeds\"\nDEST=\"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH\"\nfor name in optimal-corners.pdb.lzfse optimal-edges-a7.pdb.lzfse optimal-edges-b7.pdb.lzfse optimal-edges-a8.pdb.lzfse optimal-edges-b8.pdb.lzfse; do\n if [ -f \"$SEEDS/$name\" ]; then\n cp -f \"$SEEDS/$name\" \"$DEST/$name\"\n fi\ndone\nexit 0\n";
shellScript = "# Bundle any locally baked pattern-database seeds (gitignored).\n# Only the Release-Seeded configuration (cubeone-seeded scheme) sets\n# INCLUDE_PDB_SEEDS=YES - daily Debug/Release builds stay small and\n# fast; the app falls back to in-app generation without seeds.\nif [ \"$INCLUDE_PDB_SEEDS\" != \"YES\" ]; then\n echo \"Skipping PDB seeds (INCLUDE_PDB_SEEDS is not YES)\"\n exit 0\nfi\nSEEDS=\"$SRCROOT/Seeds\"\nDEST=\"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH\"\nfor name in optimal-corners.pdb.lzfse optimal-edges-a7.pdb.lzfse optimal-edges-b7.pdb.lzfse optimal-edges-a8.pdb.lzfse optimal-edges-b8.pdb.lzfse; do\n if [ -f \"$SEEDS/$name\" ]; then\n cp -f \"$SEEDS/$name\" \"$DEST/$name\"\n fi\ndone\nexit 0\n";
};
/* End PBXShellScriptBuildPhase section */

Expand Down Expand Up @@ -288,6 +288,69 @@
};
name = Release;
};
000000000000000013000000 /* Release-Seeded configuration for PBXProject "cubeone" */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APPLETVOS_DEPLOYMENT_TARGET = 27.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DRIVERKIT_DEPLOYMENT_TARGET = 27.0;
ENABLE_ENHANCED_SECURITY = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 26.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PROJECT_UNIQUE_VALUE = I5CVWRAE;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_COMPILATION_MODE = wholemodule;
WATCHOS_DEPLOYMENT_TARGET = 27.0;
XROS_DEPLOYMENT_TARGET = 27.0;
};
name = "Release-Seeded";
};
000000000000000111000000 /* Debug configuration for PBXNativeTarget "cubeone" */ = {
isa = XCBuildConfiguration;
buildSettings = {
Expand Down Expand Up @@ -380,6 +443,53 @@
};
name = Release;
};
000000000000000113000000 /* Release-Seeded configuration for PBXNativeTarget "cubeone" */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = cube/cube.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10101;
DEVELOPMENT_TEAM = 7P9PPXP2SF;
ENABLE_APP_SANDBOX = YES;
ENABLE_ENHANCED_SECURITY = NO;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SELECTED_FILES = readonly;
GCC_C_LANGUAGE_STANDARD = gnu23;
GENERATE_INFOPLIST_FILE = YES;
INCLUDE_PDB_SEEDS = YES;
INFOPLIST_KEY_CFBundleDisplayName = "Cube One";
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.chentianren.cube;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
SDKROOT = auto;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 27.0;
};
name = "Release-Seeded";
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
Expand All @@ -388,6 +498,7 @@
buildConfigurations = (
000000000000000011000000 /* Debug configuration for PBXProject "cubeone" */,
000000000000000012000000 /* Release configuration for PBXProject "cubeone" */,
000000000000000013000000 /* Release-Seeded configuration for PBXProject "cubeone" */,
);
defaultConfigurationName = Release;
};
Expand All @@ -396,6 +507,7 @@
buildConfigurations = (
000000000000000111000000 /* Debug configuration for PBXNativeTarget "cubeone" */,
000000000000000112000000 /* Release configuration for PBXNativeTarget "cubeone" */,
000000000000000113000000 /* Release-Seeded configuration for PBXNativeTarget "cubeone" */,
);
defaultConfigurationName = Release;
};
Expand Down
66 changes: 66 additions & 0 deletions cubeone.xcodeproj/xcshareddata/xcschemes/cubeone-seeded.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2700"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "000000000000000100000000"
BuildableName = "cubeone.app"
BlueprintName = "cubeone"
ReferencedContainer = "container:cubeone.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Release-Seeded"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "000000000000000100000000"
BuildableName = "cubeone.app"
BlueprintName = "cubeone"
ReferencedContainer = "container:cubeone.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release-Seeded"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release-Seeded"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
76 changes: 76 additions & 0 deletions cubeone.xcodeproj/xcshareddata/xcschemes/cubeone.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2700"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "000000000000000100000000"
BuildableName = "cubeone.app"
BlueprintName = "cubeone"
ReferencedContainer = "container:cubeone.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "000000000000000100000000"
BuildableName = "cubeone.app"
BlueprintName = "cubeone"
ReferencedContainer = "container:cubeone.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "000000000000000100000000"
BuildableName = "cubeone.app"
BlueprintName = "cubeone"
ReferencedContainer = "container:cubeone.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Loading