Skip to content

feat: MMCL Phase 0 — complete macOS Minecraft launcher - #1

Merged
Lhy723 merged 23 commits into
mainfrom
codex-mmcl-phase0
May 29, 2026
Merged

feat: MMCL Phase 0 — complete macOS Minecraft launcher#1
Lhy723 merged 23 commits into
mainfrom
codex-mmcl-phase0

Conversation

@Lhy723

@Lhy723 Lhy723 commented May 29, 2026

Copy link
Copy Markdown
Owner

Summary

Complete macOS Minecraft launcher with PCL-parity features, built with SwiftUI + macOS 26 Liquid Glass design.

Core Features

  • Launcher: Instance picker, block icons, launch button with pulse animation
  • Download Center: 7 tabs (原版游戏, Mod, 整合包, 数据包, 资源包, 光影包, 下载进度)
  • Modrinth/CurseForge: Search, browse, install with stagger animations
  • Instance Management: Create, copy, rename, delete, status persistence
  • Java Management: Auto-scan, portable JDK install from Adoptium, Apple Silicon optimization
  • Account System: Microsoft OAuth + offline accounts, editable username
  • Download Engine: Concurrent downloads, pause/resume/cancel, real-time speed
  • Mod/Resource Pack/Shader Pack: Local management (enable/disable/delete)
  • Skin Management: Import, preview, apply
  • Server List: Multiplayer server management
  • Diagnostics: Java mismatch detection, crash log analysis
  • Auto-Update: GitHub Releases check + download
  • Log Viewer: Real-time game log with auto-refresh

UI/UX

  • macOS 26 Liquid Glass design patterns
  • Spring animations throughout (configurable duration in settings)
  • Scroll-based stagger animations for search results
  • Block icons from PCL (Grass, CommandBlock, CobbleStone, Anvil, etc.)
  • Sheet entrance animations (opacity + offset)
  • ContentUnavailableView centering fix

Infrastructure

  • @MainActor on LauncherStore
  • GitHub Actions CI + Release workflows
  • SwiftLint configuration
  • Comprehensive README with screenshots

Test plan

  • Build succeeds on macOS
  • All unit tests pass
  • Instance creation + download flow works
  • Mod search + install works
  • Java detection + portable install works
  • Animations render correctly
  • Settings persistence works

🤖 Generated with Claude Code

Lhy723 and others added 23 commits May 27, 2026 23:21
…ncherStore

- Inject instanceService via protocol-based init parameter
- Add defaultMemoryMegabytes, defaultOfflineUsername, preferredDownloadSource, showingCreateSheet, showingLogSheet @published properties
- Add createInstance() with diagnostics for success/failure
- Add loadLogContent() for reading game logs
- Add test with MockInstanceService to verify instance creation and selection

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…e bindings

- ContentView now receives store via @ObservedObject instead of owning @StateObject
- "新增实例" button wired to store.showingCreateSheet
- Added .sheet modifiers for create and log sheets
- SettingsView replaced @AppStorage properties with store bindings
- Added LogViewerSheet stub for compilation (full impl in Task 6)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace stub LogViewerSheet with full log viewer that displays
monospaced log content in a scrollable sheet, and wire the
"打开日志" button in InstanceDetailView to present it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement deleteInstance() that removes the instance directory from disk
(if it exists), removes the instance from the list, updates selection, and
logs a diagnostic. Add a destructive context menu to sidebar instance rows.
Add testStoreDeletesInstanceAndUpdatesSelection to verify the behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace serial download execution with TaskGroup-based concurrency
(max 4 concurrent). Add cancelDownloads() to mark queued/running jobs
as failed, with a cancel button in DownloadsView.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- FabricLoaderVersion and FabricProfile models for parsing Fabric meta API
- FabricService with loader version fetching, profile fetching, and install logic
- installFabricLoader() in LauncherStore to orchestrate Fabric install flow
- "安装 Fabric" button in InstanceDetailView (visible when loader is .fabric)
- Two new tests for Fabric model parsing (loader versions and profile)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…gration

Add Modrinth models (search, project, version, file), expand ModrinthServicing
with search/fetch/download methods, add store search + install logic, and
replace static ContentProjectsView with live Modrinth search UI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add QuiltService and ForgeService with model types, API fetching,
and version metadata generation. Wire into LauncherStore and add
install buttons to InstanceDetailView.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Users can now click a Modrinth search result to see available versions,
pick one, and install it to the selected instance's mods directory.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add MinecraftAccount model, AuthService with full Microsoft/Xbox/XBL/XSTS
token exchange chain, account management in store, account picker in
toolbar, and account section in settings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add rename sheet, instance copy via context menu, local mod scanning
with enable/disable/delete, and resource pack management for instances.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nd theme switching

- Add NeoForgeVersion model and NeoForgeService for fetching/installing NeoForge loaders
- Add DownloadSpeedTracker with real-time speed display in DownloadsView
- Add crash analysis to DiagnosticService with crash log parsing and error classification
- Add AppColorScheme enum with system/light/dark options in SettingsView
- Wire NeoForge install button into InstanceDetailView for Forge instances
- Wire crash analysis button into InstanceDetailView

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace static log viewer with live-updating one (1s timer, auto-scroll)
- Add CurseForge integration with search API, sidebar tab, and result view
- Add auto-update check against GitHub releases in settings
- Add built-in help view as settings tab with usage guide sections

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…i18n, JVM presets

- Shader pack management: scan/delete shader packs with ShaderPackListView
- Version list filtering by release type (release/snapshot/beta/alpha)
- Game resolution settings in LaunchProfile, wired to launch substitutions
- Language picker and AppLanguage enum for future i18n support
- JVM argument presets (G1GC, ZGC, performance, large memory) in settings
- Update all test files for new LaunchProfile resolution fields

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add DownloadStatus.paused and DownloadJob.resumeData
- Rewrite DownloadService as URLSessionDownloadDelegate for streaming
- Add startDownload, pauseDownload, resumeDownload, cancelAllDownloads
- Update store with pauseDownloads, resumeDownloads, new cancelDownloads
- Add pause/resume toggle button in DownloadsView
- Update download tests for new callback-based API

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Parse release assets to find DMG/ZIP download URL
- Download update to temp directory and open with /usr/bin/open
- Add "下载更新" button in settings when update available
- Show download progress state in UI

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Skin management: SkinInfo model, SkinService, SkinPickerView, sidebar entry
- Profile export/import: ExportData types, ProfileExportService, settings UI
- Custom background: BackgroundImage type, image picker with opacity/blur sliders
- Auto-update download and install from GitHub releases
- Download pause/resume/cancel with URLSessionDownloadDelegate streaming

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- ServerInfo model with ping result, favorite, and address/port
- ServerListService with load/save/ping via TCP (Network framework)
- ServerListView with add/edit/delete/ping/favorite toggle
- Sidebar entry for server list, Section.serverList case
- Ping all servers button with color-coded latency display

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… of Button actions

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ign, GitHub integration

Launcher redesign:
- Simplified launcher page: instance picker + launch button only
- Instance creation moved to download center
- Instance card shows block icon, status, last played
- Gear button opens InstanceSettingsView (push navigation)

Download center:
- Search results stagger animation (scroll-based visibility)
- Block icons for version types (Grass/CommandBlock/CobbleStone)
- Spring animations throughout (configurable duration)
- Tab switching with fade-in entrance animation

Java management:
- Portable JDK installation from Adoptium (8/17/21)
- Multi-version management with delete support
- Auto-detect Apple Silicon for optimized JVM args (ZGC)
- Scan portable JDK directory on startup

Instance management:
- Duplicate instance prevention (same version+loader)
- Status persistence to disk
- File-based status verification at startup
- Last selected instance remembered via UserDefaults

UI/UX:
- Account picker: editable offline username
- ContentUnavailableView centering fix (all pages)
- Sheet entrance animations (opacity + offset)
- macOS 26 Liquid Glass design patterns
- App logo in launcher header and about page
- GitHub repository link button

Infrastructure:
- @mainactor on LauncherStore
- GitHub Actions CI (build + test + lint)
- Release workflow (DMG packaging)
- SwiftLint configuration
- Comprehensive .gitignore
- README with screenshots and documentation
- Block icon assets from PCL

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Lhy723
Lhy723 merged commit 4499a17 into main May 29, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant