This is a documentation for Board Game Arena: play board games online !

Using Typescript and Scss: Difference between revisions

From Board Game Arena
Jump to navigation Jump to search
(add Studio category)
(Moved other vscode plugins to respective wiki; added proper type definition file so we can remove all globals and such there)
Line 7: Line 7:
Install node/npm.  Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don't have to launch build manually after each modification.
Install node/npm.  Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don't have to launch build manually after each modification.


=== Auto build JS and CSS files ===
=== Configure package.json and tsconfig.json ===
In VS Code, add extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave and then add to VSCode <code>config.json</code> extension part :
 
        "commands": [
Create a file named <code>package.json</code> on the root folder, not on the src folder.
            {
 
                "match": ".*\\.ts$",
'''package.json'''
                "isAsync": true,
 
                "cmd": "npm run build:ts"
{
            },
  "name": "yourgamename",
            {
  "version": "1.0.0",
                "match": ".*\\.scss$",
  "description": "",
                "isAsync": true,
  "main": "YourGameName.js",
                "cmd": "npm run build:scss"
  "scripts": {
            }
    "build:ts": "tsc",
        ]
    "build:scss": "sass --no-source-map src/yourgamename.scss yourgamename.css",
    }
    "watch:ts": "tsc --watch",
    "watch:scss": "sass --watch src/yourgamename.scss yourgamename.css",
    "watch": "npm run watch:ts && npm run watch:sass"
  },
  "author": "yourname",
  "license": "MIT",
  "devDependencies": {
    "sass": "^1.32.6",
    "typescript": "^4.1.3"
  }
}
 
Note: if you not using scss - remove corresponding scripts and deps.
 
When package.json is created, run <code>npm i</code> on the root folder to install builders (will generate a node_modules folder).
 
 
 
For Typescript compilation we also need to set up a <code>tsconfig.json</code> on the root folder.
 
'''tsconfig.json'''
 
{
    "rootDir": ".",
    "compilerOptions": {
      "target": "es5",
      "module": "none",
      "lib": ["dom", "esnext"],
      "sourceMap": false,
      "typeRoots": ["src/types", "./types", "./node_modules/@types"]
      "outFile": "YourGameName.js",
    },
    "files": [
        "src/GameBody.ts",
        "src/define.ts"
    ]
}


<code>build:ts</code> and <code>build:scss</code> are script tasks we'll configure later.
Note: it only works now with es5


> Alternatively you can run on terminal: `npm run watch`
If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can't with this configuration.


=== Auto-upload built files ===
Also add one auto-FTP upload extension (for example https://marketplace.visualstudio.com/items?itemName=lukasz-wronski.ftp-sync) and configure it. The extension will detected modified files in the workspace, including built ones, and upload them to remote server.
In ignored files section, you can put :
    "ignore": [
        "\\.vscode",
        "\\.git",
        "\\.DS_Store",
        "package.json",
        "package-lock.json",
        "yarn.lock",
        "tsconfig.json",
        "src",
        "node_modules",
        "README.md"
    ],


=== Hint ===
Make sure <code>.vscode</code> and <code>node_modules</code> are in <code>.gitignore</code> if you commit your project somewhere.


== Create skeleton ==
== Create skeleton ==
When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a <code>src</code> folder to separate them from built files, but that's not mandatory.
When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a <code>src</code> folder to separate them from built files, but that's not mandatory.
Note to myself: check if 'src' dir will be svn version control, if not cannot really use it (even if duplicated in git).


=== Typescript file skeleton ===
=== Typescript file skeleton ===
Typescript example here have been stripped down of all comments for clarity. You can view full file with generated comments [https://github.com/thoun/bga-ts-example/blob/main/src/yourgamename.ts here].
Typescript example here have been stripped down of all comments for clarity.  
Your TS code can be splitted in multiple files, you can have a look [https://github.com/thoun/bga-ts-example here] for inspiration.
Your TS code can be splitted in multiple files, you can have a look [https://github.com/thoun/bga-ts-example here] for inspiration.
To make this page concise, I removed comments and code samples. If it's your first game, I strongly recommend you to report them on the TS file before activating auto-build !
To make this page concise, I removed comments and code samples. If it's your first game, well - don't do it if your first game - you won't be able to apply other code samples from docs, they all using dojo style and have to completely rewritten.


'''<your game name>.ts'''
 
declare const define;
'''src/GameBody.ts'''
declare const ebg;
 
declare const $;
<pre>
//declare const dojo/*: Dojo*/;
// @ts-ignore
declare const _;
GameGui = (function () { // this hack required so we fake extend GameGui
declare const g_gamethemeurl;
  function GameGui() {}
  return GameGui;
class <Your game name> /*implements Game*/ {
})();
 
    private gamedatas: any;
// Note: it does not really extend it in es6 way, you cannot call super you have to use dojo way
    private player_id: string;
class GameBody extends GameGui {  
    private players: { [playerId: number]: any /*Player*/ };
    private playerNumber: number;
     constructor() {}
     constructor() {}
      
      
Line 78: Line 95:
     public onUpdateActionButtons(stateName: string, args: any) {}  
     public onUpdateActionButtons(stateName: string, args: any) {}  
     public setupNotifications() {}
     public setupNotifications() {}
  }
}
</pre>
 
To plug the class with BGA framework, we'll also create another file:
 
'''src/define.ts'''


To plug the class with BGA framework, we'll also create another file :
'''define.ts'''
  define([
  define([
     "dojo","dojo/_base/declare",
     "dojo","dojo/_base/declare",
Line 89: Line 109:
  ],
  ],
  function (dojo, declare) {
  function (dojo, declare) {
     return declare("bgagame.<your game name>", ebg.core.gamegui, new <Your game name>());             
     return declare("bgagame.yourgamename", ebg.core.gamegui, new GameBody());             
  });
  });
Copy <code>bgagame.<your game name></code> from original JS to avoid name mistakes. <code>new <Your game name>()</code> must match your class name defined on previous file.
Copy <code>bgagame.yourgamename</code> from original JS to avoid name mistakes with letter case.
 
If you try to compile it you will be missing definitions of bunch of methods and variables for that we will add special ts type definition file .d.ts, this is not a complete version but you can get more complete from git projects below
 
'''src/types/bga-framework.d.ts'''
<pre>
 
declare var gameui: GameGui;
declare var g_replayFrom: number | undefined;
declare var g_gamethemeurl: string;
declare var g_themeurl: string;
declare var g_archive_mode: string;
declare function _(str: string): string;
 
declare const define;
declare const ebg;
 
declare class GameGui {
    page_is_unloading: any;
    game_name: string;
    instantaneousMode: any;
    player_id: string;
    interface_min_width: number;
    gamedatas: any;
   
 
    isCurrentPlayerActive(): boolean;
    addActionButton(id: string, label: string, callback: (event?: any) => void);
    checkAction(action: any);
    ajaxcall(url: string, args: object, bind: GameGui, resultHandler: (result: any) => void, allHandler: any);
    onEnteringState(state: string, args: any);
 
    onScriptError(msg: string, url?: string, linenumber?:number);
    inherited(args: any);
}
 
 
</pre>


=== SCSS file ===
=== SCSS file ===
Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it '''<your game name>.scss'''
Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it '''src/yourgamename.scss'''.
Original content same as original .css, i.e
 
  @import url(../../../css/csslayer.css);
 


Your SCSS code can be splitted in multiple files, for example :
Your SCSS code can be splitted in multiple files, for example :


'''<your game name>.scss'''
'''yourgamename.scss'''
   @import 'gametable';
   @import 'gametable';
   
   
Line 106: Line 167:
   /* _gametable related classes */
   /* _gametable related classes */


=== Configure package.json and tsconfig.json ===


Create a file named <code>package.json</code> on the root folder, not on the src folder.
=== Auto build JS and CSS files ===
'''package.json'''
 
{
To build and watch (i.e. re-build continiously changed files) run in terminal:
  "name": "<your game name>",
  npm run watch
  "version": "1.0.0",
 
  "description": "",
Alternately you can make vscode to do it for you by installing Run on Save extension, see details in [[Setting_up_BGA_Development_environment_using_VSCode]]
  "main": "<your game name>.js",
  "scripts": {
    "build:ts": "tsc",
    "build:scss": "sass --no-source-map src/<your game name>.scss <your game name>.css",
    "watch:ts": "tsc --watch",
    "watch:scss": "sass --watch src/<your game name>.scss <your game name>.css",
    "watch": "npm run watch:ts && npm run watch:sass"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "sass": "^1.32.6",
    "typescript": "^4.1.3"
  }
}


When package.json is created, run <code>npm i</code> on the root folder to install builders (will generate a node_modules folder).
=== Auto-upload generated files ===
You can setup stanard file sync or use vscode SFTP extension, see details in [[Setting_up_BGA_Development_environment_using_VSCode]]


For Typescript compilation we also need to set up a <code>tsconfig.json</code> on the root folder.
'''tsconfig.json'''
{
    "rootDir": ".",
    "compilerOptions": {
      "target": "es5",
      "module": "none",
      "lib": ["dom", "esnext"], 
      "sourceMap": false,
      "outFile": "<your game name>.js",
    },
    "files": [
        "src/<your game name>.ts",
        "src/define.ts"
    ]
}


If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can't with this configuration. If you manage to make them work, please contact me and we'll update this documentation.
=== Hint ===
Make sure <code>.vscode</code> and <code>node_modules</code> are in <code>.gitignore</code> if you commit your project somewhere.


=== Code completion ===
=== Code completion ===
To add code completion on framework, doko, stock, ... you'll need definition files. Feel free to copy them from [https://github.com/thoun/bga-ts-example this repo] and reference them at the top of files array, even before your subpart files.
To add code completion on framework, dojo, stock, ... you'll need more type definition files. Feel free to copy them from [https://github.com/thoun/bga-ts-example this repo] and reference them at the top of files array, even before your subpart files.
 
 
=== Referenced Projects ===
 
* https://github.com/thoun/bga-ts-example
* https://github.com/elaskavaia/bga-dojoless
 
 
 


[[Category:Studio]]
[[Category:Studio]]

Revision as of 01:40, 29 September 2022

This page will help you set up your project to use Typescript client file and Scss style files, and automatically build Javascript (in ES5) files and CSS files so your project stay compatible to BGA framework requirements. You can use only TS or only SCSS part if you want, they are not linked.

How to install the auto-build stack

Install dev stack

Install node/npm. Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don't have to launch build manually after each modification.

Configure package.json and tsconfig.json

Create a file named package.json on the root folder, not on the src folder.

package.json

{
  "name": "yourgamename",
  "version": "1.0.0",
  "description": "",
  "main": "YourGameName.js",
  "scripts": {
    "build:ts": "tsc",
    "build:scss": "sass --no-source-map src/yourgamename.scss yourgamename.css",
    "watch:ts": "tsc --watch",
    "watch:scss": "sass --watch src/yourgamename.scss yourgamename.css",
    "watch": "npm run watch:ts && npm run watch:sass"
  },
  "author": "yourname",
  "license": "MIT",
  "devDependencies": {
    "sass": "^1.32.6",
    "typescript": "^4.1.3"
  }
}

Note: if you not using scss - remove corresponding scripts and deps.

When package.json is created, run npm i on the root folder to install builders (will generate a node_modules folder).


For Typescript compilation we also need to set up a tsconfig.json on the root folder.

tsconfig.json

{
    "rootDir": ".", 
    "compilerOptions": {
      "target": "es5",
      "module": "none",
      "lib": ["dom", "esnext"],  
      "sourceMap": false,
      "typeRoots": ["src/types", "./types", "./node_modules/@types"]
      "outFile": "YourGameName.js",
    },
    "files": [
        "src/GameBody.ts",
        "src/define.ts"
    ]
}

Note: it only works now with es5

If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can't with this configuration.


Create skeleton

When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a src folder to separate them from built files, but that's not mandatory. Note to myself: check if 'src' dir will be svn version control, if not cannot really use it (even if duplicated in git).

Typescript file skeleton

Typescript example here have been stripped down of all comments for clarity. Your TS code can be splitted in multiple files, you can have a look here for inspiration. To make this page concise, I removed comments and code samples. If it's your first game, well - don't do it if your first game - you won't be able to apply other code samples from docs, they all using dojo style and have to completely rewritten.


src/GameBody.ts

// @ts-ignore
GameGui = (function () { // this hack required so we fake extend GameGui
  function GameGui() {}
  return GameGui;
})();

// Note: it does not really extend it in es6 way, you cannot call super you have to use dojo way 
class GameBody extends GameGui { 
     constructor() {}
     
     public setup(gamedatas: any) {
         this.setupNotifications();
     } 
     public onEnteringState(stateName: string, args: any) {}
     public onLeavingState(stateName: string) {}
     public onUpdateActionButtons(stateName: string, args: any) {} 
     public setupNotifications() {}
}

To plug the class with BGA framework, we'll also create another file:

src/define.ts

define([
    "dojo","dojo/_base/declare",
    "ebg/core/gamegui",
    "ebg/counter",
    "ebg/stock"
],
function (dojo, declare) {
    return declare("bgagame.yourgamename", ebg.core.gamegui, new GameBody());             
});

Copy bgagame.yourgamename from original JS to avoid name mistakes with letter case.

If you try to compile it you will be missing definitions of bunch of methods and variables for that we will add special ts type definition file .d.ts, this is not a complete version but you can get more complete from git projects below

src/types/bga-framework.d.ts


declare var gameui: GameGui;
declare var g_replayFrom: number | undefined;
declare var g_gamethemeurl: string;
declare var g_themeurl: string;
declare var g_archive_mode: string;
declare function _(str: string): string;

declare const define;
declare const ebg;

declare class GameGui {
    page_is_unloading: any;
    game_name: string;
    instantaneousMode: any;
    player_id: string;
    interface_min_width: number;
    gamedatas: any;
    
  
    isCurrentPlayerActive(): boolean;
    addActionButton(id: string, label: string, callback: (event?: any) => void);
    checkAction(action: any);
    ajaxcall(url: string, args: object, bind: GameGui, resultHandler: (result: any) => void, allHandler: any);
    onEnteringState(state: string, args: any);

    onScriptError(msg: string, url?: string, linenumber?:number);
    inherited(args: any);
}


SCSS file

Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it src/yourgamename.scss. Original content same as original .css, i.e

 @import url(../../../css/csslayer.css);


Your SCSS code can be splitted in multiple files, for example :

yourgamename.scss

 @import 'gametable';

 /* some classes */

_gametable.scss

 /* _gametable related classes */


Auto build JS and CSS files

To build and watch (i.e. re-build continiously changed files) run in terminal:

 npm run watch

Alternately you can make vscode to do it for you by installing Run on Save extension, see details in Setting_up_BGA_Development_environment_using_VSCode

Auto-upload generated files

You can setup stanard file sync or use vscode SFTP extension, see details in Setting_up_BGA_Development_environment_using_VSCode


Hint

Make sure .vscode and node_modules are in .gitignore if you commit your project somewhere.

Code completion

To add code completion on framework, dojo, stock, ... you'll need more type definition files. Feel free to copy them from this repo and reference them at the top of files array, even before your subpart files.


Referenced Projects