Author Topic: Learning about the TRPG code: Lesson 1.  (Read 9656 times)

0 Members and 2 Guests are viewing this topic.

Hidama

  • Gnoll Fighter
  • **
  • Posts: 72
  • Reputation: +0/-0
Learning about the TRPG code: Lesson 1.
« on: March 7, 2005 07:27 pm CST »
Hello there! My name is hidama, and I've started this post (the first in a series of posts) in order to help people understand the tribes rpg code. I'm not sure if I should put this in Assistance or Development, so I was told to just put it in general discussion for now, and ask for it to be moved to where it is supposed to be after. Sorry it is so long, but I needed to show people who are new to coding just how it works. If I do another lesson, it won't be so long.

Before we get started, I feel there is some need to introduce some basic functions to everyone reading this, since even people who have played this mod for a long time and know the code somewhat well do not know what the functions floor or cap are.

Once we get going, we'll start looking at some more advanced code, and eventually learn things like how spells work, the basics of mining, and how a player or bot is damaged.

For our first trip into trpg code, we're going to visit rpgfunk.cs, a file found in scripts.vol (in the Tribes\RPG folder). You can open rpgfunk.cs or any .cs file with notepad, and you can extract the contents of scripts.vol with volumer (available at particle's site- thank you so much!).

rpgfunk.cs contains many internal functions in the tribes rpg code, functions that are called often (string and saveworld functions), and functions that just don't have any place anywhere else.

We're going to look at a few basic functions in rpgfunk.cs, the first of which being a simple one in which I can describe some basic coding styles to you. I'll go over a few more functions, then show the function that determines the LCK cost.



Code: [Select]
function OddsAre(%n)
{
        dbecho($dbechoMode, "OddsAre(" @ %n @ ")");

        %a = floor(getRandom() * %n);
        if(%a == %n-1)
                return True;
        else
                return False;
}

I am going to explain this code piece by piece. The first part "function OddsAre(%n)" tells the code that it is starting a new function called OddsAre, which takes an input %n (which is really any number in this function).

You could call this function from within some other code by placing "OddsAre(8);" in that code (that is an actual example from the trpg code).

Let's say we do call it with    OddsAre(8);

The function is contained within the brackets { } so the first line that is processed is the dbecho line. This is just for if you are hosting a server I think, so don't worry about it.

The next line is     %a = floor(getRandom() * %n);

First off, %n is interpreted as 8, and getRandom() will return a number between 0 and 1 (well, getRandom() never returns 1, but a number just slightly under it at most).

When this random number is multiplied times %n (8), it gives a number between 0 and 8, but not 8 itself.

Then the floor() function is called. What floor does is cut the decimal points off of a number, always rounding down.

floor(8.4); returns 8, floor(0.5); returns 0, floor(7.9999); returns 7.

Let's say getRandom() * %n gives 7.9 (or anything above 7.0) so that the floor function returns 7.

%a is set to the number 7, so %a equals 7 (doing %a = something; assigns %a a value of 7).

The next line is an if statement, it will test whether something is true or not. If whatever is tested inside parentheses is true, then it executes the line below it, if it is false, then the line below the else is executed.

This if statement tests if %a is equal to %n - 1 (it says %a == %n-1 because == tests equality).

If %a is equal to %n - 1, then it returns true, and the line of code below it is executed.

We had %a equals 7, and %n is 8, so %n - 1 equals 8 - 1 which is 7. So the line "return True;" is executed. This means the function returns "true" to "OddsAre(8);". So if you do %t = OddsAre(8); it would set %t equal to "true" in this case.

If %a is not equal to 7, say 6 or 0, then the if statement returns false, and the line of code below the else is executed, which returns "false".

The point of this function is, on average 1/8 of the time %a equals 7, and 7/8 of the time it equals any number from 0 through 6. So only 1/8 of the time it returns true.



The next function we are looking at is the round(); function, which takes a number and rounds it.

Code: [Select]
function round(%n)
{
//      dbecho($dbechoMode, "round(" @ %n @ ")");

        if(%n < 0)
        {
                %t = -1;
                %n = -%n;
        }
        else if(%n >= 0)
                %t = 1;

        %f = floor(%n);
        %a = %n - %f;
        if(%a < 0.5)
                %b = 0;
        else if(%a >= 0.5)
                %b = 1;

        return (%f + %b) * %t;
}

This function takes an input (number), just like OddsAre. Notice the // at the beginning of the first line. This makes the line a comment, so the dbecho isn't called.

First, an if statement is used to test if your number was negative (%n < 0), if it is below 0. If so, %t is set to -1, and %n is set to the negative of itself (which will make it positive).

If %n is more than or equal to zero, the else if returns true and %t is set to 1, %n stays the same.

%f is set to the floor of %n (%n with the decimal points taken out of it), and then %a is set to the original number %n minus the floored number %f. This makes %a the decimal points of %n without the whole number. This is used to determine if %n was 8.5, 8.4, 8.8, etc. by making %a equal to 0.5, 0.4, 0.8, etc. and then testing it using the if statements.

The next statement tests if %a (the decimal portion of %n) is less than 0.5. If it is, then %b is set equal to 0, which means rounding down.

If %a is not less than 0.5, then it is equal to 0.5 or more than 0.5, in which case, %b is set to 1.0 (rounding up).

Then %f (the whole number) plus %b (either 0 or 1, rounding up or down) is returned, times %t, which will keep the number negative if it is negative.

So round(8.4); returns 8, round(8.5); return 9, round(8.999); returns 9, and round(-8.5); returns -9.0.



Now to the cap function, which is very important. The input is %n, any number, a lower bound %lb and an upper bound %ub.

This function will return %n if it is between the lower bound and upper bound, return the lower bound if %n is lower than it, and return the upper bound if %n is higher than it.

Code: [Select]
function Cap(%n, %lb, %ub)
{
        dbecho($dbechoMode, "Cap(" @ %n @ ", " @ %lb @ ", " @ %ub @ ")");

        if(%lb != "inf")
        {
                if(%n < %lb)
                        %n = %lb;
        }

        if(%ub != "inf")
        {
                if(%n > %ub)
                        %n = %ub;
        }

        return %n;
}

At first, a test is done to see if the lower bound is input as "inf". if %lb is "inf", then the lower bound is infinitely low, and %n can be very low without any problems.

If %lb is not inf, then a test is done to see if %n is lower than the lower bound, if so, %n is set equal to the lower bound, and the lower bound is returned.

If the upper bound is inf, then a number can be infinitely large without any problems.

If the upper bound is not inf, then a test is done to see if %n is larger than the upper bound. If it is, then %n is set equal to the upper bound.

%n is then returned, if it was too high then the upper bound is returned, if it is too low then the lower bound is returned.

Often, a lower bound of 1 is set so that numbers do not get too low.

Cap(5, 0, 10); will return 5 since it is between 0 and 10, Cap(5, 0, 3); will return 3, since 5 is above 3, and Cap(0.3333, 1, inf); will return 1, since 0.3333 is below 1.

Cap(any number, inf, inf); is completely useless, since it returns the number. Cap(10000, 0, inf); will return 10000, since the number can be infinitely high. Cap(-5, inf, 10); will return -5, since the number can be infinitely low.



Here is a fun function I just wanted to introduce. It takes a number and makes it not have such long decimals, partly by rounding.

Code: [Select]
function FixDecimals(%c)
{
        dbecho($dbechoMode, "FixDecimals(" @ %c @ ")");

        %d = round(%c * 10);
        %m = (%d / 10) * 1.000001;

        return %m;
}

This takes a number %c (lets say, 0.49999), multiplies it by 10, and then rounds it.

%d is set to this number (0.49999 * 10 is 4.9999, then rounding it 5.0).

%m is set to %d divided by 10 (5.0 / 10 equals 0.5) then multiplied by 1.000001 (to get any long decimals out of it).

So this returns 0.5 if you input 0.49999. It takes all of the long decimal points out of there except for the first one.




Alright, now that we're done with this lesson, lets look at a use of it.

Ah, the GetLCKcost function, also in rpgfunk.cs, this function determines the LCK cost based upon how many you already have.

Code: [Select]
function GetLCKcost(%clientId)
{
        dbecho($dbechoMode, "GetLCKcost(" @ %clientId @ ")");

        %a = floor( pow(2, Cap(fetchData(%clientId, "LCK"), 0, 26)) * 15 ) + 100;

        return Cap(%a, 0, "inf");
}


The input is %clientId, a number (usually above 2048) that is assigned to each player and bot.

The line of code that determines lck cost is a long one, lets take this from the middle of the line out.

fetchdata(%clientId, "LCK") is called, I won't tell you what this is now, but fetchdata just returns how much LCK you have.

The Cap function makes sure that if you have less than 0 lck (I don't know how), then the cost is determined like you have 0 LCK, and if you have more than 26 LCK, the cost is determined like you have 26 LCK.

Then the pow function is called, this just raises 2 to the power of the next number, which is pretty much your LCK amount. so pow(2, 0); returns 2^0 = 1, pow(2, 1); returns 2^1 = 2, and pow(2, 2); returns 2 squared (2^2) = 4.

Then the number is multiplied by 15. It is floored so taht any decimals are not there, and then 100 is added to it.

The returned number (cost) cannot be less than 0, but can be infinitely high.

If you have 0 LCK, the first LCK cost is 2^0 = 1, times 15 = 15, plus 100 = 115.

The second LCK cost is 2^1 = 2, times 15 = 30, plus 100 = 130.

The third is LCK cost is 160, the fourth is 220, the fifth is 340, the sixth is 580, and so on.

The highest lck can cost is when you have 26 LCK, from which you calculate (2^26 * 15 + 100) is 1,006,633,060 coins for the 27th LCK point. Needless to say, people only have over this much LCK from quests.


Well, that concludes this class. Next time we will go over some basic string functions in rpgfunk.cs

I promise the next lesson won't be so long! bye bye
« Last Edit: December 31, 1969 06:00 pm CST by Hidama »
for all of you who say I am nice, thank you thank you thank you :) :)

Particle

  • Chief Codemonger
  • Administrator
  • Centurian Lord
  • ********
  • Posts: 5,904
  • Reputation: +20/-4
    • Particle's Custom RPG
(No subject)
« Reply #1 on: March 7, 2005 08:05 pm CST »
I'll move this to documentation in a few days
« Last Edit: December 31, 1969 06:00 pm CST by Particle »
As a point of history:  Our last server clear was on September 27, 2004.  That is 4963 days ago (13.6 years) as of today.

If you're visiting after a long hiatus and have forgotten your password, try emailing me via the support form at http://www.pcrpg.org.

If your character is from after the 2004 clear but appears to have been deleted or reset, chances are it was caught in one of the inactive account purges over the years.  Backups were made before such events, so try the support form.

Hidama

  • Gnoll Fighter
  • **
  • Posts: 72
  • Reputation: +0/-0
(No subject)
« Reply #2 on: March 7, 2005 08:33 pm CST »
aww wow thanks :) that was nice of you. Hope people find this useful, even though this one was so long.
« Last Edit: December 31, 1969 06:00 pm CST by Hidama »
for all of you who say I am nice, thank you thank you thank you :) :)

GStricto

  • Elvin Legion
  • *****
  • Posts: 463
  • Reputation: +0/-0
(No subject)
« Reply #3 on: March 7, 2005 09:53 pm CST »
Nice lesson Hidama, although I must admit you have never struck me as the type of person who would know the code as well as you do.  I'm sure script kiddies like Shorty and PEACH will be happy to finally know what is going on with the scripts they have.  :wink:
« Last Edit: December 31, 1969 06:00 pm CST by GStricto »

Quote from: "Artorius"
Gnight.... Gstricto is obviously picking on you because he is a dirty racist.
So ironic that a heart made by man, when broken is easily fixed.   But a human hurt can last a lifetime.

Hidama

  • Gnoll Fighter
  • **
  • Posts: 72
  • Reputation: +0/-0
(No subject)
« Reply #4 on: March 8, 2005 05:14 pm CST »
Of course I'm good with the code, I guess. HUBBA always tells people to ask me if they have any questions about the aspects of trpg. Last year, whenever I wouldn't be able to be on the main computer, I'd be on mine, and mine could not play tribes because of some error with gdi32.dll or something. So I'd look at the code of the game. But yeah I took a few computer programming classes too, so I know bit about how this code is but not too much. This "class" is making me look at new code too and making me understand it (before I show it to others here). Thanks for the support :)

edit - people like taurik and sinister are much better coders than I am, as I'm sure you can already tell. I learned a lot from taurik.
« Last Edit: December 31, 1969 06:00 pm CST by Hidama »
for all of you who say I am nice, thank you thank you thank you :) :)

GStricto

  • Elvin Legion
  • *****
  • Posts: 463
  • Reputation: +0/-0
(No subject)
« Reply #5 on: March 9, 2005 02:38 pm CST »
Yes, Taurik is one of the best coders in Tribes right now, he would never admit to it, but it's the truth.  I might know more about TRPG, server-side mods, and quest scripting, but I have nothing on him when it comes to Perl or client-side code.  I still go back and read what he has done to GhettoBot and with his script pack, just amazing.  I'm quite sure the only people left that can even come close to matching him (that are still active in Tribes) are KingTomato (pretty much made PB mod all his own) and Plasmatic (Annihilation developer).  I must hold out in Java, C++ and OpenGL before he gets his grubby hands all in to that stuff. :wink:
« Last Edit: December 31, 1969 06:00 pm CST by GStricto »

Quote from: "Artorius"
Gnight.... Gstricto is obviously picking on you because he is a dirty racist.
So ironic that a heart made by man, when broken is easily fixed.   But a human hurt can last a lifetime.

FloPPy_PiLLoW

  • Elvin Legion
  • *****
  • Posts: 654
  • Reputation: +0/-0
(No subject)
« Reply #6 on: March 9, 2005 02:51 pm CST »
Bleh, I know the coding and stuff but
A) I am too lazy
B) You guys like to get technical, I have no clue what your talking about, I can code what I want but all this C++, Perl, Client-side confuses me. I don't understand all those technical terms.
« Last Edit: December 31, 1969 06:00 pm CST by FloPPy_PiLLoW »

Frantic

  • Elvin Legion
  • *****
  • Posts: 662
  • Reputation: +0/-0
(No subject)
« Reply #7 on: March 9, 2005 03:01 pm CST »
Quote from: "FloPPy_PiLLoW"
Bleh, I know the coding and stuff but
A) I am too lazy
B) You guys like to get technical, I have no clue what your talking about, I can code what I want but all this C++, Perl, Client-side confuses me. I don't understand all those technical terms.


« Last Edit: December 31, 1969 06:00 pm CST by Frantic »

Escalade

  • Gnoll Fighter
  • **
  • Posts: 91
  • Reputation: +0/-0
(No subject)
« Reply #8 on: March 9, 2005 07:34 pm CST »
Quote from: "FloPPy_PiLLoW"
Bleh, I know the coding and stuff but
A) I am too lazy
B) You guys like to get technical, I have no clue what your talking about, I can code what I want but all this C++, Perl, Client-side confuses me. I don't understand all those technical terms.


No one asked what you knew.
« Last Edit: December 31, 1969 06:00 pm CST by Escalade »


Quote from: "Escalade"
<3 gizoogle

Hidama

  • Gnoll Fighter
  • **
  • Posts: 72
  • Reputation: +0/-0
(No subject)
« Reply #9 on: March 9, 2005 09:01 pm CST »
you guys are so funny, you always immediately get into an argument. You even turn my post into a fight lol. Sorry it's just so funny. Why aren't you talking about the code and stuff? No wonder your post count gets so high.

[GLBL] "GhettoBot what is Frantic?"

[GLBL] GhettoBot "Hidama_Hinotama, Frantic is a wittle Jonah."

Sorry just had to say that, you guys are soooo funny. I'll post another lesson soon, you guys can carry your fight over there.
« Last Edit: December 31, 1969 06:00 pm CST by Hidama »
for all of you who say I am nice, thank you thank you thank you :) :)

Frantic

  • Elvin Legion
  • *****
  • Posts: 662
  • Reputation: +0/-0
(No subject)
« Reply #10 on: March 9, 2005 09:02 pm CST »
People still talk about me on the server? Sad...
« Last Edit: December 31, 1969 06:00 pm CST by Frantic »

Hidama

  • Gnoll Fighter
  • **
  • Posts: 72
  • Reputation: +0/-0
(No subject)
« Reply #11 on: March 9, 2005 09:08 pm CST »
HOLY CRAP! I make a post and you IMMEDIATELY have another one jonah, that was just scary. I mean... did you wait around for someone to post so you could make another post? that was just scary... wow. I was expecting to see my name as the last who posted in general discussion, and I seen it was still Frantic, I thought the browser didn't work right, surely enough, before I could even check my own post, you posted. lol that was just scary. but thanks for posting here, ok bye :)
« Last Edit: December 31, 1969 06:00 pm CST by Hidama »
for all of you who say I am nice, thank you thank you thank you :) :)

villman420

  • Minotaur Rager
  • ******
  • Posts: 752
  • Reputation: +5/-2
(No subject)
« Reply #12 on: March 9, 2005 09:16 pm CST »
gstricto, kingtom played nappy mod for a LONG time before he came to paintball mod. if you want to see a good modder, ask sneeky or kingtom about smokey, the maker of nappy mod.
« Last Edit: December 31, 1969 06:00 pm CST by villman420 »

Frantic

  • Elvin Legion
  • *****
  • Posts: 662
  • Reputation: +0/-0
(No subject)
« Reply #13 on: March 9, 2005 09:37 pm CST »
Hidama - Just between us, I sit at the main page refreshing over and over until someone replies.
« Last Edit: December 31, 1969 06:00 pm CST by Frantic »

Taurik

  • I'll have a Tribes 1
  • Elvin Legion
  • *
  • Posts: 683
  • Reputation: +0/-0
    • http://www.Linneberg.com
(No subject)
« Reply #14 on: March 9, 2005 11:53 pm CST »
Gladio - Thanks for the praise, but it really isn't the truth.  :( My script pack only seems impressive because i've been adding to it on and off for a few years... It's like one big, bloated helper script for rpg, nappy and annihilation. haha. And the only reason I was able to make ghettobot is because Perl is the ultimate duct tape and coat hangers language (it's forgiving to novice coders, unlike C++). You can throw anything together with it, using relatively little skill. The only thing easier is probably visual basic...

Ah yes, Plasmatic. Some of the stuff he codes is so amazing, I can't even begin to imagine how he may have done it... plasmatic.annihilation.info videos > all.

And kingtom is a great coder, but he isn't very original. Most of the things he has created are improved versions of things other people have already done. *grumbles about Kingtomato "Winamp Song Monitor"*
« Last Edit: December 31, 1969 06:00 pm CST by Taurik »