Panduan Bahasa
Sintaks, deklarasi, alur kontrol, dan data.
Deklarasi
File .sa berisi konfigurasi, callback, fungsi bantu, dan variabel.
system::config() { ... }; // server.cfg
player::connect(int playerid) { }; // callback
function add(int a, int b) { return a + b; };
let total = 0; // variabel
; di akhir blok callback, function, atau config wajib ada.Variabel
let hp = 100; // int
let speed = 1.5; // float
let name = "CJ"; // string
let online = true; // bool
hp = 90; // reassign
hp += 5; // compound: += -= *= /= %=
Operator
| Operator | Arti |
|---|---|
+ - * / % | Aritmetika; + juga menggabung string |
== != ~= | Kesetaraan (~= alias !=) |
< <= > >= | Perbandingan |
and or not | Logika; juga &&, ||, ! |
+= -= *= /= %= | Assignment gabungan |
& | ^ ~ << >> | Bitwise dan/atau/xor/not, shift |
Alur kontrol
player::command("/rank", int score) {
if (score >= 100) {
SendClientMessage(playerid, "Veteran");
} else if (score >= 50) {
SendClientMessage(playerid, "Reguler");
} else {
SendClientMessage(playerid, "Pemula");
}
};
Loop
Semua bentuk loop umum tersedia. break keluar dari loop atau switch terdekat; continue lompat ke iterasi berikutnya.
// while
let i = 0;
while (i < 10) {
i += 1;
}
// do / while: minimal sekali jalan
do {
i -= 1;
} while (i > 0);
// for gaya C
for (let n = 0; n < 5; n += 1) {
if (n == 3) { break; }
}
// iterasi array
let names = ["amy", "bob", "cid"];
for (let name in names) {
SendClientMessage(playerid, "Hai {name}");
}
// iterasi array + indeks
for (let index, name in names) {
SendClientMessage(playerid, "{index}: {name}");
}
// iterasi map (kunci urut)
let scores = { "amy": 10, "bob": 20 };
for (let key in scores) {
SendClientMessage(playerid, "{key} = {scores[key]}");
}
// lewati sebagian iterasi
for (let n = 0; n < 20; n += 1) {
if (n % 2 == 0) { continue; }
if (n > 15) { break; }
}
switch
switch membandingkan satu nilai dengan label case. Tidak ada fall-through: cabang pertama yang cocok dijalankan lalu switch selesai, jadi tidak perlu break di akhir cabang.
player::command("/class", int id) {
switch (id) {
case 0:
SendClientMessage(playerid, "Medis");
case 1:
SendClientMessage(playerid, "Polisi");
default:
SendClientMessage(playerid, "Warga");
}
};
Array dan map
let scores = [10, 20, 30];
let player = { "name": "CJ", "score": 0 };
scores[0] = 15;
player["score"] = 42;
let first = scores[0];
let n = len(scores);
push(scores, 40); // ubah langsung: [10, 20, 30, 40]
let last = pop(scores); // 40, scores kini [10, 20, 30]
let part = scores[1:3]; // [20, 30]
let sorted = sort([3, 1, 2]); // [1, 2, 3]
Literal
let hex = 0xFF00FF00; // int hex
let wait = 500ms; // durasi -> milidetik
let pos = [1.0, 2.0, 3.0];
let meta = { "hp": 100 };
Komentar dan include
// komentar baris
/* komentar blok
beberapa baris */
Include diselesaikan relatif terhadap file yang menyertakan. Include melingkar ditolak dengan error.
Fungsi
Gunakan function untuk mendefinisikan helper yang bisa dipakai ulang. Fungsi juga bisa dipanggil berdasarkan nama dari timer dan callback database.
function clampHealth(float value) {
if (value < 0.0) { return 0.0; }
if (value > 100.0) { return 100.0; }
return value;
}
player::spawn(int playerid) {
SetPlayerHealth(playerid, clampHealth(150.0));
};
Parameter: tipe, default, dan rest
Parameter fungsi bertipe dan dicek saat kompilasi. Parameter di belakang boleh punya nilai default, dan parameter terakhir ...rest menampung argumen sisa menjadi array.
function spawnAt(Player target, float x, float y, float z = 3.0) { ... }
function total(int first, ...rest) {
let sum = first;
for (let n in rest) { sum += n; }
return sum;
}
spawnAt(playerid, 100.0, 200.0); // z default 3.0
total(1, 2, 3, 4); // 10
Konstanta
const MAX_HP = 100;
const RATIO: float = 0.5;
function cap(float hp) { return hp > MAX_HP ? MAX_HP : hp; }
Assignment ke const ditolak saat kompilasi.
Memanggil fungsi berdasarkan nama
CallRemoteFunction(nama, ...args) dan aliasnya CallLocalFunction memanggil function level atas berdasarkan namanya. Berguna saat fungsi dipilih saat runtime, dan membuat kode Pawn mudah diporting.
function add(int a, int b) { return a + b; }
function isBig(int n) { return n > 10; }
let sum = CallRemoteFunction("add", 2, 3); // 5
let big = CallLocalFunction("isBig", 50); // 1
let x = CallRemoteFunction("missing"); // 0 (dicatat di log)
Hasilnya selalu int, seperti Pawn: angka dipotong, true/false menjadi 1/0, string menghasilkan panjangnya, handle objek menghasilkan id-nya, dan null menghasilkan 0. Nama yang tidak ada menulis peringatan ke log dan mengembalikan 0.
Scope
Variabel di level modul dipakai bersama semua callback sepanjang umur server. Variabel di dalam blok hanya ada di sana.
let total = 0; // scope modul
player::connect(int playerid) {
let local = 5; // scope callback
total = total + local; // variabel modul bisa diubah
};
Keamanan loop
Loop dibatasi. Satu callback, command, atau timer maksimal menjalankan 10 juta iterasi; melewatinya menghentikan callback dengan pesan loop iteration limit exceeded dan server tetap responsif, jadi satu baris bermasalah tidak bisa membekukan server.
Truthiness
| Nilai | Truthy? |
|---|---|
true / angka bukan nol | ya |
false / 0 / 0.0 | tidak |
| string tidak kosong | ya |
string kosong "" | tidak |
null | tidak |
| array / map tidak kosong | ya |
Prioritas operator
Dari tertinggi ke terendah:
| Level | Operator |
|---|---|
| 1 | ! not - + ~ (unary) |
| 2 | * / % |
| 3 | + - |
| 4 | << >> |
| 5 | < <= > >= |
| 6 | == != ~= |
| 7 | & |
| 8 | ^ |
| 9 | | |
| 10 | and && |
| 11 | or || |
| 12 | ? : (ternary) |
Gunakan tanda kurung bila maksudnya tidak jelas.
Keyword
| Keyword | Arti |
|---|---|
let | Deklarasi variabel |
if / else | Kondisional |
return | Kembali dari fungsi atau callback |
function | Deklarasi fungsi helper |
true / false | Literal boolean |
null | Tidak ada nilai |
and / or / not | Operator logika |
while / do / for | Loop |
in | Iterasi range pada for |
break / continue | Kontrol loop |
switch / case / default | Percabangan banyak (tanpa fall-through) |
Yang sengaja tidak ada
- Tidak ada class, inheritance, atau method — hanya callback dan fungsi.
- Tidak ada
selfatau namespace pada native — panggil dengan namanya. - Tidak ada
goto, label, atau fall-throughswitchgaya C. - Tidak ada keyword
foreach— gunakanfor (let x in arr).