[Tutorial] Let's talk about scripting
#1







Within SA-MP's Scripting Help section and wiki, a lot of scripters show newbies archaic methods of doing things. I'm here to try and help to tackle that..


________________________________________



1. MEMORY ALLOCATION

Almost every newbie to scripting will type any random value into the size of the variable.

Take this for an example:

pawn Код:
new string[1024];
What you're saying to the script is to allocate 1024 cells (4096 bytes) of memory to that variable. This is fine if you're requiring that much memory, but when it is not applicable is when you're doing things like this:

pawn Код:
format(string, sizeof(string), "Welcome to the server, %s", "John_Smith");
A message like that only requires 34 cells (136 bytes) of memory. Therefore, you are leaving 990 cells (3960 bytes) of memory completely unused. It doesn't sound like much, but when you get into the habit of doing this, it comes at a price. Simple optimization techniques like only using as much as SendClientMessage will take (128 cells), instead of 256 (1024 bytes), or 1024 (4096 bytes) cells.

You might be wondering why it's the same numbers popping up, and you'll see it in every script. Numbers like 16, 32, 64, 128, 255, 256, 512, 1024, 2048, 4096 etcetera will constantly pop up in definitions.

Why is this? All of these numbers are powers of 2(except 255, see THIS for info). RAM works in the same method too. You'll never see 1.3(1300mb) gigabytes of RAM.

This part might not make complete sense, but just bare with me:

2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^8 = 255

Every location of memory all have different memory addresses. So, if you have an 8-bit system of addressing memory, your bits can be addresses from(in binary):

00000000 (0)
to
11111111 (8)

It doesn't matter how big of a number you use in addressing memory, but in current architrecture it is always going to be powers of 2.

If you have a 32-bit system to address memory, you'll get from 0 to this:

11111111111111111111111111111111

Or, as a more understandable number,

2^32: 4,294,967,295 or 4 gibibytes.
"Gibi" is a prefix to fix the disparity between a base ten system where giga means billion and a base two system where giga means 1,073,741,824. But enough about that now.


Also, your script runs on stack memory. If you're constantly making your strings too big (which is something I sometimes still do accidently, not going to deny it), you'll get an exception popping up when you compile your script telling you that you've ran out of stack memory. I've had the exception, and by reducing the sizes of strings and variables my script is not only compiling faster but also performing better.

The fix is simple: MAKE YOUR STRINGS SMALLER!

DO NOT USE #pragma dynamic UNLESS YOU ABSOLUTELY NEED TO!


________________________________________



Another thing I would like to touch on is this:

Have you ever seen a string defined like this?:

pawn Код:
new name[MAX_PLAYER_NAME];
MAX_PLAYER_NAME is just a number. It is defined in a_samp.inc and it is 24 bytes large.

We'll go on to explain macros in depth later, but you can do this type of thing to give your script more clarity when reading it:

pawn Код:
#define TYPE_1 (1)
#define TYPE_2 (2)
As you can see, TYPE_1 is 1 byte large and TYPE_2 is 2 bytes large.

So, we can do this:

pawn Код:
printf("%i", TYPE_1);
You can also embed it! If it isn't a string, you'll need to convert TYPE_1 and TYPE_2 to strings to embed it! Example:

pawn Код:
#define TYPE_1 "1"
#define TYPE_2 "2"

// Rather than
//#define TYPE_1 1
//#define TYPE_2 2
// ============

SendClientMessage(playerid, -1, "Type "TYPE_1" and Type "TYPE_2"");


________________________________________

1.5. #pragma macro

If you download a script you might see #pragma accompained by parameters at the top of a script. What is a pragma though?



••• It's the method of sending additional information to the compiler, beyond what is channeled by the language itself. •••

So, if we needed more stack memory, you can actually change it:

pawn Код:
#pragma dynamic 4096
//This creates a 16K stack of memory (default).
//It is measured in blocks of 4 byte cells.




________________________________________


2. SCRIPT STRUCTURE

Some scripts out there are a complete shambals in terms of structure. There is not an order within it, and things are just declared at any random place in the script.

Even though your script can be structured however you want it, if you're working in a community there's a chance that there's more than one scripter.

Splitting your script up can work, you could have a sepearate .pwn file with the enumerations, arrays, variables, functions, commands etcetera. At the same time that can be very complicated. So, here's a structure I go by using:

Код:
INCLUDES

MACROS

FORWARDING

VARIABLE DECLERATIONS

ENUMERATIONS

ENUM VARIABLE DECLERATIONS

PUBLIC FUNCTIONS

CUSTOM PUBLIC FUNCTIONS

FUNCTIONS

COMMANDS

STOCK FUNCTIONS

main(){}
Remember, this format works for me. It might not be for you. This format isn't actually got any technical condition as to why it's ordered in that way, but more to the point that it is easier to locate functions. A layout for your script is essential if you're going to release it, as nobody is going to have high standards for a messy script..

Your script structure also includes indentation. The one thing people think a simple #pragma tabsize 0 will fix.

You need to understand that #pragma tabsize 0 only stops the exception from popping up every time you compile the script - this does not fix your problem.
Reply
#2

bruh nice tutorial
Reply
#3

Quote:
Originally Posted by JacobEdwards
Посмотреть сообщение
bruh nice tutorial
It's nowhere near finished, but thanks!
Reply
#4

Going good so far, you might want to go into depth about having string that may require a name such as (Adding the length of the Name (MAX: with MAX_PLAYER_NAME, plus the rest of the memory needed for the string and so on).

pawn Код:
new string[42+MAX_PLAYER_NAME];
format(string,sizeof(string), "Welcome to the server %s, have a good time", "Smity");
Reply
#5

Updated.
Reply
#6

+rep , nice work , keep it up newbies needja
Reply
#7

Quote:
Originally Posted by ItzRbj
Посмотреть сообщение
+rep , nice work , keep it up newbies needja
Thanks man!
Reply
#8

pawn Код:
SendClientMessage(playerid, -1, "Type "TYPE_1" and Type "TYPE_2""); // Will output "Type 1 and Type 2
Are you sure this works as the definitions aren't strings?
Reply
#9

https://sampforum.blast.hk/showthread.php?tid=55261

https://sampforum.blast.hk/showthread.php?tid=166680
Reply
#10

Quote:
Originally Posted by kvann
Посмотреть сообщение
pawn Код:
SendClientMessage(playerid, -1, "Type "TYPE_1" and Type "TYPE_2""); // Will output "Type 1 and Type 2
Are you sure this works as the definitions aren't strings?
I'll test it just now

Edit: Just found out that doesn't work, thanks for informing me of that!
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)