例如,人们如何让模组在游戏中发挥作用?我所说的 mods 是指对最终可执行文件的添加。
如果我要制作游戏(使用编译语言),我是否可以允许自己或其他人在无需创建某种脚本语言的情况下对其进行添加。
我的想法:(这行得通吗?)
通常您会向模组编写者公开您的一些应用程序(游戏?)内部接口和对象。mod 编写器将构建一个 dll,它使用这些对象和接口来做一些有用的事情。然后应用程序将动态加载 mod dll 并在必要时调用 mod 实现。
另一种思考方式是,假设您的游戏是一个操作系统(Windows),而您的 mod 是一个应用程序(Word)。操作系统提供了一些 API 来创建和管理窗口,应用程序在必要时使用它们。
因此,作为游戏开发者,您可以创建和分发以下界面:
//mod.h
class Mod {
//takes suggested damage as an arg and returns modified damage
virtual int takeDamage(int damage);
};
Run Code Online (Sandbox Code Playgroud)
并指导用户提供导出函数来实例化和删除mod对象。
实施它:
//godmod.h
class GodMod : public Mod {
int takeDamage(int damage) { return 0; } // god mode!!
}
__declspec(dllexport) Mod *create_mod() { return new GodMode(); }
__declspec(dllexport) void delete_mod(Mod *mod) { delete mod; }
Run Code Online (Sandbox Code Playgroud)
然后你将不得不加载 dll(LoadLibraryWindows 上的 API)、导出create_mod和delete_mod带有GetProcAddressAPI 的符号。之后在游戏中的某个地方,您将使用 实例化 mod create_mod,并在需要的地方使用它:
int damage = 100; //original damage
for (int i = 0; i < mods_count; i++) {
damage = mods[i]->tageDamage(damage);
}
decrease_health(damage);
Run Code Online (Sandbox Code Playgroud)
毕竟,您必须delete_mod从相应的 dll 中释放 mod 。
如果不实现脚本语言,它的工作方式与您所描述的方式类似。Windows 有一个称为动态链接库 (DLL) 的东西,Linux 有一个类似的概念,称为共享对象 (SO)。
在任一操作系统上的程序中,程序都可以动态(通过在某个目录中查找文件或通过配置文件)加载这些文件。这些文件像普通程序一样包含可执行代码,只要程序知道函数的名称,加载它们的程序就可以调用其中的函数。
您可以对函数的名称进行硬编码,或者将它们放入配置文件中,或者创建一个硬编码的函数名称,该名称返回要加载的其他函数的名称或指向函数本身的指针。
这种方法很常见。这就是 mysql 通过从特定目录加载共享库并调用“LOAD PLUGIN”命令中提供的函数来允许用户定义函数和索引的方式。
虽然这在理论上是可行的,但这并不是通常的做法。
Mod 通常不作为本机代码实现。Mod 友好的游戏通常使用数据驱动的方法,并提供一些脚本语言和配置手段,然后用于实现 Mod 的自定义功能。
除其他外,采用这种方法的原因还有:
如果您不想创建自己的脚本语言,使用一些现成的(LUA 在游戏中非常流行)相对容易。