Quantcast

Jump to content

» «
Photo

Generic SA SCM Documentation

127 replies to this topic
Seemann
  • Seemann

    Ruhe

  • GTA Mods Staff
  • Joined: 03 Sep 2004
  • Russia
  • Best Tool 2013 "Sanny Builder"
    Contribution Award [Mods]
    Helpfulness Awards [Mods]

#121

Posted 04 October 2015 - 02:42 PM

We could implement a system similar to the objects segment in the scm format. The compiler builds a lookup table for each script command used and compiles a script with relative indices in that table rather than actual opcodes. Consider this example:

We have a simple code
WAIT 500
ADD_SCORE player 100
WAIT 250
END_CUSTOM_SCRIPT
it would compile to
1: 500
2: 0 100
1: 250
3:
with the following lookup table (pseudo code):
1=wait
2=add_score
3=end_custom_script
CLEO when initialised knows all the original opcodes under their names+numbers (wait is 0001, jump is 0002, etc) and all the custom handlers (.cleo plugins). It reads the lookup table and replaces string names with actual opcodes
1=0001
2=0109
3=0A93
We hook the CRunningScript::Process() and replace an index read from the script with the opcode from the lookup table, so everything works as usual.
So, CLEO plugins must expose custom opcodes with string names instead of indices. And the compiler should be able to read the plugins export before compiling to collect custom opcodes names and number of parameters (if we don't want to manually update the INI).
  • Wesser and fastman92 like this

Wesser
  • Wesser

    The complexity simplifier, the efficiency optimizer.

  • Feroci
  • Joined: 19 Aug 2006
  • Unknown
  • Contribution Award [Mods]

#122

Posted 04 October 2015 - 11:21 PM Edited by Wesser, 05 October 2015 - 06:50 PM.

Yeah, it's more or less what I was trying to explain but I honestly didn't think about used objects (as of R*' denomination).

Modifying the script buffer by overwriting the referenced command numbers would require accessing the lookup table only every time a user-defined command is being used and not when any command is being read by the scripting engine, which can occur multiple times if inside a loop. Nonetheless, even though the way you exposed is slight inefficient it is actually hook-friendly and so recommended: injecting SCM codes into a script featuring new commands would be far less problematic because knowing the table indices would be enough for the hooker, who won't be forced to organize the script such that command numbers get updated manually at runtime.

GTA3script compilers will have no issue to handle the script compilation at each command addition since their definition is what matters. Instead, SB compilers and similar should provide support for script dependent lists (enumerating only the new commands) without the need to touch the standard configuration.

It's too late here, I apologize for my potential superficiality.

 
EDIT: In summary, assuming we would like to take advantage of additional commands, we would have to build a script.lst file holding the new commands list beginning from the last free index, in this human-readable format:
[COMMAND]
0A51=0,command
Consequently, a compiler's directive should include the aforesaid list by replicating $OPCODE behaviour in this manner:
{$NEWOPCODE script.lst}
Its variant can also be enhanced to accomodate the new syntax used for individual command definitions by establishing another directive:
{$NEWOPCODE COMMAND 0A51=0,command}
At compilation stage, the compiler will generate a hypotetical script.no (New Opcodes) file containing only the command string names sorted by the command index which must be progressive before compiling. At startup, CLEO will collect the POC (ProcessOneCommand) of each new command in the order they are registered by means of loaded plugins. At script launch, if the associated .no file is present, CLEO will generate a context dependent lookup table by swapping string names with indices and give the task to select the belonging list of the processed command to CRunningScript::ProcessOneCommand, as the following pseudocode demonstrates:
class CRunningScript
{
    struct CommandID
    {
        short m_sIndex : 7;
        short m_bNotFlag : 1;
    };

    ...
    short *m_pNewCommandsAssoc;

    ...
    void ProcessOneCommand(void);
};

...

void CRunningScript::ProcessOneCommand(void)
{
    ...
    CommandID commandID;
    short sCommandIndex;
    ...

    do
    {
        ...
        sCommandIndex = commandID.m_sIndex;
    }
    while((m_pNewCommandsAssoc && sCommandIndex > 2640
         ? g_aNewCommandsArray[m_pNewCommandsAssoc[sCommandIndex - 2641]]
         : g_aCommandsPOCArray[sCommandIndex / 100])(sCommandIndex));

    ...
}
The neat thing is the compatibility of the scripts which won't avail of the questioned feature will never get lost.
  • fastman92 likes this

LINK/2012
  • LINK/2012

    LIVIN' IN CODE

  • Feroci
  • Joined: 30 Jan 2011
  • Brazil
  • Best Tool 2014 [Mod Loader]
    Contribution Award [Mods]

#123

Posted 3 weeks ago Edited by LINK/2012, 3 weeks ago.

So, I've been working on a GTA3script compiler for a few months now and would certainly like to implement something along the lines of what has been discussed here.
 
In fact, I've formalized things a bit up, and would like to listen to divergences, alternatives and suggestions.

So far I have collected lots of insights from Wesser, NTAuthority and Silent. So, the work in those drafts aren't mine by any means, instead they're supposed to be a collection of whatever the community ends up agreeing upon.
 
Although the features above are the most important ones, there are a few other extensions to the language which I would like to see discussed as well:

  • REQUIRE
  • DEFINE
  • The addition of hexadecimal integer literals.
  • The additional of a semantic (perhaps a command) for a similar purposes as the Sanny Builder's HEX...END blocks.
  • Relaxing REPEAT to allow variables in the times argument.
  • The addition of ELSEIF to complement IF.

And to conclude, a little script to sum things up a bit :)

  • Seemann, Jestic, Wesser and 5 others like this

fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • Poland
  • Contribution Award [Mods]

#124

Posted 3 weeks ago Edited by fastman92, 3 weeks ago.

Contact me and I can tell you something about the GTA LCS and VCS SCM. For which I have made a simple compiler.
  • Jestic and dkluin like this

goodidea82
  • goodidea82

    SA Modder

  • Members
  • Joined: 13 Jun 2013
  • Germany

#125

Posted 2 weeks ago Edited by goodidea82, 2 weeks ago.

"Adding custom commands is always carefully considered as it costs a 15-bit command id. And, since command ids are essentially progressive numbers, the risk of collisions is quite high, if not unavoidable."

Do I understand correctly, if I implement a custom opcode with a new unused ID using the cleo library (in a so-called cleo plugin with .cleo extension), then eventually there will be a hash collision and a different opcode will be called instead?

(Background: I have code that generates opcode implementations for new opcodes in the ID range 1000-1FFF and negated versions in the range 9000-9FFF)

 

Suggestion about the code example. Using upper case letters will get very tedious. It would be better to use lower case letter for keywords and known names and let a syntax-aware editor do the visual appealing.


LINK/2012
  • LINK/2012

    LIVIN' IN CODE

  • Feroci
  • Joined: 30 Jan 2011
  • Brazil
  • Best Tool 2014 [Mod Loader]
    Contribution Award [Mods]

#126

Posted 2 weeks ago Edited by LINK/2012, 2 weeks ago.

"Adding custom commands is always carefully considered as it costs a 15-bit command id. And, since command ids are essentially progressive numbers, the risk of collisions is quite high, if not unavoidable."
Do I understand correctly, if I implement a custom opcode with a new unused ID using the cleo library (in a so-called cleo plugin with .cleo extension), then eventually there will be a hash collision and a different opcode will be called instead?
(Background: I have code that generates opcode implementations for new opcodes in the ID range 1000-1FFF and negated versions in the range 9000-9FFF)

You misunderstood it, yes. Command ids are what we currently call opcodes. What I meant is the opcode range 0000-7FFF is too small. Not only that, the way we register opcodes at the moment can very easily make two people to pick the same opcode ids as humans are not good at randomness.

 

Suggestion about the code example. Using upper case letters will get very tedious. It would be better to use lower case letter for keywords and known names and let a syntax-aware editor do the visual appealing.

That's Rockstar Vision :p. Everything is case-insensitive, but a conventional coding style can be observed from R* sources: commands and constants in uppercase and variables in lowercase. See here if you wanna learn further.


goodidea82
  • goodidea82

    SA Modder

  • Members
  • Joined: 13 Jun 2013
  • Germany

#127

Posted 2 weeks ago Edited by goodidea82, 2 weeks ago.

I guess there is still some confusion what we're talking about. "Do I understand correctly" - "You misunderstood it, yes" ?

You mean "...the risk of collisions---with IDs defined by different people---is quite high,.."? Here two people have used the same command ID for defining their custom opcode.

 

Or, you mean that if I define opcode 1ABC, then a hash is created in the SCM engine (let say 123456) and it has a collision with another opcode, e.g., 2ABC (same hash: 123456). When I call 1ABC, then actually 2ABC will be called because the hashes collide?


LINK/2012
  • LINK/2012

    LIVIN' IN CODE

  • Feroci
  • Joined: 30 Jan 2011
  • Brazil
  • Best Tool 2014 [Mod Loader]
    Contribution Award [Mods]

#128

Posted 2 weeks ago

No hashes are involved in the current script engine, just command ids (0000 for NOP, 0001 for WAIT, 0002 for SHAKE_CAM...). Indeed, I'm not talking about hash collisions there, perhaps a better term could be used to avoid confusion.

 

The collision I meant is with the opcode number itself, like you register 2ABC and another plugin also registers 2ABC.

  • goodidea82 likes this




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users