Page 1 of 1

Separate data file for Javascript

Posted: 15 October 2020, 18:35
by fafa-fr
Hi,
I'd like some help about spliting javascript in different files, in order to avoid placing in my main JS file a lot of data (mainly text for tooltips, so I need to be able to use BGA's _() in this data file to mark the tooltip strings to translate). I know I could use material.inc.php and transfer it with getAllDatas(), but this data is only needed client-side, and since there's a bit of code (not much) required to construct this data (some of the strings are duplicated for different elements), I'd rather avoid placing it in material.inc.php since this file is executed each time an action is triggered. I believe it would be best to have this data client-side only, but feel free to say if you disagree. material.inc.php is still an option for me if I don't find how to do otherwise properly.

There's an example of how to use several JS files in the doc, in the BGA Studio Cookbook.

Code: Select all

define([ "dojo", "dojo/_base/declare", "ebg/core/gamegui", "ebg/counter",
   // load my own module!!!
   g_gamethemeurl + "modules/ggg_other.js" ], function(dojo,
       declare) {
But there's no indication of how ggg_other.js file should be written. Maybe it's implied by the use of the term "module", but since I'm not used to this stuff, I don't know how to do this properly while being able to use BGA's methods inside this file. I've looked at a few Studio projects' code, I've read the dojo doc about adding classes (dojo/declare) and AMD modules, and I also saw that it was possible to load non-AMD code, but I'm a bit lost and I don't know what would be the best option for my case, and how to do it properly.
If I only declare variables in this file without declaring a class / module, I have access to these variables in my main JS file, but if I try to use _() I have a JS error ("_() undefined" in the console) and the game interface won't load.

Can anyone explain me a clean way to have a separate file for data that can use BGA's methods?

Re: Separate data file for Javascript

Posted: 15 October 2020, 19:16
by Tisaac
Check the sharedcode github of Victoria, there is an example of how to split js file.

Re: Separate data file for Javascript

Posted: 15 October 2020, 22:29
by fafa-fr
Tisaac wrote: 15 October 2020, 19:16 Check the sharedcode github of Victoria, there is an example of how to split js file.
I already looked at her code, but this is just an example, that does much more than what I'm looking for (instead of the classic BGA game class inheriting from ebg.core.gamegui, she defines a sharedparent class inheriting from ebg.core.gamegui, and then the game class inherits from sharedparent, if I'm not mistaken). So I'm not sure that this is what I need, and without more explanations I'd be afraid of doing wrong things. For example, in another thread, I read that a badly created javascript module caused double construction of ebg.core.gamegui, which was not noticeable at first, but caused a problem (a minor problem in this case).

Re: Separate data file for Javascript

Posted: 15 October 2020, 22:56
by Tisaac
fafa-fr wrote: 15 October 2020, 22:29
Tisaac wrote: 15 October 2020, 19:16 Check the sharedcode github of Victoria, there is an example of how to split js file.
I already looked at her code, but this is just an example, that does much more than what I'm looking for (instead of the classic BGA game class inheriting from ebg.core.gamegui, she defines a sharedparent class inheriting from ebg.core.gamegui, and then the game class inherits from sharedparent, if I'm not mistaken). So I'm not sure that this is what I need, and without more explanations I'd be afraid of doing wrong things. For example, in another thread, I read that a badly created javascript module caused double construction of ebg.core.gamegui, which was not noticeable at first, but caused a problem (a minor problem in this case).
Well another alternative would be to define your own class that you will instanciate by passing "this" so that your module can access bga methods (that's what I'm doing when using Vuejs in Concept)

Re: Separate data file for Javascript

Posted: 15 October 2020, 23:54
by fafa-fr
Tisaac wrote: 15 October 2020, 22:56 Well another alternative would be to define your own class that you will instanciate by passing "this" so that your module can access bga methods
Yes, if I'm not mistaken, that's what I saw in marco polo two's code.

So would it be ok if I had something like this:

game_tooltips.js:

Code: Select all

define([ "dojo", "dojo/_base/declare" ], function(dojo, declare) {
  return declare(null, {   
    constructor : function(bgaMeth) 
    {
        this.ttText = {
          zoomInButton: {
            name: bgaMeth._( "" ),
            descr: bgaMeth._( "Display bigger boards and pieces." )
          },
          zoomOutButton: {
            name: bgaMeth._( "" ),
            descr: bgaMeth._( "Display smaller boards and pieces (allows to see more boards at the same time)." )
          },
          ...
        };
    },
  });
});
game.js:

Code: Select all

define([
    "dojo","dojo/_base/declare",
    "ebg/core/gamegui",
    "ebg/counter",
    g_gamethemeurl + "modules/game_tooltips.js"
],
...
...
    setup: function( gamedatas ) {
      ...
      var tooltips = new game_tooltips(this);
      for ( var nodeId in tooltips.ttText ) {
        var ttStrings = tooltips.ttText[nodeId];
        this.addTooltip( nodeId, ttStrings.name, ttStrings.descr );
      }
      ...

Re: Separate data file for Javascript

Posted: 16 October 2020, 03:35
by hersh
Both ways work. But if you prefer module not to be a subclass of gameui then passing the instance works. That's what I ended up doing in marco polo 2.

I think you want declare("game_tooltips", null, { // code } ); inside game_tooltips.js

https://dojotoolkit.org/reference-guide ... clare.html

That example of double instantiation was from marco polo 2 when I was trying to get the dojo module to work :)

Re: Separate data file for Javascript

Posted: 16 October 2020, 08:17
by Tisaac
That's being said, the function "_" is defined at the window scope, so you don't have to pass the game to your modules and therefore do a singleton/a single object (that's what I'm doing in Concept with the tooltip contents)

Re: Separate data file for Javascript

Posted: 16 October 2020, 14:12
by fafa-fr
hersh wrote: 16 October 2020, 03:35 Both ways work. But if you prefer module not to be a subclass of gameui ...
I prefer the way that will have the less risk of causing bugs, so I prefer the way that I can most easily fully understand. This means, not only that I more or less understand how it works, ideally I'd like to know all the consequences of using this or that way. (That's why I was looking for a quite simple solution, and/or well explained, and I still consider the option of placing all datas / strings at the very end of my main JS file, so that it's less annoying than if they were in setup() or in the middle of utility functions.)
And I think (I hope) I understand enough the "defining a class, then instanciating an object in the main JS file, giving a parameter to the constructor, so that it can use BGA framework's methods" way (though I'd still like some more feedback about the example code I wrote above), whereas I'm not really sure that the sharedcode project approach is appropriate for my needs, and there are some things that I don't really understand, so I wouldn't feel comfortable neither to use it completely as it is and adding my stuff above it (but I don't know exactly where), nor to take only some parts of the code.
hersh wrote: 16 October 2020, 03:35 I think you want declare("game_tooltips", null, { // code } ); inside game_tooltips.js
https://dojotoolkit.org/reference-guide ... clare.html
Well, I read that it was not advised anymore to provide a className parameter. The link you provide is for dojo 1.6, and a more recent doc says that the class name (first argument of declare()) is omitted in new development.
See the first point of the common conventions:
https://dojotoolkit.org/reference-guide ... onventions
Tisaac wrote: 16 October 2020, 08:17 That's being said, the function "_" is defined at the window scope, so you don't have to pass the game to your modules ...
I'll have a look at that, thanks. It might make me feel a bit less worried ;)

Re: Separate data file for Javascript

Posted: 16 October 2020, 16:01
by hersh
If I understand the BGA example it is extending the gamegui class. MP2 I created a separate module and pass instance (I wanted access to tooltip & animation methods).

If you want nameless class like dojo suggestion then you need include parameters. I think something like below

Code: Select all

define([
    "dojo","dojo/_base/declare",
    "ebg/core/gamegui",
    "ebg/counter",
    g_gamethemeurl + "modules/game_tooltips.js"
],
function (dojo, declare, g, c, game_tooltips)		//note the seq matches define
{
....
});
then you can use new game_tooltips();

Re: Separate data file for Javascript

Posted: 17 October 2020, 00:08
by paramesis
I have a few active projects in Studio where I'm using simple Javascript classes defined in another file that don't inherit from anything and take this in the constructor, as others have described. Here is an example from Petrichor (which is public):

game.js

Code: Select all

define([
    "dojo","dojo/_base/declare",
    "ebg/core/gamegui",
    "ebg/counter",
    "ebg/stock",
    "ebg/zone",
    g_gamethemeurl + "modules/scripts/Constants.js",
    g_gamethemeurl + "modules/scripts/ObjectManager.js",
    g_gamethemeurl + "modules/scripts/NotificationManager.js",
    g_gamethemeurl + "modules/scripts/InteractionManager.js"
],

...

        setup: function( gamedatas )
        {

            console .log( "Starting game setup" );
            
            // manages most dom objects, tokens, and zones and the client-side game state
            this.object_manager = new ObjectManager( this );

            // manages notifications log entries and animations
            this.notification_manager = new NotificationManager( this );
            
            // handles interactive elements and buttons
            this.interaction_manager = new InteractionManager( this );

            this.notification_manager.setupNotifications();
            console .log( "Ending game setup" );

        },
        
 
ObjectManager.js

Code: Select all

var ObjectManager = function( game ) {

    this.game = game;
    
    ...
    // setup stuff
    ...
};

ObjectManager.prototype.someFunction = function( someArg ) {
	this.game.slideTemporaryObject(...);
	dojo.removeClass(...);
	
	this.zone = new ebg.zone();
	this.zone.create( this.game, ... );
	this.game.showMessage( _('Translated Message'), 'info' );
};
    
I can then still access all of the animation methods and objects, I just have to access some things through the "game" reference, as illustrated above.

This has worked well for every use case I've had so far, it has worked with minified JS, and I've been able to build without errors. Is there any reason this wouldn't be able to go to a production server?