Error creating tournament with registerTournamentEnd function

I’m been going through the Typescript guide and testing out Nakama, so far so good!

I’ve run into a problem with tournaments, however. They seem to create ok, but I can’t seem register hook to handle when it ends. I get the following error in the log:

{"level":"info","ts":"2022-09-12T15:38:31.171Z","caller":"server/core_tournament.go:59","msg":"Tournament created","id":"dailyChallenge"}
{"level":"error","ts":"2022-09-12T15:38:31.175Z","caller":"server/runtime_javascript_logger.go:94","msg":"Error creating tournament%!(EXTRA map[string]interface {}=map[value:js registerTournamentEnd function key could not be extracted: not found])"}

Here’s a snipped of my server code:

const distributeTournamentRewards: nkruntime.TournamentEndFunction = function (
  ctx: nkruntime.Context,
  logger: nkruntime.Logger,
  nk: nkruntime.Nakama,
  tournament: nkruntime.Tournament,
  end: number,
  reset: number
) {
  // I commented everything out here...
};

const InitModule: nkruntime.InitModule = function (
  ctx: nkruntime.Context,
  logger: nkruntime.Logger,
  nk: nkruntime.Nakama,
  initializer: nkruntime.Initializer
) {
  // ...

  // Create tournament
  {
    const id = "dailyChallenge";
    const authoritative = false;
    const sortOrder = nkruntime.SortOrder.DESCENDING;
    const operator = nkruntime.Operator.BEST;
    const resetSchedule = "*/10 * * * *"; // Every 10 minutes
    const duration = 1000; // Until reset
    const metadata = {
      weatherConditions: "rain",
    };
    const metadata = {};
    const title = "Daily Challenge";
    const description = "The top score for today's challenge";

    try {
      nk.tournamentCreate(
        id,
        authoritative,
        sortOrder,
        operator,
        duration,
        resetSchedule,
        metadata,
        title,
        description
      );

      initializer.registerTournamentEnd(distributeTournamentRewards);

      logger.info("Tournament created");
    } catch (error) {
      logger.error("Error creating tournament", error);
    }
  }
};
  1. Versions: Nakama 3.13 on Docker
  2. Server Framework Runtime language: TS

Any help would be appreciated. Thanks!

Hello @himmelattack, I can’t tell by the snippet, is initializer.registerTournamentEnd invoked at the top level of your InitModule function?

Ok, so I eventually resolved out the problem, by adding duration, startTime, and endTime when creating the tournament. The corrected code is below.

I also had to remove the previous tournament with the same ID in order to change the resetSchedule. It appears that the schedule is cached otherwise…

const distributeTournamentRewards: nkruntime.TournamentEndFunction = function (
  ctx: nkruntime.Context,
  logger: nkruntime.Logger,
  nk: nkruntime.Nakama,
  tournament: nkruntime.Tournament,
  end: number,
  reset: number
) {
  logger.info("In distributeTournamentRewards for tournament", tournament.id);
};

const InitModule: nkruntime.InitModule = function (
  ctx: nkruntime.Context,
  logger: nkruntime.Logger,
  nk: nkruntime.Nakama,
  initializer: nkruntime.Initializer
) {
  logger.info("Starting custom module");

  initializer.registerTournamentEnd(distributeTournamentRewards);

  // Create tournament
  {
    const id = "dailyChallenge";
    const authoritative = false;
    const sortOrder = nkruntime.SortOrder.DESCENDING;
    const operator = nkruntime.Operator.BEST;
    const resetSchedule = "* * * * *"; // Every minute
    const duration = 60; // 60 seconds 
    const metadata = {
      weatherConditions: "rain",
    };
    const title = "Daily Challenge";
    const description = "The top score for today's challenge";
    const category = 1; // For filtering tournaments
    const startTime = 0; // Start now.
    const endTime = 0; // Never end, repeat the tournament each day forever.

    try {
      nk.tournamentCreate(
        id,
        authoritative,
        sortOrder,
        operator,
        duration,
        resetSchedule,
        metadata,
        title,
        description,
        category,
        startTime,
        endTime
      );

      logger.info("Tournament created");
    } catch (error) {
      logger.error("Error creating tournament", error);
    }
  }
};

Hi @sesposito! I just figured it out, as in my response below. However, I’m still confused about a few things:

  • Are duration, startTime, and endTime mandatory when creating a tournament?
  • Is there a way to “update” a tournament in order to change its settings? Or is the correct pattern to delete the tournament if it exists before creating it again?

Thanks a lot!

  • Duration is mandatory and has to be > 0 - it dictates for how long the tournament is active and accepts scores, starting from Start Time.
  • Start Time can be set to 0 (meaning it’ll start effective immediately).
  • End Time can be set to 0, meaning the tournament’s end is dictated by duration alone. If it is set to a value > 0 AND a reset schedule is present, then it should be a value after at least one cycle from Start Time to the first reset.

There is no way to update a created tournament, to change its configuration it has to be deleted and recreated.