Your preferred scripting methods
#1

Your preferred scripting methods

Sup?

So anyways, it's that time of year again where I start developing my own gamemode (last year was a bust). Now I need opinions and I want you guys to tell me your preferred methods for scripting PAWN.

This is very similar to the coding style research thread from a while back, but this one is more advanced because I'm seeking more ways to do stuff.

1) Numerated lists

Code:
a)

#define DIALOG_PIZZA 1356
#define DIALOG_CARS 1483
#define DIALOG_GUNS 1753
#define DIALOG_STORE 1533


b)

enum
{
    DIALOG_PIZZA = 1356,
    DIALOG_CARS = 1483,
    DIALOG_GUNS = 1753,
    DIALOG_STORE = 1533
};
2) Player arrays

Code:
a)

new Money[MAX_PLAYERS];
new Score[MAX_PLAYERS];
new JailTime[MAX_PLAYERS];
new LoggedIn[MAX_PLAYERS];

b)

enum ePlayerInfo
{
    Money,
    Score,
    JailTime,
    LoggedIn
}
new PlayerInfo[MAX_PLAYERS][ePlayerInfo];
3) Functions

Code:
a)

stock GiveMoney(playerid, amount)
{
    Money[playerid] += amount;
    return 1;
}

b)

GiveMoney(playerid, amount)
{
    Money[playerid] += amount;
}

c)

forward GiveMoney(playerid, amount);
public GiveMoney(playerid, amount)
{
    Money[playerid] += amount;
}
4) Commands

Code:
a)

public OnPlayerCommandText(playerid, cmdtext[])
{
    if (!strcmp(cmdtext, "/help", true))
    {
        SendClientMessage(playerid, -1, "My help command.");
        return 1;
    }
    return 0;
}

b)

CMD:help(playerid, params[])
{
    SendClientMessage(playerid, -1, "My help command.");
    return 1;
}

c)

public OnPlayerCommandText(playerid, cmdtext[])
{
    dcmd(help, playerid, 4);
    return 0;
}

dcmd_help(playerid, params[])
{
    #pragma unused params
    SendClientMessage(playerid, -1, "My help command.");
    return 1;
}
5) Single statement functions

Code:
a)

stock IsPlayerLogged(playerid)
{
    return LoggedIn[playerid];
}

b)

stock IsPlayerLogged(playerid) return LoggedIn[playerid];

c)

#define IsPlayerLogged(%0) (LoggedIn[(%0)])
6) Conditions

Code:
a)

if (a)
{
    b = a + 1;
}
else
{
    b = a + 2;
}

b)

if (a) b = a + 1;
else b = a + 2;

c)

b = (a) ? (a + 1) : (a + 2);
7) Loops

Code:
a)

for (new i = 0; i < MAX_ITEMS; i ++)
{
    // ...
}

b)

new i;

while (i < MAX_ITEMS)
{
    // ...
    i++;
}
8) Variable grouping

Code:
a)

new a, b, c;

b)

new
    a,
    b,
    c;

c)

new a;
new b;
new c;
9) Multiple conditions

Code:
a)

if (something == 1)
{
    ...
}
else if (something == 2)
{
    ...
}
else if (something == 3)
{
    ...
}

b)

switch (something)
{
    case 1:
    {
        ...
    }
    case 2:
    {
        ...
    }
    case 3:
    {
        ...
    }
}

c)

if (something == 1) ...
else if (something == 2) ...
else if (something == 3) ...
10) Data organization

Code:
a)

stock Spawn(playerid)
{
    if (gTeam[playerid] == 1)
    {
        SetPlayerPos(playerid, 0.0, 1.0, 2.0);
    }
    else if (gTeam[playerid] == 2)
    {
        SetPlayerPos(playerid, 5.0, 10.0, 15.0);
    }
    else if (gTeam[playerid] == 3)
    {
        SetPlayerPos(playerid, 25.0, 10.0, 155.0);
    }
}

b)

static const Float:g_SpawnArray[3][4] =
{
    {0.0, 1.0, 2.0},
    {5.0, 10.0, 15.0},
    {25.0, 10.0, 155.0}
};

stock Spawn(playerid)
{
    SetPlayerPos(playerid, g_SpawnArray[gTeam[playerid] - 1][0], g_SpawnArray[gTeam[playerid] - 1][1], g_SpawnArray[gTeam[playerid] - 1][2]);
}
11) Formatting strings

Code:
a)

new string[128];

format(string, sizeof(string), "Emmet is");
format(string, sizeof(string), "%s a boss.", string);

b)

new string[128];

strcat(string, "Emmet is");
strcat(string, " a boss");
12) Copying a string

Code:
a)

new str[128];

format(str, sizeof(str), "%s", string);

b)

new str[128];

strcat(str, string, sizeof(str));

c)

new str[128];

memcpy(str, string, 0, 512, sizeof(str));
13) Clearing or deleting a string

Code:
a)

string[0] = '\0';

b)

strdel(string, 0, strlen(string));

c)

for (new i = 0, length = strlen(string); i < length; i ++)
{
    string[i] = 0;
}
14) Prefixing

Code:
a)

new score, string[128];

b)

new iScore, szString[128];
Thanks!
Reply
#2

1) b

2) b

3) a

4) b

5) b

6) c

7) a

8\) b

9) b

10) b

11) b

12) b

13) a

14) b
Reply
#3

The language features that exist should be used to suit the best case scenario for a given situation. Asking for preferences on syntax is fine, but things like #3, "stock" and "public" keywords just show one's lack of knowledge for the language they're using.

For example, when one writes a library they should declare variables (if not all) and functions that are only used internally by the library as static. For the functions called by the script that include the library, but not necessary to be called, should be stock.

I've wanted to write a tutorial describing how to use PAWN properly, but I feel like it would be a waste (just look at YSI).
Reply
#4

It ultimately comes down to YOUR opinion, but here are my preferences:

#1 - In cases like the one you presented, I would go with define because it is a better fit for said example. I typically will only use an enum in that case when I have a list of constants whos values are set in a specific manner (The common ones being: each one is increased by one, or each value is shifted to the left/right (bitwise)).

#2 - I prefer the second one hands down. It just is much cleaner and organized.

#3 - Depends on the function and its usage! This is less a preference and more of a functionality issue. If I know I am going to be using CallRemoteFunction or using this function in a timer, It obviously has to be public; no choice about it. If its just a function that I am planning on releasing/using for one file, then I would chose stock.

#4 - This is also more about functionality, rather then preference, as they are not equal. I would go with the fastest method, which in my scripting days, was YCMD (followed closely by zcmd).

#5 - I would probably just use the macro if I had to pick one instead of just using my player array.

#6 - It depends on the situation. I have a BIG pet peeve when it comes to people over using the triadic operator because they think it makes them seem more knowledgeable, or skilled. If it's a small statement, I understand...but if not, just use a regular if statement (I prefer A btw).

#7 - I will always use a for loop over a while when it comes to iterating a specifically known amount of times. Any smart man would (less chances of mistakenly creating an endless loop).

#8 - It depends on my mood. This is a good preference thing to ask! I usually use b the most.

#9 - Situation. Unless its a straight up ideal situation for switch, I'll go with if instead. That simply comes from other languages though. Pawn has my favorite implementation of the control structure personally (i liked being able to specify constant number ranges).

#10 - (Ignoring that you do not need to fill the array dimensions in this case/have a size issue with the second dimension) The first one is cleaner, and I would definitely go with that if it was a simple script. I like building dynamic scripts that are easy to modify ingame...so I would likely go with something along the lines of the second one if I was building it for personal use.

#11 - I would probably format the players name into my sentence ("%s is a boss"). Not really a practical example in either case tbh.

#12 - I've used a and b (though I always null the string out when using strcat). I think format is more clear tbh, but some people are going to complain about the speed in this thread :P.

#13 - A flat out.

#14 - Oh dear gawd...a...just a...always (with the exception of g_ for globals).
Reply
#5

1. - Neither y_inline/y_dialogs is the way to go
2. - I'd always go with an enum is makes more sense
3. - All of them depending on the situation but I'd also be using the static modifier on functions quite regularly since I script modular
4. - Obviously zcmd/ycmd method
5. - It really depends a function might be desirable if you looking for data encapsulated in a included
6. - I would go with b unless there is more than one action
7. - for is more desirable
8. - Either a or c depending on what is going on
9. - All 3 depending on the situation
10. - I'd go with b but would be using an enum UNLESS I'm expecting to passing the arrays to another function
11. - Don't you ever use strlib? I might use both methods at some point
12. - Most likely a
13. - I think I might go with b it's easier to read but a is fine
14. - Depends on what is going on so I might do both
Reply
#6

1) I only use enum for sequential constants or array indexes.
2) I tend to avoid huge player enums and such, especially since everything is split up into multiple include files (pseudo-modules).
3) Only make a function public if you actually need it.. Also, stock is best for large modules/includes that has unused functions. If you know a function is used, it shouldn't be a stock. It's no big deal if it is, though.
4) dcmd? strcmp? This is not 2007.
5) a - Consistency is good.
6) I only use ternary where it saves space and maintains readability.
7) a
8) a/b - If the total length is less than 80 characters I usually put it on one line, otherwise one variable for each line.
9) b/c - Depends on whether I'm testing for a static value or something else.. Apples and oranges.
10) b - I hope that question was a joke..
11) b - Only use format if you're actually formatting something!
12) NOT a - Don't use format to copy strings.
13) a - Strings are zero-terminated - anything after the first NULL-character is completely irrelevant to the string.
Reply
#7

1. a, 2. b, 3. a, 4. b, 5. c, 6. c, 7. a, 8. a, 9. b, 10. b, 11. a, 12. c, 13. a, 14. b

Also I may refer to Slice's tips thread https://sampforum.blast.hk/showthread.php?tid=216730

I'm using those tips with my gamemode, they're just something great. I loved Bit-flags in enums, char-arrays, and the usage of stock const for efficient memory management.
Reply
#8

Thanks a bunch for your opinions, guys!

Although, this was actually just a quiz for you all since I wanted to see if people were actually doing things right. It's nice to see some more people who have experience with PAWN!

I'm actually writing a tutorial on the things you shouldn't do in PAWN. I know for myself that I would never use public for functions, or EVER use format to copy strings. Just a discussion on what you guys think.

Quote:
Originally Posted by Slice
View Post
10) b - I hope that question was a joke..
Actually, the reason why I included it in the post was because someone questioned me about it earlier.
Reply
#9

Furthermore, a very important (often neglected) thing is consistency.

Use the same programming idioms, whitespace, and naming convention throughout your project.
Reply
#10

1, A

2, B

3, B

4, B

5, B

6, A

7, A

8, A

9, Sometimes A and B

10, B

11, B

12, A

13, None, I use string[0] = EOS;

14, A
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)