Making a portable launcher for your game in less than 30 minutes

Started by Monsieur OUXX, Wed 20/05/2020 17:02:59

Previous topic - Next topic

Monsieur OUXX

Making a portable launcher for your game in less than 30 minutes

EDIT: Click here to reveal a solution with Qt. Turns out it's not portable because Qt didn't maintain their QtWebEngime module on non-Windows systems.
Spoiler

Here, we're using Qt to make a launcher for our game.

Why a launcher?

  • Because basic users have no clue. Maybe you want a frontend to control who starts winsetup.exe, and how.
  • Because maybe you want to make the startup of your game more festive (a big nice picture and a gigantic, green "start game" button).
  • Because maybe you want the user to agree to general terms before they launch your game.
  • Because maybe you want to automatically display your game's latest news from an online page before running the game.

Why Qt?
  • Qt is free and open source
The condition is that you keep your launcher's code public and make it adhere to the LGPL license or GPL2 license or another one that I forgot.
  • Qt is portable
You just build your launcher as a static-bound program and you're done. Of course, that doesn't make the code to start the AGS game from the launcher immediately portable (e.g. Linux file paths are not formatted identically to Windows file paths) but once the GUI is portable you've done the hardest part.


Steps


1. Install Qt

  • What is Qt?
          Qt is altogether a C++ library to make GUIs, and the IDE that comes with it to build the projects easily.
  • How to get it?
          - You need to create an account on the Qt website
          - Then, make sure to download the open source version of it. Follow the steps in this video "How To Install Qt Creator on Windows 10 - 2019"
          - IMPORTANT : The video tells you to select MinGW as the defaut compiler. Don't do that. Instead, pick MSVC 2017 64 bitsor more recent. The reason is that MinGW doesn't offer the module for embedding a web browser into Qt. If you really need MinGW, then you can try your luck with msys2 by following these steps from stackoverflow
          - Make sure to also check "Qt Design Studio" to design your GUI more easily

Note: If you messed up the install, you can still add or remove features in Qt later by going to "Add or remove programs" and modifying Qt.

2. Create the project
  • On the welcome screen of Qt Creator, use the filter box to see only the sample projects containing the word "Webengine". They should be here if you properly selected WebEngine during install
  • Pick the project called "Webengine markdown editor example"
  • Let Qt create it and build it for the first time. If you see an error (something like : "Unknown module QWebEngineView" it means that you didn't listen earlier and tried with MinGW  :=
  • Run the program ("Build" and/or "Run" in the bottom-left corner of the window). Victory! You have in front of you an application containing a custom GUI and embedding a browser window.


3. Customize your launcher
  • Remove what you don't like : You probably don't need the "File" menu at the top or the Notepad-like editor on the left. Open the "Design" panel of Qt Creator and delete the Notepad-like editor and the menu in your GUI. Delete "menu bar" in the hierarchy on the right. Also delete the rows that contain "ActionOpen", etc. Then go to the "Edit" panel of Qt creator, open file mainwindow.cpp and delete all code related to the things you've removed (basically, any line that has red on it). Open mainwindow.h and delete the same things (onFileNew, isModified, etc.). Click on "Build" in the bottom-left corner of the screen, and always answer "Yes to all" if the editor wants you to save stuff. Look at the errors and fix accordingly until you can run your application
  • Important: If for some reason you can't click on "Design" anymore, click on file mainwindow.ui instead
  • Add what you're missing. You probably need a button to launch your game, and an image. Go again to the "Design" panel and add those. If you're smart you can probably embed the image into your project as a resource. 
  • Make the button start your AGS game. In the function that's fired when the button is clicked, use this simple call :     system("start C:\\path_to_your_game\\yourgame.exe");   Of course, you'll need to experiment a little bit with relative paths and if you're on Linux it will be / instead of \\. You need to use \\ instead of just \ because in C++, \ is a special character that you need to double if you want to use it.
(I'll detail how to fully implement the button and the image later)
(I'll detail how to distribute the launcher later)
[close]



Here, we're using Electron to make a launcher for our game.

Why a launcher?

  • Because basic users have no clue. Maybe you want a frontend to control who starts winsetup.exe, and how. Maybe you want them to launch a custom setup program.
  • Because maybe you want to make the startup of your game more festive (a big nice picture and a gigantic, green "start game" button).
  • Because maybe you want the user to agree to general terms before they launch your game.
  • Because maybe you want to automatically display your game's latest news from an online page before running the game.

Why Electron?
  • Electron and the dev tools that you need are free
  • Electron is portable (Windows, MacOS, Linux, iOS, Android)
  • Electron uses familiar technologies and languages: HTML, CSS, javascript



Steps


1. Install Visual studio code (5 min)

(this is only required for the developer, the players of your game won't need that)

Visual Studio Code is a pumped up text editor. Do not confuse it with the behemoth Visual Studio. Visual Studio Code is lightweight and is more like a modern version of Notepad++, except it comes with a gazillion plugins to easily develop in any language you like. Plus, it's modern, which means it's meant to let you use easily the modern philosophy of "packages" (npm and the like, see below)

It's free. Just google it, download it and install it : https://code.visualstudio.com/Download

2. Install Node.js with npm (5 min)

(this is only required for the developer, the players of your game won't need that)
(if you wish you can skip the explanations and just install them)

Let's just say that Node.js will be your development kit. A bit like installing .Net or the Java SDK. Except here it's for Node.js, which is a sort of pumped up Javascript virtual machine for running Websites as a desktop app.

Npm is what cool kids nowadays call a "package manager". This is the development philosophy that says that instead of downloading the source code of libraries manually, instead everything in the world is a package, with a unique name, and all you have to do is "npm install the_package" and BAM it's included in your project. No more headaches with importing and including the right dependencies. Sensible people in the Linux world have been doing that for decades, but now it's the standard and it's pretty rad.

Both Node.js and npm come bundled together : Again, super easy. https://nodejs.org/en/download/


3. Create your very first electron project (5 min)

  • Open a terminal. On Windows, that would be : Start menu --> type "powershell" (if you're fancy) or "command prompt" and click on the result. Please note that I'm not aware if the most basic versions of Windows still have terminals in 2020. Let's assume you've put on your developer hat today, so you're not trying to follow this tutorial on Windows Home Zero-features edition.
  • In the terminal, go to the folder where you want to create the project for your launcher : cd "C:\MyProjects\MyLauncher"
  • Still in the terminal, type this command : npx create-electron-app my-app     Do it exactly like in this video. If you get an error there, then uh oh! It means you somehow npm (and npx, which is supposed to come with it) didn't get installed properly in the previous steps.
  • It takes about one minute. Now you have a new folder containing the project. It's the folder that contains the file package.json. Open Visual Studio Code and make it open that folder. On the left panel you see the "src" folder and "package.json"
  • Inside Visual Studio Code, in the left panel (under "NPM SCRIPTS"), right-click on package.json and select "Run install". It's a bit like doing a "build" on an old-school project. It downloads all the packages that your project references. Your project is ready to be run!
  • Still under NPM SCRIPTS, now click on the little "Run" arrow next to "start". Your Hello World application should start. Success!



4. Start customizing

  • Your launcher is built like an HTML page with javascript. Except we'll use the Javascript code to run our AGS game and other cool things
  • Watch  this video and get familiar with the general philosophy of your app.

5. Embed your "News" page into your app (1 min)

  • In your file index.html, under <h1 >Hello world!< /h1>, add this row :
Code: ags

    <iframe width="100%" height="400px" src="https://www.google.com"></iframe>

  • Run the app. Success! You now have the Google page inside the window of your desktop app. Replace google.com with any URL you want


6. Add a button that launches your game (5 min)

  • Follow the steps of the video mentionned previously to add a button and the script that reacts to the click on the button:

In the HTML file:
Code: ags
    <button id="launchgame">Launch game</button>


In the render.js file :
Code: ags

const btn = document.getElementById("launchgame");
btn.onclick = () => {
   alert("A click has occurred!");
}

  • Start your app and click on the button. Success!

  • Make the button run an external program.
- At the very top of render.js, add this :
Code: ags

const spawn = require('child_process').spawn;


- Now modify the onclick function like this :
Code: ags

const btn = document.getElementById("launchgame");
btn.onclick = () => {
    const path = "C:\\PATH_TO_YOUR_GAME\\Compiled\\Windows" 
    const cmd = path + "\\mygame.exe";
    const args = { }

    //Runs the external program (the game)
    const p = spawn(cmd, args)

    //Optional : display "stdout" into our app's console
    p.stdout.on('data', (data) => { console.log('stdout: ' + data) })

    //Optional : display "stderr" into our app's console
    p.stderr.on('data', (data) => { console.log('stderr: ' + data)})

    //Optional : display the game's exit code into our app's console
    p.on('close', (code) => { console.log('child process exited with code ' + code)})
}


    • Run the game and click on the button. Success! Your game starts.
    Note: If you get an error about some missing files (for examle the translation files) it's because your didn't start the launcher and the game from the same folder, so you got AGS confused regarding the files' location.

7. Distribute your launcher (1 min)

  • Run the "build" script instead of the "start" script. Success! you now have the .exe file of your launcher (and all the other required files to run it) in the corresponding output folder of your project (look closely at the left panel in Visual Studio code, you'll see them.
  • Snoop around to build the Linux and MacOs equivalents to the .exe file (I'll detail it later). Success! you can now distribute your launcher onto other systems.
 

Crimson Wizard

For those interested in custom launchers / setup programs, we've added a "--tell" command line argument to the 3.5.0 engine, which may come handy

https://github.com/adventuregamestudio/ags/blob/master/OPTIONS.md#command-line

Quote
--tell - print various information concerning engine and the game, and quits. Output is done in JSON format.
--tell-config - print contents of merged game config.
--tell-configpath - print paths to available config files.
--tell-data - print information on game data and its location.
--tell-engine - print engine name and version.
--tell-graphicdriver - print list of supported graphic drivers.

Example of use:
Code: text

game.exe --tell-config

will print JSON INI format actually, OPTIONS.md was not correctly updated, - with all the active runtime options into stdout, from which you may read in your program and parse it using some json library.

morganw

It comes out in INI format (to avoid the dependency on a JSON parser), so I think the OPTIONS.md page must be wrong.

Crimson Wizard

Quote from: morganw on Wed 20/05/2020 18:02:58
It comes out in INI format (to avoid the dependency on a JSON parser), so I think the OPTIONS.md page must be wrong.

What? It was supposed to be JSON, I am forming it specifically in json... or was there a change which completely fall out of my memory?

EDIT: ok, there was... so yes, it's in INI format, where some keys are combined to allow longer "paths".

So, OPTIONS.md was written before than and not corrected.

Crimson Wizard

Another thing that I forgot to warn about, on Windows the result won't get to the console, because of how engine is built (this is a known issue).
If you want to see result by yourself, you can do "game.exe --tell > 1.txt" to reroute it into the text file.

Here's the example of such output
Spoiler

Code: text

[config-path]
default = c:/Users/<redacted>/NIGHTW~2/acsetup.cfg
global = C:\Users\<redacted>\SAVEDG~1\.ags/acsetup.cfg
user = C:\Users\<redacted>\SAVEDG~1/Night Witch/acsetup.cfg
[config@graphics]
driver = D3D9
filter = StdScale
game_scale_fs = proportional
game_scale_win = max_round
refresh = 0
render_at_screenres = 0
screen_def = scaling
screen_height = 1050
screen_width = 1680
vsync = 1
windowed = 1
[config@language]
translation = 
[config@misc]
antialias = 0
cachemax = 131072
defaultres = 8
game_height = 720
game_width = 1280
gamecolordepth = 32
letterbox = 0
notruecolor = 0
shared_data_dir = 
titletext = Empty Game Setup
user_data_dir = 
[config@mouse]
auto_lock = 0
control_enabled = 1
speed = 1.000000
[config@sound]
digiid = AUTO
midiid = NONE
threaded = 1
usespeech = 0
[data]
basepack = c:/Users/<redacted>/DOWNLO~1/NIGHTW~2/NIGHTW~1.EXE
compiledwith = 3.5.0.20
gamename = Night Witch
version = 50
[engine]
name = Adventure Game Studio run-time engine
version = 3.5.0.20
[graphicdriver]
0 = D3D9
1 = OGL
2 = Software

[close]

Monsieur OUXX

 

eri0o

You may like this: https://github.com/ericoporto/agsconfig

The code is separated in core and UI so you can do your own UI.
https://github.com/ericoporto/agsconfig/tree/master/agsconfigCore

I am unsure Qt license allows unless you pay or make the launcher opensource too

Monsieur OUXX

@eri0o : investigating a custom setup is my next step.

About the launcher: All of the above leads to not much as this stupid Qt framework actually broke its compatibility with its QtWebEngine module, hence making it hard to embed a web page in a desktop app on anything but Windows -- which was pretty much the whole point of this exercise.

I'm currently investigating doing the same with a very simple React Native or an Electron app -- still with the goal of making it work at least on Windows, MacOS and Linux, and if simple enough on iOS and Android.
 

Monsieur OUXX

Update : I have rewritten the first post to do the launcher with Electron. I tested it, it's awesome and super easy. And modern. Zero chance of breaking in the next 5 years at least.
 

SMF spam blocked by CleanTalk