Bypass BZFS API - Game Timers & Countdown - Enable countdowns whenever with whatever timing for whoever

Questions, comments, and news on the server side plug-ins and it's API
Post Reply
User avatar
Zehra
Survey Champion 2024
Survey Champion 2024
Posts: 972
Joined: Sun Oct 18, 2015 3:36 pm
Location: Within the BZFS API and Beyond it
Contact:

Bypass BZFS API - Game Timers & Countdown - Enable countdowns whenever with whatever timing for whoever

Post by Zehra »

One problem sometimes encountered is granting some form of a countdown within a game. Currently we just give it a starting point, activate it and watch the timer countdown. Instead, what if we could set timers/adjust them on the fly/extend games on demand? This is what is now possible!

Enable flags to have time limits, regardless if they are good or bad, give indicators for the duration of a powerup, set time limits for in game goals/races, show different countdowns depending on team objectives..etc

Here's how to do it:

Include bzfs.h and StateDatabase.h in addition to the standard bzfsAPI.h header. The way I compile plug-ins means it looks like this, but your results may vary.

Code: Select all

#include "bzfsAPI.h"
#include "../src/bzfs/bzfs.h"
#include "StateDatabase.h"
Now we just need two custom utility functions to enable all possibilities:

This one sends an individual timer for a single player:

Code: Select all

void sendPlayerTimerUpdate(int playerID, int timerUpdate)
{
  bufStart = getDirectMessageBuffer();
  buf = nboPackInt(bufStart, (int32_t)timerUpdate);
  directMessage(playerID, MsgTimeUpdate, (char*)buf-(char*)bufStart, bufStart);
}
And this one sends it to all players:

Code: Select all

void sendAllTimerUpdate(int timerUpdate)
{
  void *buf, *bufStart = getDirectMessageBuffer ();
  buf = nboPackInt (bufStart, (int32_t) timerUpdate);
  broadcastMessage (MsgTimeUpdate, (char *) buf - (char *) bufStart, bufStart);
}
Sending any positive value will "activate" the timer if it hasn't been started, or change it if it is already started. Or resume it if the timer is paused:
Example: sendAllTimerUpdate(30); will send a timer of 30 seconds. sendAllTimerUpdate(-1);[/b] will pause any active timer.
In short the following grant timers of 60 seconds:

Code: Select all

sendAllTimerUpdate(60);
sendPlayerTimerUpdate(playerID, 60);
While the ones below will pause the timer:

Code: Select all

sendAllTimerUpdate(-1);
sendPlayerTimerUpdate(playerID, -1);
It's relatively simple to use and merely requires keeping good track of the timers set/sent.

The only slight issue may be issues with replays, but this is relatively minor compare to most problems:
From the code, it appears that Direct messages in terms of packets aren't recorded.
This may be seen in the void directMessage(int playerIndex, uint16_t code, int len, void *msg) compare to void broadcastMessage(uint16_t code, int len, void *msg) which appears to contain methods for recording packets.

Hopefully someone finds this fun and useful!

-Zehra
Some useful references:
Map editor and tool list (summary)
Prefab and BZW help threads index
Map releases index
Some of my BZFlag related stuff.
BZList.net Modern HTML5 server stats site.

BZFlag has a cycle every 1-3 years. Activity drops/stops and resumes some time after. It returns to 90% of what it was.
We see late in 2013, the following thread: Why are there only like 30 people playing BZFLAG at one time.
Let's say 2014 starts with 30 players:
With a cycle length of:
3 years: 2017=27 players, 2020=24 players...
2.5 years: mid-2016=27 players, 2019=24 players, mid-2021=22 players.
I think the cycles get shorter as time goes along, but the bigger issue is eventually that activity will not be able to sustain itself in the long run, as nobody waits an hour for people to show up.
Post Reply