AMX Mod Compatibility Layer (AMX Mod X)

From AlliedModders Wiki
Revision as of 12:36, 8 September 2006 by BAILOPAN (talk | contribs) (some more words)
Jump to: navigation, search

As of 1.76, AMX Mod X has an AMX Mod backward compatibility layer. This layer has two goals. The first goal is API compatibility: AMX Mod plugins should compile without modification and subsequently run normally on AMX Mod X. The second goal is ABI compatibility: AMX Mod plugins should run as raw '.amx' files, without recompilation, on AMX Mod X.

This current status of this side project is experimental. While it will work for most plugins, there may be niches or obscure details yet unresolved.

List of Tested Plugins

The following is a list of plugins the development or beta testing team has verified to be working. (D) denotes a default plugin shipped with AMX Mod.

  • Dev Tested
    • admin (D)
    • admin SQL (D)
    • hackmod
    • sentryguns
    • shoot_at_nades
    • ultimate_c4


Makeshift Tracker

  • VexdUM Port
    • Natives
      • Engine's entity_[g|s]_*() natives should no longer bail out if the player is not ingame.
      • radius_damage replacement (NOTE
      • traceresult and its related natives
      • get/set offset functions
      • TODO: Port the TFC natives.
    • Forwards
      • All done but monster_hurt.
  • MySQL Port
    • Entirely done.
  • Fun Port
    • Unknown
  • Core Port
    • Translator functionality nearly complete. Helper functions not done yet.
    • Added detection for AMX Mod's localinfo keys.
    • Math functions ported.


Userland Information

Language Files

AMX Mod language files, if needed, can be used. They are marshalled by the bcompat plugin and it must be loaded. Simply place the files in amxmodx/data/amxmod-lang/. You do not need to modify or rename them.

localinfo/core.ini

Localinfo support is marshalled by core. If you have copied your core.ini from AMX Mod, you will want to change the paths to match your AMX Mod X installation.


Technical/Coding Details

The AMX Mod compatibility layer (codenamed 'bcompat') is largely done through a plugin called amxmod_bcompat. Our wa to keep C++ editing to a minimum. Unfortunately, there are a few limited things that could only be done in C++. However, keeping the majority of code in a plugin reduces the amount of work ordinary plugin developers need to add features or fix problems. It also makes it easy to centralize the system rather than adding spidery code across modules.

Internal Compatibility (Core)

Core adds specific backwards compatibility for plugins detected as AMX Mod plugins. It has two methods of detection. On detection, the plugin is flagged with AMX_FLAG_OLDFILE.

  • Any plugin being loaded with a '.amx' extension is flagged as a bcompat plugin. Although this extension was used with AMX Mod X 0.16, the core version was similar enough to AMX Mod 0.9.7 that the time gap should be about the same.
  • Plugins recompiled while including 'amxmod.inc' automatically get a special identifier added to their public variable table. Core identifies any plugin carrying this identifier and flags it as a bcompat plugin.

Plugins flagged as bcompat act almost entirely the same. The two major differences are in which natives they are allowed to use and how they format strings.

Translator

AMX Mod's translator can be broken into two pieces. The first is the file format, which must be loaded and added to a database. The second is the actual translation API itself and how plugins use it.

File Format

The file format is completely loaded and parsed by the bcompat plugin. The translation key pairs are added to the internal AMX Mod X storage engine through the CreateLangKey() and AddTranslation() natives. As noted earlier, the files are loaded from amxx_datadir/amxmod-lang/.

Backend Translation

The backend is provided through Core. The _T() stock remains and the translate() is provided to all plugins (whether having AMX_FLAG_OLDFILE or not). The translate native takes in the translation info and creates a unique translation identifier returned to the plugin for use with the '%s' format specifier. If the get_amxstring(), get_amxstring_r(), or format() routines are used from a flagged plugin, and one of these unique identifiers is used for '%s', the translation identifier is freed and the translation performed.

This implementation allows for up to 1,024 translation identifiers to be in the translation pool at once. If for some reason a translation fails to pop off the internal stack, for example:

   format(buffer, sizeof(buffer)-1, "%s %d %s %s", _T(...), b(), _T(...), _T(...))

If b() fails, the first translation passed will "leak." These leaked identifiers are freed on mapchange (and only take up about 12 bytes), but if a continuous flaw exists in a plugin, the translation pool will be filled and future translations will fail. This may or may not be addressed in a future release.