Here we have a overview of the toolchain & runtime of this project
For the whole project, we have
- Node.js >=18.17.0. The core libraries base environment.
- Electron 27. The actual runtime of the launcher.
- pnpm. Used for monorepo package management.
- TypeScript. The whole project uses as much TypeScript as possible.
For main process (Electron), we have
- esbuild. We use esbuild to build our main process TypeScript.
For renderer side, which is the pure front-end
- Vue. Used to build user interfaces.
- Vite. Used as our build system.
- Vuetify. Used as a component library.
- Windi CSS. Used for CSS tooling.
- Vue Composition API. The bridge for compositional API for Vue 2. Once the Vuetify upgrade to the Vue 3, the Vue will be upgraded and this will be removed.
- xmcl
- The linked git repo launcher-core is a git submodule in this project.
- Implements the core Minecraft install & launch logic, and expose them as a library.
- xmcl-electron-app
- Use Electron to implement the runtime.
- This directly depends on the xmcl-runtime.
- This implicitly depends on xmcl-keystone-ui (temporally, might be removed later?)
- xmcl-keystone-ui
- The major default UI of the launcher.
- 100% browser compatible. No Electron API involved in this project.
- xmcl-runtime
- The core implementation of the launcher architecture. This only depends on Node.js, and does not require Electron runtime.
- xmcl-runtime-api
- This is the shared code & API for XMCL runtime. It can be used for renderer app (browser side)
The launcher is composed by "server/client" or "main/renderer". They communicates with each other by Electron's ipcMain and ipcRenderer.
The main is the "backend" of the launcher. It manages the windows, and all the persistent data/state of the app. It manages the state by Vuex. Once the state/data has been modified by a Vuex commit, it will broadcast a ipc message containing the mutation info the all the renderer. At the same time, it will trigger the save action of the modified module to write the change on disk.
The renderer is/are just (a) browsers which communicate with main. It maintains a copy of the store. (I can be a full copy, or a partial copy) User's input will trigger an action or commit, and it will be sync to the main. Though, it does't require any extra action for developer. The local commit and action will automatically send to main. The developer can treat the renderer as a normal vue application.
If you are interested in a specific page logic, you can go to xmcl-keystone-ui/src/windows/main/views
. The .vue
files under this folder are the major component used in the launcher. The prefix of the file are the domain of the UI.
See some examples:
AppSideBar.vue
is the sidebar component, and theAppSideBarInstanceItem.vue
is the component used inAppSideBar.vue
representing an instance.Curseforge.vue
is the CurseForge page component, and theCurseforgeCategories.vue
is the category card used inCurseforge.vue
page.
If you are interested in core logic, you can goto xmcl-runtime/services/
. Each file under it are representing a service for a specific domain/aspect of the launcher logic. During this process, you should also aware about the corresponding files under the xmcl-runtime-api/services/
, which declare the interface of the actual services.
Some examples:
xmcl-runtime/services/InstanceService.ts
contains the API implementation of add/remove/update of instances. Thexmcl-runtime-api/services/InstanceService.ts
contains the interface of theInstanceService
xmcl-runtime/services/InstanceVersionService.ts
contains the API implementation of checking instance version health. It will determine what version will the instance use, and whether should we install that version.xmcl-runtime/services/InstallService.ts
contains the API implementation of install Minecraft/Forge/Fabric and etc.xmcl-runtime/services/LaunchService.ts
contains the API implementation of launch an instance.
Highly recommend to use the VSCode to open the project.
Clone the project with submodule flag --recurse-submodules
.
git clone --recurse-submodules https://github.com/Voxelum/x-minecraft-launcher
If you forget to add --recurse-submodules
flag, you need to initialize & update the git submodule manually.
git submodule init
git submodule update
Install the project using pnpm:
pnpm install
解决中国国内安装依赖(如 Electron)太慢的办法
打开你的 git bash,在 pnpm i
前面加上 registry=https://registry.npm.taobao.org electron_mirror="https://npm.taobao.org/mirrors/electron/"
。使用国内阿里提供的 npm 以及 Electron 的镜像。
最终输入的 command 也就是
registry=https://registry.npm.taobao.org electron_mirror="https://npm.taobao.org/mirrors/electron/" pnpm i
You should set the CURSEFORGE_API_KEY
by creating a .env
file under xmcl-electron-app
. This .env
file is added in .gitignore
file.
DO NOT LEAK YOUR CURSEFORGE API KEY
Then you can run the launcher
Go Run and Debug
section, use the profile Electron: Main (launch)
to start the electron. (Hot key F5)
Open one terminal
# Start a dev server for UI
npm run dev:renderer
Open another terminal
# Start watching main process code
npm run dev:main
You have code change, and you want to update the change to the running launcher instance.
The Vite provide hot reload, it should update automatically. If something went wrong, you can refresh the browser by Ctrl+R
.
If you use VSCode to launch the launcher, after you changed the code, you can press the reload button on VSCode debugger.
If you don't use VSCode to launch, it should close Electron and reload automatically.
The launcher core is in separated project written in TypeScript.
Please open issue there if you identify any issue related to it.
- Create a new file for hook in
src/renderer/composables
folder, and export the hook throwsrc/renderer/composables/index.ts
- Wrap Vuex operation in your hook
- Import your hook by
import { yourHook } from '/@/composables'
in your Vue file - Use hook in Vue file without directly access of Vuex
The project includes VSCode debugger configs. You can add breakpoint on line and debug. Currently, VSCode debugger method only supports debug on main process.
(You can use Chrome Devtools for renderer process anyway)
We have two options now:
- Electron: Main (launch)
- Electron: Main (attach)
If you use the first one to launch, it will automatically attach the debugger to the instance.
This project follow the conventional commits. In short, the first line of your commit message should be:
commit type: commit description
There are several avaiable commit type: feat
, fix
, refactor
, style
, docs
, chore
, test
.
Refer from this gist:
feat: (new feature for the user, not a new feature for build script)
fix: (bug fix for the user, not a fix to a build script)
docs: (changes to the documentation)
style: (formatting, missing semi colons, etc; no production code change)
refactor: (refactoring production code, eg. renaming a variable)
test: (adding missing tests, refactoring tests; no production code change)
chore: (updating grunt tasks etc; no production code change)
Your commit will be rejected if you do not follow these rules.
The current launcher require to run 2 commands to build
First, you need to build the frontend code:
pnpm build:renderer
Unless the code under xmcl-keystone-ui
changed, you don't need to build this again.
Then, you can build Electron bundling with frontend you just build:
pnpm build:all
If you want a debug build, you can use pnpm build:dir
which only build the directory result, and won't pack them up to different release format.