What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal
RebornBuddy Forums

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

IPulsator and You!

Apoc

Well-Known Member
Joined
Jan 16, 2010
Messages
2,790
Wildbuddy is built on a new framework, with an entirely new pulse model.

What is a "pulse"?

A pulse (in terms of Buddy bots), is similar to your heartbeat. It gets called on a "timer". By default in Wildbuddy, this is 20 times per second (or less depending on certain things being executed). This is the main mechanic that Buddy bots use to execute logic for all sorts of things, such as bots, combat routines, or plugins. Almost always, it is represented as a call to a method called "Pulse".


What is a "Pulsator"?

In Wildbuddy, we have a new system of calling "Pulse", and handling "many tasks at once". You can think of the Wildbuddy Pulsator object as a pseudo-scheduler. It handles ensuring that the IPulsable object registered to it, gets pulsed at the times it needs to. (Please note that Pulsator itself, implements IPulsable, this will be explained later). It also allows you to determine how fast it's registered objects are pulsed, whether they are even being pulsed (overriding the IPulsable instances), and lets you also "suspend" pulsing for a specific period of time.

You can register as many IPulsable objects as you wish to any Pulsator object, however, we suggest that you group your IPulsable's by some form of logical system and toss them in a new Pulsator instance.


What is "IPulsable"?

In short, it's an interface, defined as follows:

Code:
	/// <summary>	///     Defines behavior for a pulsable object.
	/// </summary>
	public interface IPulsable
	{
		/// <summary>
		///     Whether or not this Pulsable object is currently allowed to be pulsed.
		/// </summary>
		bool CanBePulsed { get; }


		/// <summary>
		///     Called each time this object is pulsed.
		/// </summary>
		void Pulse();


		/// <summary>
		///     Called when this pulsator is registered in a Pulsator object.
		/// </summary>
		/// <remarks>[NYI]</remarks>
		void OnRegistered();


		/// <summary>
		///     Called when this pulsator is unregisterd in a Pulsator object.
		/// </summary>
		/// <remarks>[NYI]</remarks>
		void OnUnregistered();
	}

There are two very important parts here, CanBePulsed, and Pulse(). CanBePulse simply returns what it says on the tin, whether that specific instance of IPulsable can currently be pulsed by the Pulsator that houses it. Pulse, again, does what it says on the tin.

Any object that implements IPulsable can be registered to a Pulsator, and each IPulsable object will have its CanBePulsed evaluated before any Pulse() call is made (this ensures that we're not executing "extra code" that doesn't need to be executed).

Please see the following code for an example of usage:

Code:
			Pulsator botPulsator = new Pulsator();
			botPulsator.RegisterForPulse(GameEngine.CurrentBot);
			botPulsator.TicksPerSecond = 20;


			Pulsator routinePulsator = new Pulsator();
			routinePulsator.RegisterForPulse(GameEngine.CurrentRoutine);
			routinePulsator.TicksPerSecond = 20;


			// Register the routine to be pulsed under the bots.
			botPulsator.RegisterForPulse(routinePulsator);




			Pulsator pluginPulsator = new Pulsator();
			pluginPulsator.RegisterForPulse(new MyPlugin());
			// Don't pulse plugins nearly as often as bots/routines.
			pluginPulsator.TicksPerSecond = 10;


			botPulsator.RegisterForPulse(pluginPulsator);




			Pulsator fastPulsator = new Pulsator();
			fastPulsator.RegisterForPulse(new TimeCriticalPulsableObject());


			// NOTE: This will only actually run at 20 TPS, because botPulsator itself is capped at 20.
			// Child pulsators can only run as fast as their parent!
			fastPulsator.TicksPerSecond = 60;


			botPulsator.RegisterForPulse(fastPulsator);

As you'll notice, the bot, and routine are being registered under their own Pulsator object, set to run at 20 ticks per second (TPS). Plugins are registered at 10 TPS (as they don't need to be run quite as often). And finally, there is a "TimeCriticalPulsableObject" being registered at 60 TPS. As noted in the comments, the last pulsator registered, will only run at a maximum of 20 TPS, because its parent (botPulsator) is set to 20. Children can only run as fast as their parents!

In Wildbuddy there's a single main Pulsator object that everything is registered to by default (which is set at 20 TPS), GameEngine.BotPulsator. You may register anything you want to this, but keep in mind that it will only run at 20 TPS.

Also note, that you are free to create your own Pulsator, at however fast as you want, and run it separately! (It will run in it's own thread, so please do keep that in mind)

Due to this new architecture, the bot, routine, and plugin system are almost entirely separated. (You may still make calls between any of them, as per usual) They are executed "in parallel" (meaning that one is executed after the other, with no real relationship to the other). This allows you to easily "suspend" another Pulsator if you have something important to do. (Say you need to do some "Rest" logic in the routine, but the bot will immediately start doing it's own thing once you are out of combat, you'd want to suspend the bot's pulsator to do that)

Note: Any API here is subject to change, and probably will change at some point.
 
Back
Top