Author Topic: Making a portable launcher for your game in less than 30 minutes  (Read 504 times)

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
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: ShowHide

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)




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: Adventure Game Studio
  1.     <iframe width="100%" height="400px" src="https://www.google.com"></iframe>
  2.  
  • 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: Adventure Game Studio
  1.     <button id="launchgame">Launch game</button>

In the render.js file :
Code: Adventure Game Studio
  1. const btn = document.getElementById("launchgame");
  2. btn.onclick = () => {
  3.    alert("A click has occurred!");
  4. }
  5.  
  • 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: Adventure Game Studio
  1. const spawn = require('child_process').spawn;

- Now modify the onclick function like this :
Code: Adventure Game Studio
  1. const btn = document.getElementById("launchgame");
  2. btn.onclick = () => {
  3.     const path = "C:\\PATH_TO_YOUR_GAME\\Compiled\\Windows"
  4.     const cmd = path + "\\mygame.exe";
  5.     const args = { }
  6.  
  7.     //Runs the external program (the game)
  8.     const p = spawn(cmd, args)
  9.  
  10.     //Optional : display "stdout" into our app's console
  11.     p.stdout.on('data', (data) => { console.log('stdout: ' + data) })
  12.  
  13.     //Optional : display "stderr" into our app's console
  14.     p.stderr.on('data', (data) => { console.log('stderr: ' + data)})
  15.  
  16.     //Optional : display the game's exit code into our app's console
  17.     p.on('close', (code) => { console.log('child process exited with code ' + code)})
  18. }
  19.  
    • 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.
« Last Edit: 26 May 2020, 20:09 by Monsieur OUXX »
 

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
  1. game.exe --tell-config
  2.  
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.
« Last Edit: 20 May 2020, 18:13 by Crimson Wizard »

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

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.
« Last Edit: 20 May 2020, 18:13 by 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: ShowHide

Code: Text
  1. [config-path]
  2. default = c:/Users/<redacted>/NIGHTW~2/acsetup.cfg
  3. global = C:\Users\<redacted>\SAVEDG~1\.ags/acsetup.cfg
  4. user = C:\Users\<redacted>\SAVEDG~1/Night Witch/acsetup.cfg
  5. [config@graphics]
  6. driver = D3D9
  7. filter = StdScale
  8. game_scale_fs = proportional
  9. game_scale_win = max_round
  10. refresh = 0
  11. render_at_screenres = 0
  12. screen_def = scaling
  13. screen_height = 1050
  14. screen_width = 1680
  15. vsync = 1
  16. windowed = 1
  17. [config@language]
  18. translation =
  19. [config@misc]
  20. antialias = 0
  21. cachemax = 131072
  22. defaultres = 8
  23. game_height = 720
  24. game_width = 1280
  25. gamecolordepth = 32
  26. letterbox = 0
  27. notruecolor = 0
  28. shared_data_dir =
  29. titletext = Empty Game Setup
  30. user_data_dir =
  31. [config@mouse]
  32. auto_lock = 0
  33. control_enabled = 1
  34. speed = 1.000000
  35. [config@sound]
  36. digiid = AUTO
  37. midiid = NONE
  38. threaded = 1
  39. usespeech = 0
  40. [data]
  41. basepack = c:/Users/<redacted>/DOWNLO~1/NIGHTW~2/NIGHTW~1.EXE
  42. compiledwith = 3.5.0.20
  43. gamename = Night Witch
  44. version = 50
  45. [engine]
  46. name = Adventure Game Studio run-time engine
  47. version = 3.5.0.20
  48. [graphicdriver]
  49. 0 = D3D9
  50. 1 = OGL
  51. 2 = Software
  52.  

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
Great addition guys
 

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
« Last Edit: 22 May 2020, 01:27 by eri0o »

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
@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.
« Last Edit: 26 May 2020, 14:36 by Monsieur OUXX »
 

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
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.