Developing and Publishing a Web Game on Steam with ElectronJS + Steamworks.js

Step 1: Set Up ElectronJS Project

Start by creating a new directory for your project and navigate to it using the command line.

$ mkdir my-game && cd my-game

Initialize a new Node.js project and install ElectronJS.

$ npm init -y

$ npm install -g npm

$ npm install electron --save-dev

Example of the package.js from my game


{
  "name": "incrementalmonstersrpg",
  "version": "0.0.3",
  "description": "---",
  "main": "main.js",
  "scripts": {
    "start": "electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make",
    "publish": "electron-forge publish",
    "build": "electron-packager . incrementalmonstersrpg --platform=win32 --no-tmpdir --out ../build --overwrite --arch=x64 --prune=true --asar.unpackDir=\"node_modules/steamworks.js\""
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@angular/cli": "^16.0.3",
    "@electron/asar": "^3.2.4",
    "electron-squirrel-startup": "^1.0.0",
    "express": "^4.18.2",
    "firebase": "^9.22.2",
    "nodemailer": "^6.9.2",
    "npm-run-all": "^4.1.5",
    "rimraf": "^5.0.1",
    "steamworks.js": "^0.2.0",
    "typescript": "^5.0.4"
  },
  "devDependencies": {
    "@electron-forge/cli": "^6.1.1",
    "@electron-forge/maker-deb": "^6.1.1",
    "@electron-forge/maker-rpm": "^6.1.1",
    "@electron-forge/maker-squirrel": "^6.1.1",
    "@electron-forge/maker-zip": "^6.1.1",
    "electron": "^25.0.1"
  }
}

 

Step 2: Create the Game

Build your web game using HTML, CSS, and JavaScript. Ensure that it runs locally within a browser.

You can use the followin game to test: https://github.com/ikraamg/ForestRPG

Step 3: Integrate Steamworks.js

Add Steamworks.js to your project.  ( https://github.com/ceifa/steamworks.js )

$ npm install steamworks.js

[ Follow the steps from  https://github.com/ceifa/steamworks.js  ] 

Step 4: Configure ElectronJS

Create a main.js file in your project directory to configure ElectronJS.

$ touch main.js

Inside main.js, add the following code:

const { app, BrowserWindow, Menu } = require('electron');
const steamworks = require('steamworks.js')
const path = require('path');

Menu.setApplicationMenu(false)

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 1024,
    height: 768,
    webPreferences: {
      contextIsolation: false,
      nodeIntegration: true
    }
  });


  // You can pass an appId, or don't pass anything and use a steam_appid.txt file
  const client = steamworks.init()

  // Print Steam username
  console.log(client.localplayer.getName())

  // Tries to activate an achievement
  if (client.achievement.activate('ACHIEVEMENT')) {
      // ...
  }

  // Carrega o arquivo index.html
  mainWindow.loadFile(path.join(__dirname, 'index.html'));


  // Abre o DevTools (opcional)
  // mainWindow.webContents.openDevTools();

  // Evento disparado quando a janela é fechada
  mainWindow.on('closed', function () {
    // Remove a referência da janela
    mainWindow = null;
  });
}

// Evento disparado quando o Electron terminou a inicialização e está pronto para criar janelas de navegador
app.on('ready', createWindow);

// Encerra o aplicativo quando todas as janelas estão fechadas
app.on('window-all-closed', function () {
  // No macOS, é comum que o aplicativo e sua barra de menu continuem ativos até que o usuário saia explicitamente com Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

// Evento disparado quando o aplicativo é ativado, geralmente pelo ícone do dock no macOS
app.on('activate', function () {
  // Cria uma nova janela se a variável mainWindow estiver nula
  if (mainWindow === null) {
    createWindow();
  }
});

Step 5: Package and Test Your Game

Use Electron Builder to package your game for distribution.

$ npm install electron-builder --save-dev

$ npm install electron-packager --save-dev

 

You can package you game from command line in the project folder with the following command:

$ electron-packager . --electron-version --no-tmpdir --asar --force --platform win32 --out ../build/[YOU GAME NAME] --overwrite

for more options see the electron Doc in  https://www.electronforge.io/cli#package

From NPM 

Add the following configuration to your package.json:

"scripts": {
        "start": "electron .",
        "package": "electron-builder"
    },
    "build": {
        "appId": "com.yourcompany.yourgame",
        "win": {
            "target": "NSIS"
        }
    }

To test your game, run the following command:

$ npm start


Step 6: Publish on Steam

Create a new application on Steamworks and upload your packaged game build.

Add the file steam_appid.txt to your root project folder

Follow the Steamworks documentation for detailed instructions on submitting your game to Steam.

Conclusion

Congratulations! You've learned how to develop and publish a web game on Steam using ElectronJS and Steamworks.js.


Advantages and Disadvantages of this approach

Advantages
  1. Platform Independence: ElectronJS allows cross-platform app development.
  2. Web Technologies: Leverages HTML, CSS, and JavaScript.
  3. Lightweight and Fast: ElectronJS apps have faster load times and better performance.
  4. Familiar Development Workflow: Utilizes web development knowledge and tools.
  5. Steam Integration: Seamless integration with Steam features and services.
  6. Quick Prototyping: Enables rapid prototyping using web development frameworks and libraries.
  7. Flexible UI Design: Offers extensive customization using HTML and CSS.
Disadvantages
  1. Performance Limitations: May not perform as well as native game engines for resource-intensive games.
  2. Steeper Learning Curve for Advanced Features: Advanced functionality may require more expertise in web technologies.
  3. Limited Visual Effects and Rendering Capabilities: Not as robust as Unity3D in terms of graphics capabilities.