Appearance
Configuration File
GemShell saves all settings to gemshell.config.json in your game folder.
File Location
my-game/
├── index.html
├── game.js
└── gemshell.config.json <-- Configuration fileFull Schema
Keys are snake_case. This is exactly what GemShell writes for a fresh project:
json
{
"app": {
"name": "My Game",
"version": "1.0.0",
"entrypoint": "index.html",
"icon": null,
"splash": false,
"debug": false
},
"window": {
"title": "",
"width": 1280,
"height": 720,
"min_width": 800,
"min_height": 600,
"resizable": true,
"start_fullscreen": false,
"always_on_top": false,
"frameless": false,
"lock_aspect_ratio": false,
"node_integration": true
},
"permissions": {
"media": false
},
"steamworks": {
"enabled": false,
"app_id": 480
},
"exclude": [],
"build": {
"platforms": { "windows": true, "mac": true, "linux": true },
"architectures": [],
"optimization": {
"asset_compression": false,
"code_minification": false,
"remove_unused": false,
"remove_console_logs": false,
"bundle_cdn": false
},
"output_path": "",
"author": "",
"app_name": "my-game"
},
"plugins": {},
"ios": false,
"android": false,
"mobile": {
"bundle_id": "",
"min_ios_version": "16.0",
"min_android_sdk": 24
}
}Deploy targets (steam_deploy, itch_deploy, github_deploy) are written once you configure them in the Deploy tab.
Properties
app
| Property | Type | Default | Description |
|---|---|---|---|
app.name | string | "" | Display name — window title, About dialog |
app.version | string | "1.0.0" | Version string |
app.entrypoint | string | "index.html" | HTML file to load |
app.icon | string | null | null | Path to the icon image |
app.splash | boolean | false | Show the splash screen on launch |
app.debug | boolean | false | Open DevTools, enable the DevTools shortcut |
window
| Property | Type | Default | Description |
|---|---|---|---|
window.width / height | number | 1280 / 720 | Initial size |
window.min_width / min_height | number | 800 / 600 | Minimum size |
window.resizable | boolean | true | Allow resizing |
window.start_fullscreen | boolean | false | Launch fullscreen |
window.always_on_top | boolean | false | Keep above other windows |
window.frameless | boolean | false | Hide the OS window frame |
window.lock_aspect_ratio | boolean | false | Keep width/height ratio when resizing |
window.node_integration | boolean | true | Node.js in the renderer — turn off for jQuery and other global scripts |
build
| Property | Type | Default | Description |
|---|---|---|---|
build.app_name | string | — | Technical name; used for the executable and save folder |
build.author | string | "" | Shown in the About dialog and Windows file properties |
build.output_path | string | "" | Where builds are written (empty = default location) |
build.platforms | object | all true | Coarse platform toggles |
build.architectures | string[] | [] | Exact targets to build; takes precedence over platforms |
build.optimization.asset_compression | boolean | false | Recompress images and audio |
build.optimization.code_minification | boolean | false | Minify JS/CSS/HTML |
build.optimization.remove_unused | boolean | false | Drop assets nothing references |
build.optimization.remove_console_logs | boolean | false | Strip console.log calls |
build.optimization.bundle_cdn | boolean | false | Download CDN scripts into the bundle |
Available Architectures
| Value | Description |
|---|---|
mac-arm64 | macOS Apple Silicon |
mac-x64 | macOS Intel |
windows-x64 | Windows 64-bit |
windows-arm64 | Windows ARM |
windows-ia32 | Windows 32-bit (legacy) |
linux-x64 | Linux 64-bit |
linux-arm64 | Linux ARM |
ios / android | Mobile (Pro) |
steamworks
| Property | Type | Default | Description |
|---|---|---|---|
steamworks.enabled | boolean | false | Enable the Steam API |
steamworks.app_id | number | 480 | Steam App ID — a number, not a string |
exclude
| Property | Type | Default | Description |
|---|---|---|---|
exclude | string[] | [] | Glob patterns for files to keep out of the build |
json
{ "exclude": ["*.psd", "*.ai", "src/**", "*.map"] }plugins
| Property | Type | Default | Description |
|---|---|---|---|
plugins.[id].enabled | boolean | false | Enable the plugin for this game |
plugins.[id].values | object | {} | Setting overrides for that plugin |
mobile
| Property | Type | Default | Description |
|---|---|---|---|
mobile.bundle_id | string | "" | Reverse-DNS bundle identifier |
mobile.min_ios_version | string | "16.0" | Minimum iOS version |
mobile.min_android_sdk | number | 24 | Minimum Android SDK level |
Permissions
Web capabilities are denied by default. Opt in per capability:
json
{
"permissions": {
"media": true
}
}| Key | Default | What it allows |
|---|---|---|
media | false | navigator.mediaDevices.getUserMedia() — microphone and camera |
Also available as Allow Microphone & Camera in Game Settings → Window Options.
Scope
media is granted only to your own game content. If your game loads a remote page (an iframe, an embedded widget), that page still cannot reach the microphone. The operating system asks the player separately — on macOS you additionally need NSMicrophoneUsageDescription, which GemShell ships in the bundle.
Without this, getUserMedia fails
Before this option existed, getUserMedia({ audio: true }) rejected with NotAllowedError in packaged builds even after the OS prompt was accepted, because the runtime denied Electron's media permission outright.
Example Configurations
Minimal
json
{
"app": { "name": "My Game", "version": "1.0.0" },
"build": { "app_name": "my-game" }
}Steam Release
json
{
"app": { "name": "My Steam Game", "version": "1.0.0" },
"window": {
"width": 1920,
"height": 1080,
"start_fullscreen": true
},
"steamworks": {
"enabled": true,
"app_id": 123456
},
"build": {
"app_name": "my-steam-game",
"architectures": ["mac-arm64", "mac-x64", "windows-x64", "linux-x64"],
"optimization": {
"code_minification": true,
"asset_compression": true,
"remove_console_logs": true
}
}
}itch.io / Direct Distribution
json
{
"app": { "name": "My Game", "version": "1.0.0" },
"build": {
"app_name": "my-game",
"architectures": ["mac-arm64", "mac-x64", "windows-x64", "linux-x64"],
"optimization": { "code_minification": true, "asset_compression": true }
}
}Development
json
{
"app": { "name": "My Game (Dev)", "version": "0.1.0", "debug": true },
"build": {
"app_name": "my-game-dev",
"architectures": ["mac-arm64"]
},
"plugins": {
"debug-tools": {
"enabled": true,
"values": { "fpsCounter": true, "memoryUsage": true }
}
}
}Game using jQuery or other global scripts
json
{
"app": { "name": "My Game", "version": "1.0.0" },
"window": { "node_integration": false },
"build": { "app_name": "my-game" }
}Auto-Save
GemShell automatically saves settings when you:
- Change any setting in the UI
- Navigate between steps
- Close the application
Changes are debounced (500ms delay) to prevent excessive writes.
Manual Editing
You can edit gemshell.config.json directly:
- Close GemShell (or it will overwrite your changes)
- Edit the JSON file
- Reopen the game in GemShell
Version Control
Add gemshell.config.json to your Git repository to share build settings with your team.
gitignore
# .gitignore - Do NOT ignore config
# gemshell.config.json <-- Keep this tracked