/* game_mod_abi.h * * The contract between the engine and a player-built dynamic library. * * This header is included BOTH by the engine (to read the result) and is * emitted verbatim into the user's generated source (so their game_build() * agrees on the struct layout). Keep it pure C — no C++ — so the layout is * stable across the dlopen boundary regardless of how either side is built. * * IMPORTANT (security): the engine compiles and dlopen()s code the player * typed on the editor wall. This is acceptable ONLY because it is a local, * single-player sandbox where the player can affect nothing but their own * process. Never feed untrusted or networked input through this path. */ #ifndef GAME_MOD_ABI_H #define GAME_MOD_ABI_H #ifdef __cplusplus extern "C" { #endif typedef enum { DYN_TEXT = 0, DYN_BOX = 1 } DynObjKind; /* A flat, POD description of one object to spawn. No pointers, no C++: * the library fills these in, the engine constructs the real Text::Token::Data / * SolidBox from them. Nothing the library allocates outlives dlclose(). */ typedef struct { int kind; /* DynObjKind */ int dynamic; double x, y, z; /* world position (centre) */ double hx, hy, hz; /* half-extents — BOX only; ignored for TEXT */ float r, g, b; /* colour 0..1 */ char text[64]; /* TEXT only, null-terminated; ignored for BOX */ } DynObject; /* The user's compiled library MUST export this symbol. * Fills `out` (capacity `max` entries) and returns the number written. * Returning more than `max` is undefined; the engine passes a generous max. */ int game_build(DynObject* out, int max); #ifdef __cplusplus } #endif #endif /* GAME_MOD_ABI_H */