04 · First plugin

Your first Shroudtopia mod

Every mod implements Mod and exports a factory named CreateModInstance. This small example logs lifecycle events and reads a boolean setting. It avoids game-memory writes so you can learn the integration contract first.

#include <windows.h>
#include <string>
#include <vector>
#include <shroudtopia.h>

class ExampleMod final : public Mod {
public:
    ModMetaData GetMetaData() override {
        return {"example_mod", "Lifecycle and config example", "1.0.0",
                "Your name", "0.1.1", true, false};
    }

    void Load(ModContext* context) override {
        context->Log("[example_mod] loaded");
    }

    void Activate(ModContext* context) override {
        active = true;
        context->Log("[example_mod] active");
    }

    void Deactivate(ModContext* context) override {
        active = false;
        context->Log("[example_mod] inactive");
    }

    void Update(ModContext* context) override {
        const bool showNotice = context->config.GetBool(
            "example_mod", "show_notice", true);
        // Read settings here; avoid repeating expensive work every update.
        (void)showNotice;
    }

    void Unload(ModContext* context) override {
        Deactivate(context);
        context->Log("[example_mod] unloaded");
    }
};

extern "C" __declspec(dllexport)
Mod* CreateModInstance() {
    return new ExampleMod();
}

Build a 64-bit DLL. Name it example_mod.dll to match the manifest ID. Put both files in mods/example_mod/. Set active to false until you have checked the code path and target environment.

Factory name is an ABI contract. Keep the exact exported C symbol. Do not rename it or expose a C++-mangled factory in place of it.
10 · Example gallery

Learn from preview mods

These examples show how individual DLLs use the framework. They are source walkthroughs, not promises that all mods work on every game build or mode. Read the linked per-mod notes before adapting behavior.

Flight Mod gameplay preview
Flight Mod · client exampleF6 toggle, config-driven key, status feedback, and a guarded client layout. Current example supports a specific Steam client data revision and explicitly does not claim dedicated-server flight. Source and compatibility notes ↗
First Person View gameplay preview
First Person View · client exampleCamera-distance setting, signature-checked camera hook, cleanup, and optional stamina HUD placement. Its README documents the tested client layout and limits. Source and compatibility notes ↗

Basics

Legacy mod collection; useful for reading older scan-and-patch patterns. Its signatures and target notes are historical. Do not copy blindly.

Browse source ↗

Whitelist

Server-oriented example using a uint64 ID list. Its current source contains legacy signatures; verify before use and do not infer server acceptance from metadata alone.

Browse source ↗

Start with a no-op

Implement metadata, lifecycle logs, and config access first. Add game interaction only after your own guarded test path exists.

Open skeleton ↗
11 · Developer workflow

Build, test, and package

Build environment

Use Visual Studio 2022 C++ tools, Windows SDK, x64, and MSVC v143 for the maintained examples. Match runtime and architecture to the loader and game process. Keep build artifacts out of the installed game until your isolated test setup is ready.

Test in layers

  1. Compile checks: build with warnings visible and verify exported symbol using your normal PE inspection tooling.
  2. Offline tests: test byte matching, version guards, cleanup, and config validation with synthetic inputs where possible.
  3. Loader integration: test discovery, manifest defaults, ID/name matching, client/server flags, and disabled-by-default behavior.
  4. Isolated gameplay: test only on a backed-up, disposable client or server setup. Confirm activation, deactivation, cleanup, and unsupported-version fallback.
  5. Publish honestly: report the exact game build, mode, test scope, and unverified combinations. Link source and retain upstream credit.
Never test an unknown native patch on a valuable save or live server. Keep backups outside the game directory. Framework support flags and successful DLL loading do not prove safe gameplay.
↑ Top