[Off Topic] Typescript object instance creation issue

I have a Typescript related query. Here is how I planned my code
I have a class named Game.
Its declared in the global scope

let game: Game | null = null;

In match loop when the game starts I want to create instance of Game and assign it to “game” variable
like this

 if (game == null) {
                        game = new Game(logger);
                    }

Here I get the following error
TypeError: Cannot assign to read only property ‘game’"
So I tried to create a variable inside GameState and store it there. that also is not allowed. Can someone share some insights

In the InitModule I can create the instance but I cannot access it in matchloop

let game: Game | null = null;
function InitModule(_ctx: nkruntime.Context, logger: nkruntime.Logger, _nk: nkruntime.Nakama, initializer: nkruntime.Initializer) {
    try {
            game = new Game(logger);
    } catch (error) {
        logger.debug('InitModule Create Game Instance Failed ----> : ' + error);
    }
    logger.info(`Hello World!............................game? ${game == null}`);}

@Sathyaraj the use of global variables is heavily discouraged, it’s bad practice and can lead to unexpected issues due to inner workings of Nakama’s JS VMs.

RPCs should not use global state at all, this won’t work as expected due to how Nakama uses a pool of VMs to service requests, this means that each request may be serviced by a different VM, and if global vars are used, these VMs will have different global state. Keep all state local to the functions and use the storage engine for any state that needs to be persisted across requests.

Global state should only be used for constants, this is why the runtime throws an error if you attempt to write over a globally declared object.

The recommended approach for match code is that you keep all your game state in the state object (should be a POJO), and use simple functions to manipulate it.

Hope this helps.

Somewhere I read that we cannot store objects inside GameState. and it cannot have functions. I am trying to build the game with OOPS principle. So once the game starts I want to spawn a Game class and it use it across ticks.
Can you show a small snippet how it could be done.

Have a look at our project template, it contains a TS example.

Yes, I went through it a few times. It’s a very minimal use case. I still did not understand how to use classes and objects inside match_loop. I know this is not related to Nakama. But some insights would help.

The example avoids using objects and classes for the aforementioned reasons but there’s nothing preventing you from using OOP principles - have a class with a constructor or method that takes in the state object and populates its internal state and then manipulates it with its own instance methods, and then has a method that returns the state as a simple POJO for the match handlers.

You’ll need to re-instantiate this object in every RPC and match handler function, but otherwise this is not dissimilar to any object serialization/deserialization pattern.

Here is what I understood. instance the Game class when the match starts in matchloop. serialize and save it in GameState at the end of the loop. in the next loop Deserialize it to Game class and use it again. Correct me If I am wrong.

yes this should be a valid approach

1 Like