First PAPER consumer
This minimal pattern reads runtime state on coherent FrameComplete events.
#include "PAPERApi.h"
#include <cstdio>
using namespace paper::api;
std::uint64_t ownerToken{};
std::uint64_t callbackToken{};
void PAPER_CALL onPaperEvent(const PaperEventV1* eventData, void*)
{
if (!eventData || eventData->kind != PaperEventKindV1::FrameComplete) {
return;
}
// eventData->runtime is already a value-only coherent snapshot.
}
bool connectPaper()
{
if (PaperApi::initialize(
PAPER_API_VERSION,
PAPER_PROVIDER_API_V1_BASE_TABLE_BYTES) != 0 ||
!PaperApi::inst || !PaperApi::inst->isReady()) {
return false;
}
PaperConsumerRegistrationV1 registration{};
std::snprintf(registration.modName, sizeof(registration.modName), "MyPlugin");
registration.requestedCapabilities =
static_cast<std::uint32_t>(PaperConsumerCapabilityV1::RuntimeState) |
static_cast<std::uint32_t>(PaperConsumerCapabilityV1::FrameCallbacks);
PaperConsumerHandleV1 handle{};
if (PaperApi::inst->registerConsumerV1(®istration, &handle) !=
PaperResultV1::Ok ||
handle.ownerToken == 0 ||
(handle.grantedCapabilities & registration.requestedCapabilities) !=
registration.requestedCapabilities) {
return false;
}
ownerToken = handle.ownerToken;
if (PaperApi::inst->registerEventCallbackV1(
ownerToken, &onPaperEvent, nullptr, &callbackToken) !=
PaperResultV1::Ok ||
callbackToken == 0) {
PaperApi::inst->unregisterConsumerV1(ownerToken);
ownerToken = 0;
return false;
}
return true;
}
void disconnectPaper()
{
if (!PaperApi::inst || ownerToken == 0) {
return;
}
if (callbackToken != 0) {
PaperApi::inst->unregisterEventCallbackV1(ownerToken, callbackToken);
callbackToken = 0;
}
PaperApi::inst->unregisterConsumerV1(ownerToken);
ownerToken = 0;
}
Connect after game data is available and disconnect before load transitions or plugin teardown. All calls shown above are game-thread-only.
Initialization codes
| Code | Meaning |
|---|---|
| 0 | Descriptor or base legacy discovery succeeded. |
| 1 | PAPER.dll is absent, or this is not Windows. |
| 2 | Legacy export absent. |
| 3 | Legacy export returned null. |
| 4 | Provider API older than requested. |
| 5 | Invalid/short descriptor, or appended extent requested from a legacy-only provider. |