Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Monsieur OUXX on Wed 20/05/2020 17:02:59

Title: Making a portable launcher for your game in less than 30 minutes
Post by: Monsieur OUXX on Wed 20/05/2020 17:02:59
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" (https://www.youtube.com/watch?v=XpRAaw-vZNU)
          - 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 (https://stackoverflow.com/questions/50687740/how-to-include-qwebengineview-without-getting-an-error)
          - 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?

Why Electron?



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)



4. Start customizing

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

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



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

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

In the render.js file :
Code (ags) Select

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

- At the very top of render.js, add this :
Code (ags) Select

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


- Now modify the onclick function like this :
Code (ags) Select

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)})
}

7. Distribute your launcher (1 min)

Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: Crimson Wizard on Wed 20/05/2020 17:13:51
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) Select

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.
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: 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.
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: Crimson Wizard on Wed 20/05/2020 18:08:30
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.
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: Crimson Wizard on Wed 20/05/2020 18:22:52
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) Select

[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]
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: Monsieur OUXX on Thu 21/05/2020 10:52:11
Great addition guys
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: eri0o on Thu 21/05/2020 23:36:20
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
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: Monsieur OUXX on Tue 26/05/2020 12:00:55
@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.
Title: Re: Making a portable launcher for your game in less than 30 minutes
Post by: Monsieur OUXX on Tue 26/05/2020 20:05:18
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.