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.