roomConfig - wxyz-abcd/node-haxball GitHub Wiki

RoomConfig

This class defines a roomConfig object to be used inside Haxball rooms. A roomConfig is the backbone of all Haxball bots. Every room has an internal (and initially empty) roomConfig object built inside.

1. RoomConfig.prototype

Defines these functions that has to exist in every plugin:

1.1. RoomConfig.prototype.defineMetadata(metadata: object)

This function is called internally inside the constructor of all roomConfigs by default. The function body is empty by default. This means that the metadata values are not stored in RoomConfig objects by default, because they are not useful in a non-GUI node.js environment. If we want to make use of the metadata, we might override this behavior by overriding this method with this code:

RoomConfig.prototype.defineMetadata = function(metadata){
  this.metadata = metadata;
};

Remember that this should be done after initializing the API and before initializing any roomConfigs.

1.2. RoomConfig.prototype.defineVariable(variableObj: object)

This function defines a variable inside the renderer object that can be changed from outside. The default behavior of this function is as follows:

RoomConfig.prototype.defineVariable = function(variableObj){
  return variableObj?.value;
};

If we want to make use of the metadata that we sent into this function; we can override this function, but have to be careful to always return variableObj?.value; in the end.

2. constructor(metadata: object)

Creates a new RoomConfig instance.

2.1. metadata

Any information that we would want to show/update inside a GUI application about this roomConfig. This is not used by the API by default, but we can reprogram the RoomConfig's prototype to make use of this value if we want.

Example RoomConfig Definition:

We can define a custom roomConfig with the following code:

function TestRoomConfig(API){
  const { RoomConfig } = API;
  Object.setPrototypeOf(this, RoomConfig.prototype);
  RoomConfig.call(this, {
    version: "0.1",
    author: "author",
    description: `This is a test roomConfig`
  });
  // RoomConfig codes here...
}

3. Callbacks

The API can work with the following callback functions inside a RoomConfig object.

3.1. initialize(room: Room)

If defined, called while creating or joining a room, or during a call to Room.setConfig. We should write all custom initialization logic inside this callback function.

3.2. finalize()

If defined, called while leaving a room, or during a call to Room.setConfig. We should write all custom finalization logic inside this callback function.

3.3. Common Callbacks

A RoomConfig calls all common callbacks by prepending onBefore, on, and onAfter before the callback's name. As an example; if the common callback is RoomPropertiesChange(props: object), there are 3 different callbacks related to it in the RoomConfig class:

  • customData = onBeforeRoomPropertiesChange(props: object): This is called as soon as the event happens at first, before all plugin and renderer callbacks for the same event. We can use this to initialize a customData object and return it from the function. The customData object is automatically passed to the next callback for the same event.
  • customData = onRoomPropertiesChange(props: object, customData: object): This is called just before the other plugin and renderer callbacks for the same event.
  • customData = onAfterRoomPropertiesChange(props: object, customData: object): This is called in the end, after all plugin and renderer callbacks for the same event have finished running.

We have to select the callbacks that we want to use and transform the callback signature to one of the above depending on when we want it to run while defining them in our roomConfig. All of these callbacks may also take an extra customData parameter that is passed from the previously called callback and may also return a new customData object to the next callback in the callback queue. This is done to be able to better communicate between API components.

NOTE: To use the modifier callbacks(except onOperationReceived, which is just like the other callbacks) in RoomConfig classes, we do not prepend onBefore, on, and onAfter. Instead, we append Before, nothing and After. The before callback has to return an array with two objects, the last one being the customData. So for example, the modifier callback newFrameNo = modifyFrameNo(frameNo: int) has 3 callbacks in a RoomConfig: [newFrameNo, customData] = modifyFrameNoBefore(frameNo: int), newFrameNo = modifyFrameNo(frameNo: int, customData: any) and newFrameNo = modifyFrameNoAfter(frameNo: int, customData: any).

NOTE: All callbacks are also accessible through all room objects directly. For example; we can write the code to add an onRoomPropertiesChange callback to room's config in two different ways:

  • Inside a RoomConfig:

    this.onRoomPropertiesChange = function(props, customData){
      // callback code here...
      // return customData; // if you need it
    }
    
  • By modifying the RoomConfig inside a Room object indirectly:

    room.onRoomPropertiesChange = function(props, customData){
      // callback code here...
      // return customData; // if you need it
    }
    

You can see the complete list of common callbacks here.