Author Topic: [Resource] Baseplate (extremely early alpha version)  (Read 1185 times)

Going to quote this entire post because it'll clear things up a lot (this post is what this is based on):

Sometimes programming in TorqueScript can be a bit of a pain. So I had an idea a while ago for a little support script that someone could execute and it would wrap TorqueScript things into a simple interface. It works a lot like jQuery, with recursive or chaining of functions and is completely event-orientated and a tiny bit asynchronous. Here's a little bit of examples of what it can do (the global object is known as _ for quick coding, $Baseplate if you're picky):

Code: [Select]
_.on("client connect", sayHello);

function sayHello(%client) {
_(%client).message("You're now admin.").admin(true).message("Just kidding.").kick();
}

The engine is basically event-based, which means you bind a callback to an object based on a specified event and then when that object triggers that event (or "it happens") the callback is called (usually with additional arguments, depending on the event). The first bit is a function that binds the global event "client connect" to the function/callback "sayHello" (which is then defined below it). "sayHello" is passed the %client object who just connected to the server and called whenever a client connects.

Then the real magic of the recursive nature of the library starts. The first function is just the function "_", which at the moment just returns the object if it is passed an object. This is only used to signify the fact that you'll be using a baseplate chain for easier reading, and it's possible it'll be required in a future version (if there is one). You'll notice it's one big long line (and it might look a little messy like that, but you can make it look nicer by putting a new line between the dots). This is because every function that takes a value (for eg. the "message" function is a method on the client that messages a value to the client) then returns the client afterwards.

The first function messages the client telling them they're getting admin, then returns the client object, which then can be recursively used again. Then the client is made an admin (admin(isAdmin)) and then the client object is again returned. The client is then messaged saying it was a joke and then the client is returned. Then finally the client is kicked from the server. Note: all of these functions are defined by this library.

But that's just a simplistic example, there are plenty of other cool features. Note: Most methods in the library return the current value of a property of an object when no arguments are supplied, but set the property of the object to a supplied argument and then return the object if an argument is supplied.

An array class (all baseplate methods that need some sort of array thing use this):
Code: [Select]
%array = _.Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
%another = _.Array(11, 12, 13, 14, 15);

%array.push(11).pop(); // add 11 to the end, then remove the last element (hence removes newly added 11)
%array.concat(%another).each(forEach); // concatenate (joins two arrays) and then return a newly joined array, but then do a foreach loop on it and calls the specified callback ("forEach") with every value in the array

function forEach(%value) { // called for each value in the array
echo(%value);
} // echos all the way between 0 and 15

echo(%another.join("\t")); // joins an array together into a string, delimited by a string value
// echos "11\t12\t13\t14\t15"

%zeros = _.Array();
%zeros.allocate(100, 0); // sets the array size to 100 and fills all elements with zero
%zeros.set(0, 1).reverse(); // sets the first element to 1 and then reverses the array, hence 1 is now the last element (the 100th element)

A platform object (and class, but it's auto instantiated) that gives you underlying connections to the player's computer. Because all of the methods are generally accessing things controlled by the computer, the only thing that takes an argument to change it's property is .clipboard and .resolution.
Code: [Select]
%platform = _.platform; // also _.Platform() or $Baseplate::Platform

echo(%platform.os()); // echoes "windows" or "macintosh", as they are the only operating system that currently work for blockland
echo(%platform.ram()); // echos the amount of ram the computer has
echo(%platform.clipboard("lol this is on the clipboard").clipboard()); // sets the clipboard and then echos the value of it, should echo what it was set to

%resolution = %platform.resolution(); // returns an array of the computer's resolution

echo(%resolution.get(0) @ ", " @ %resolution.get(1));
%platform.resolution(800, 600); // set the computer's resolution to 800 by 600.

// and others that aren't as useful

A benchmarking system for testing the speed of something (usually against another method):
Code: [Select]
function test1(%time) {
if(%time) // finished
echo("test1 took " @ %time);
else
getRandom(1, 10);
}
function test2(%time) {
if(%time)
echo("test2 took " @ %time);
else
getRandom(1, 1000);
}

// do 1000 tests of each
_.benchmark(test1, 1000);
_.benchmark(test2, 1000);

A simplified schedule system:
Code: [Select]
function callback1() {
echo("callback1 called");
}
function callback2() {
echo("callback2 called");
}

_.in(4000, callback1); // in 4 seconds after this is called, call callback1
_.every(5000, callback2); // every 5 seconds call callback2 (repeating schedule)

Extended string operations:
Code: [Select]
%string = _.string;

%string.toUppercase("dogS"); // -> DOGS
%string.charAt("bbbac", 3); // -> "a"
%string.fromCharCode(%string.charCodeAt("zed", 0)); // -> "z" (ascii map manipulation, useful for lots of things)

function tokenCallback(%token) {
echo(%token);
}

%string.tokenize("dogs:are:animals:omg", ":", tokenCallback);

Extended math operations:

Code: [Select]
%math = _.math;

echo(%math.PI);
echo(%math.PHI); // more constants too

%math.cos(3.14); // all trig in radians, just like torque
%math.atan(0.5); // this is the standard atan, torque forces atan2 on you
%math.atan2(0.5,0.5); // torque's version (works better for complex math)
%math.round(0.4); // 0
%math.radians(90); // %math.PI / 4
%math.degrees(%math.PI / 2); // 180
%math.ln(100); // natural log
%math.exp(10); // exp function
%math.random() // random value, or %math.random(min, max)
%math.fraction(10.2); // returns 0.2 (fraction part of a number)
%math.base(50, 2); // 11010 (converts from one base to another, %math.base(%value, %to [, %from = 10]);

Crypto functions:
Code: [Select]
%crypt = _.crypt;

echo(%crypt.sha1("i am laughing hahahah dogs")); // uses native sha1 algorithm in torque
// %crypt.md5("dogs are funny"); needs big number math, almost works but torque's large number handling breaks it
echo(%crypt.base64Decode(%crypt.base64Encode("ninjas are smart")); // ninjas are smart

And then other things, like working with game objects (clients, players, bricks):
Code: [Select]
%brick.pushState();
%brick.name("cat_umbrella").item(gunItem).vehicle(jeepVehicle);
%brick.popState(); // back to how it was when pushState was called

Other things I've thought about are JSON handling, XML handling, networking utilities and stuff. Is this pointless or would people actually use this library?

This is a very early implementation of a system like this. No, it hasn't been tested yet, but most if not all of the currently implemented functionality should work. Get it here: http://hostr.co/cywZA2uEyg4l

Quick list of current functions, objects, etc.:

_ (alternatively $Baseplate)
The main Baseplate object.

_([object]) (alternatively Baseplate(...))
For now, simply returns the passed object if any, _ otherwise.

_.in(delay, object, method[, ...]) (alternatively $Baseplate.in(...) - this is obvious, not writing this anymore)
Schedules method (optionally as a method of object) to be called with the specified arguments in delay milliseconds. Returns a schedule reference.

_.every(delay, object, method[, ...])
Repeats a call to method (optionally as a method of object) every delay milliseconds. Returns a repeating schedule identity.

_.cancel(reference)
Given the return value of _.in or _.every, cancels the pending call or repeating call.

_.pending(reference)
Given the return value of _.in or _.every, cancels the pending call or repeating call.

_.on(event, method)
Registers method as a callback for when event is triggered. See below for a list of events.

_.trigger(event[, ...])
Calls all callbacks defined for event with the given arguments.

_.crypto (alternatively $Baseplate::Crypto, or instanciated with _.Crypto())
Provides simple cryptography features.

_.crypto.base64Encode(value)
Returns value encoded with base64.

_.crypto.base64Decode(value)
Returns value decoded with base64.

_.crypto.sha1(value)
Returns value hashed with sha1.

_.platform (alternatively $Baseplate::Platform, or instanciated with _.Platform())
Provides access to platform information and basic configuration(?). Extremely incomplete.

_.platform.os

...

you know what forget it
I'm going to write a good, formal documentation later
just read through the code and the post at the top

yes, arrays, events, bignum math, etc. is implemented



Current event list (extremely incomplete):

  • "client connect" - triggered immediately after gameConnection::autoAdminCheck
  • "client disconnect" - triggered immediately before gameConnection::onDrop
  • "chat" - triggered immediately after serverCmdMessageSent and ...TeamMessageSent
  • "global chat" - triggered immediately after serverCmdMessageSent
  • "teamchat" - triggered immediately after serverCmdTeamMessageSent

This is extremely incomplete right now.

A very small example of the "event/scheduling" part of this:

function start( %client )
{
   _.every( 1000, %client, annoy );
}
 
function gameConnection::annoy( %client )
{
   %level = _.math.random( 0, 2 );
   %level = _.math.floor( %level );
   
   _( %client ).message( "fat" ).admin( %level );
}
 
_.on( "client connect", start );

I'm very confused about double posting rules.

I'm very confused about double posting rules.

There aren't any.

The user defined double posting rules.

So kind of (really loosely) VCE for torquescript? Yeah. I like this.

So kind of (really loosely) VCE for torquescript? Yeah. I like this.
I've always considered VCE as an in game torquescript for Blockland.


Wow, this is incredible. Simplifies a lot of scripting. Really looking forward to where this goes, although i'm not entirely confident i would use it.


package _EmoteTriggers {
function serverCmdAlarm( %client )
   {
      parent::serverCmdAlarm( %client );
      _.trigger( "Emote Alarm", %client );
   }
   function serverCmdWTF( %client )
   {
      parent::serverCmdWTF( %client );
      _.trigger( "Emote WTF", %client );
   }
   function serverCmdConfusion( %client )
   {
      parent::serverCmdConfusion( %client );
      _.trigger( "Emote Confusion", %client );
   }
   function serverCmdHate( %client )
   {
      parent::serverCmdHate( %client );
      _.trigger( "Emote Hate", %client );
   }
   function serverCmdLove( %client )
   {
      parent::serverCmdLove( %client );
      _.trigger( "Emote Love", %client );
   }
};
package _ClearBrickTriggers{
   function serverClearBricks( %client )
   {
      parent::serverClearBricks( %client );
      _.trigger( "Clear Bricks", %client );
   }
   function serverClearAllBricks( %client )
   {
      parent::serverClearAllBricks( %client );
      _.trigger( "Clear All Bricks", %client );
   }
   function serverClearBrickGroup( %client , %index )
   {
      parent::serverClearBrickGroup( %client , %index );
      _.trigger( "Clear Brick Group", %client , %index );
   }
   function serverClearFarAwayBricks( %client )
   {
      parent::serverClearFarAwayBricks( %client );
      _.trigger( "Clear Far Away Bricks", %client );
   }
   function serverClearFloatingBricks( %client )
   {
      parent::serverClearFloatingBricks( %client );
      _.trigger( "Clear Floating Bricks", %client );
   }
   function serverClearSpamBricks( %client )
   {
      parent::serverClearSpamBricks( %client );
      _.trigger( "Clear Spam Bricks", %client );
   }
};
activatePackage(_EmoteTriggers);
activatePackage(_ClearBrickTriggers);

i'll package a huge list of events later
« Last Edit: May 18, 2013, 01:33:20 AM by MARBLE MAN »