• 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Pawn] YSI Daily Tips
2021-11-17: Unsafe YSI.

YSI does a lot of checks and work at mode start to ensure many things, including:

  • All callbacks work.

  • The correct mode type is determined (FS/GM).

  • JIT and crashdetect plugins are handled well.

  • Mode information is available when asking for help in forums/discord.

  • Run-time generated code can be debugged.

  • Client types are determined.

  • Latest versions are checked.

  • Reasons for slow startup (the things just mentioned) are well documented.

  • And more...

This produces a slower startup (with good reason) and a lot of output (also with good reason, it

helps immensely with helping people).? However, some people do not like these steps and frequently

complain about them.? Previously different steps could be disabled with commands like


#define YSI_NO_OPTIMISATION_MESSAGE, but these were poorly documented,

often missing new features that people wanted to remove, and just plastered across the top of a mode

with no thought or understanding as to why they were there in the first place (the obnoxious header

was just for fun).

So instead, I've added a new way to disable these checks and features; which involves signing a mini

"contract" in defines to state that you accept full responsibility for all errors/bugs/crashes

arising from disabling these checks.? This contract is only for people who actually know what

they're doing, and I'm not even going to put it here as a "just use this magic code" solution.? I'll

also probably randomly change it in subtle ways periodically so you need to keep it updated with YSI

changes.? Including it in a mode and releasing that will only go badly for anyone using that mode.

The change is called ENABLE_YSI_UNSAFE_STARTUP, and defining it along with its contract makes the following changes:

  • All startup messages are disabled, except for one single line to say this mode is in

  • callbackfix.amx is not loaded as a filterscript, so you need to manually ensure that OnRconCommand and OnClientCheckResponse work for your mode.

  • OnScriptInit is simplified, #define FILTERSCRIPT is again required for filterscripts.

  • y_master cloud mode is removed, you must specify one of the single-behaviour y_master modes.

  • Disable scriptfiles YSI folder checks, just assumes they are correct.

  • Ignores old (default) compiler compatibility. It might work, it might not...

  • Slow function crashdetect messages are re-enabled on startup.

2021-11-19: What Is YSI_SetTimerEx?

YSI redefines several SA:MP natives internally. For example:


native YSI_HTTP(index, type, const url[], const data[], const callback[]) = HTTP;

native YSI_Format(dest[], size = sizeof (dest), const format[], GLOBAL_TAG_TYPES:...) = format;

native YSI_SendRconCommand(const str[]) = SendRconCommand;

Why? What's wrong with the originals? Simple - they're sometimes wrong. The updated (community) compiler is const-correct, which means that passing a constant such as a string literal to a parameter that might be modified is a compile-time warning. This is a very good thing that should be enabled, but does cause some issues with people using the default includes (because they are not const-correct). One solution to this is fixes.inc, which correctly redefines the natives to be const-correct; another solution is the samp-stdlib updated includes which do the same thing (amongst other updates).

However, YSI can work with the old or new compiler, and with or without fixes.inc and samp-stdlib, so it needs to always work regardless of the combination of other includes involved. Code that is not const-correct might give warnings on the new compiler (for obvious reasons), but code that is not const-correct might (counter-intuitively) give errors on the old compiler. For example:


stock MyFunction(const function[])


____return SetTimer(function, 1000, false);


Will give an error on the old compiler as function is const, but shouldn't be for SetTimer.

Hence, YSI bypasses this problem entirely and declares its own const-correct versions of a few select functions that it needs. Doing so happens only sparingly as required, because the downside is that this also bypasses hooks; and it breaks if hooks aren't declared with ( as they should be:


#define SetTimer( Hooked_SetTimer(

2022-12-30: YSI YSI YSI

Yonder Scripting Imbeciles,
YSI Snubbing Intentionally;
You're Still Implementing,
Yet Struggling Immensely.

You Should Install:
Y_Less' Server Includes;
You'll See Instantly,
Your Script Improves.

Yes, She's Immense,
Yes Sir, Intense,
Yelling: "Share Information!"
Yields Serenity. Imagine!
2023-01-02: y_groups Permissions

There are three permission types in y_groups - ALLOW, DENY, and UNDEF

The first one, ALLOW, corresponds to true and means people in the group can use the entity in question:


Group_SetClass(group, class, ALLOW);

The last one, UNDEF, corresponds to false and means the group has no setting for the entity. People in this group may or may not be able to use it, determined by other groups. It is also "don't care":


Group_SetClass(group, class, UNDEF);

The second one, DENY, corresponds to cellmin and means people in the group absolutely cannot use the entity in question. If a player is in two groups - one ALLOW and one DENY on the same entity, the DENY will take precedence and stop them using the entity:


Group_SetClass(group, class, DENY);

Ideally DENY would have been false and UNDEF cellmin, but that can't be because of backwards-compatibility.
2023-01-03: Hash Maps

A hash map is similar to an array, but instead of a number to access things it takes a string. YSI has basic hash map support via y_hashmap (note that this is different to y_stringhash, although they do share a basic hash algorithm so both libraries will give the same numeric representation of a string).

The hash map functions convert a string to an array index, which can be subsequently used to access data.

Given the following data you want to add string indexing to:

enum E_MY_DATA


The enum must have a string added, which becomes the name, and some extra data:

enum E_MY_DATA
____// Must come first.
____// Must come second.
____// Normal enum contents.

new HashMap:gHashMap<>;

You can use the name in your own code, the hash map data is an implementation detail.

Initialise the data with the enum offsets:

HashMap_Init(gHashMap, gData, E_DATA_HASH_DATA);

Add an item by name (to enable y_hashmap to translate the given name to the given index):

HashMap_Add(gHashMap, name, id),

This will also set the name in the array at the given index, so you don't need to do that yourself.

Look up an index by name:

new id = HashMap_Get(gHashMap, "name");

You can now use id as in index in to gData.

There are more functions to remove items and get entires in clever ways. See the library for more information.

Forum Jump: