Discord
Login
Community
DARK THEME

Recipe: standalone desktop app of your game with electron

In this article we will set up our own electron build environment which we can use to build a native desktop app of our game.

We will also provide a config.json file, that the app will read on start up so we can adjust the resolution, window mode and other stuff after the app has been built.

0. What is electron

Electron is a framework developed by GitHub that allows you to build cross-platform desktop apps with web technologies such as HTML, CSS, and JavaScript.

The idea behind Electron is to allow developers to create desktop applications using the web technologies they already know, rather than having to learn different programming languages and technologies for different platforms. Electron applications can be packaged and distributed for Windows, macOS, and Linux.

Electron does this by providing a runtime that wraps your web application code, along with a version of the Chromium web browser, and Node.js. This combination allows you to use Node.js APIs in your application, which provides much more control and flexibility than is usually available in a web browser environment.

Electron has been used to create many popular applications such as Visual Studio Code, Slack, Atom, and Discord.

1. Install Electron

To install Electron, you first need to initialize your project using npm. Go to your project directory using command prompt and then run the following commands:

npm init

Fill out the prompts to initialize your project, e.g.:

package name: (electron) my_game
version: (1.0.0)
description: An Awesome Game
entry point: (index.js) main.js       <---- make sure you name this main.js as we will name our main script like that
test command:
git repository:
keywords:
author: Game Dev
license: (ISC) MIT
About to write to package.json:

{
  "name": "my_game",
  "version": "1.0.0",
  "description": "An Awesome Game",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Game Dev",
  "license": "MIT"
}


Is this OK? (yes)

After you're done, install Electron:

npm install --save-dev electron

2. Creating the Main Script

Next, create a new file in the root directory of your project and name it "main.js". This will be the entry point into your app.

Here is a basic main.js file:

const { app, BrowserWindow } = require('electron')

function createWindow () {
  let win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
    }
  })

  win.loadFile('game/index.html')
}

app.whenReady().then(createWindow)

This script creates a new browser window with node integration enabled and then loads your index.html file.

3. Updating your package.json

Your package.json should look something like this (based on the input you provided for the init prompt):

{
  "name": "my_game",
  "version": "1.0.0",
  "description": "An Awesome Game",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "Game Dev",
  "license": "MIT",
}

replace the following:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
},

with this:

"scripts": {
    "start": "electron ."
},

4. Running Your Application

At this point, you can run your application by using the command:

npm start

At this point, you wont see much, just an empty window if everything went well.

5. Packaging Your Application

To distribute your application, you'll need to package it into an .exe file. One of the most popular tools to do this is electron-packager. You can install it using npm:

npm install --save-dev electron-packager

After it's installed, you can add a script to your package.json to run it:

"scripts": {
  "start": "electron .",
  "build": "electron-packager . --overwrite"
}

Then, you can package your app by running:

npm run build

This will create a new folder in your project directory with the packaged application.

6. Adding a config.json

In order for your app to read configurations like window mode, resolution etc. you have to create a config file that your app can read at start up. We will call it config.json. Create a config.json in the project root folder.

Add the following content:

{
  "screenMode": "windowed_resizeable",
  "resolution_width": 1280,
  "resolution_height": 720,
  "backgroundThrottling": true
}

To read the config.json file and use the configuration in your Electron script, your main.js should look like as follows:

const { app, BrowserWindow } = require('electron')
const fs = require('fs');

function createWindow() {
    const path = require('path');
    const configPath = path.join(path.dirname(app.getPath('exe')), 'config.json');
    let rawdata = fs.readFileSync(configPath);
    let config = JSON.parse(rawdata);

    let screenMode = config.screenMode;
    let width = config.resolution_width;
    let height = config.resolution_height;
    let backgroundThrottling = config.backgroundThrottling;

    let windowOptions = {
        width: width,
        height: height,
        webPreferences: {
            nodeIntegration: true,
            backgroundThrottling: backgroundThrottling
        }
    }

    if (screenMode === "fullscreen") {
        windowOptions.fullscreen = true;
    } else if (screenMode === "borderless") {
        windowOptions.frame = false;
    } else if (screenMode === "windowed_resizeable") {
        windowOptions.resizable = true;
    } else if (screenMode === "windowed_static") {
        windowOptions.resizable = false;
    }

    let win = new BrowserWindow(windowOptions);

    win.setMenu(null);
    win.loadFile('game/index.html')

    win.webContents.on('devtools-opened', () => {
        win.webContents.closeDevTools();
    });
}

app.whenReady().then(createWindow)

Note: do not run the app yet, it won't work until the next step

7. Adding Your Game to the Electron App

Now all the prerequisites are fullfilled. Now you can add your actual game:

  1. Export your game from microStudio as Html5 game

  2. Create a folder called game in the root folder of your electron project and copy your exported game files into it. So that the index.html is located in game/index.html

  3. run the build command: npm run build. This will create a new folder with the built executable

  4. Copy your config.json into the newly created folder

  5. done :) you now have a build system that you can use to create a native desktop executable of your game

8. Summary

Your main.js should now look like as follows:

const { app, BrowserWindow } = require('electron')
const fs = require('fs');

function createWindow() {
    const path = require('path');
    const configPath = path.join(path.dirname(app.getPath('exe')), 'config.json');
    let rawdata = fs.readFileSync(configPath);
    let config = JSON.parse(rawdata);

    let screenMode = config.screenMode;
    let width = config.resolution_width;
    let height = config.resolution_height;
    let backgroundThrottling = config.backgroundThrottling;

    let windowOptions = {
        width: width,
        height: height,
        webPreferences: {
            nodeIntegration: true,
            backgroundThrottling: backgroundThrottling
        }
    }

    if (screenMode === "fullscreen") {
        windowOptions.fullscreen = true;
    } else if (screenMode === "borderless") {
        windowOptions.frame = false;
    } else if (screenMode === "windowed_resizeable") {
        windowOptions.resizable = true;
    } else if (screenMode === "windowed_static") {
        windowOptions.resizable = false;
    }

    let win = new BrowserWindow(windowOptions);

    win.setMenu(null);
    win.loadFile('game/index.html')

    win.webContents.on('devtools-opened', () => {
        win.webContents.closeDevTools();
    });
}

app.whenReady().then(createWindow)

And your package.json should look something like this:

{
  "name": "my_game",
  "version": "1.0.0",
  "description": "An awesome game",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-packager . --overwrite"
  },
  "author": "Awesome Gamedev",
  "license": "MIT",
  "devDependencies": {
    "electron-packager": "^17.1.1",
    "electron": "^24.3.1"
  }
}

Note: electron-packager - and electron version may vary.

Your folder structure should look like this:

electron_app_root
├── game
│   ├── index.html
│   └── ... (other game files and folders)
├── my_game (folder that has been built by running `npm run build` (folder name varies depending on your project name))
│   ├── my_game.exe
│   ├── config.json
│   └── ... (other genereated files)
├── node_modules
├── config.json (this file has to be copied manually into the output folder (my_game))
├── main.js
├── package-lock.json
└── package.json
    

Thanks nice post!

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community