Discovery and capabilities
ROCK uses four separate checks because they answer different questions:
| Check | Question answered |
|---|---|
| API version | Does the provider speak the V1 contract family? |
| Table extent | Does this particular function-pointer slot physically exist? |
| Feature bit | Does the provider claim the behavior behind that slot? |
| Capability grant | May this registered consumer use that owned/read surface? |
A safe consumer passes all applicable checks. None of them is a substitute for the others.
Descriptor-first negotiation
New consumers should use RockProviderApi::initialize(version, bytes). The
helper looks for ROCKAPI_GetDescriptorV1 first. The immutable descriptor owns:
apiVersion— currently1;tableByteSize— the exact x64 function-table extent;featureBitsandfeatureBits2— both discovery words;table— the process-lifetime function-table pointer.
If you require a non-zero extent, initialize will not use the unsafe legacy
fallback when the descriptor is absent. This is deliberate: a legacy V1 table
can be valid yet shorter than the header your plugin compiled against.
using namespace rock::provider;
bool connectForScopedContacts()
{
const int result = RockProviderApi::initialize(
ROCK_PROVIDER_API_VERSION,
ROCK_PROVIDER_API_V1_EXTERNAL_BODY_SCOPES_TABLE_BYTES);
return result == 0 &&
RockProviderApi::inst != nullptr &&
supportsExternalBodyScopesV1();
}
Table-byte constants
Use the constant for the furthest slot your feature may call. Requiring a later constant also covers all earlier slots because the table is append-only.
| Family | Constant | Required bytes |
|---|---|---|
| Force grab | ROCK_PROVIDER_API_V1_FORCE_GRAB_TABLE_BYTES | 200 |
| Force release | ROCK_PROVIDER_API_V1_FORCE_RELEASE_TABLE_BYTES | 208 |
| Thrown drop | ROCK_PROVIDER_API_V1_THROWN_DROP_TABLE_BYTES | 216 |
| Hand input suppression | ROCK_PROVIDER_API_V1_HAND_INPUT_SUPPRESSION_TABLE_BYTES | 232 |
| Weapon-part interaction | ROCK_PROVIDER_API_V1_WEAPON_PART_INTERACTION_TABLE_BYTES | 264 |
| Weapon classification | ROCK_PROVIDER_API_V1_WEAPON_CLASSIFICATION_TABLE_BYTES | 272 |
| Weapon-part grip state | ROCK_PROVIDER_API_V1_WEAPON_PART_GRIP_STATE_TABLE_BYTES | 280 |
| Raw wand buttons | ROCK_PROVIDER_API_V1_RAW_WAND_BUTTON_STATE_TABLE_BYTES | 288 |
| Pip-Boy suppression state | ROCK_PROVIDER_API_V1_PIPBOY_INPUT_SUPPRESSION_TABLE_BYTES | 296 |
| Weapon emitters | ROCK_PROVIDER_API_V1_WEAPON_EMITTERS_TABLE_BYTES | 312 |
| Native animation authority | ROCK_PROVIDER_API_V1_NATIVE_ANIMATION_AUTHORITY_TABLE_BYTES | 336 |
| Animation phases | ROCK_PROVIDER_API_V1_ANIMATION_PHASES_TABLE_BYTES | 352 |
| Equipped grip state | ROCK_PROVIDER_API_V1_EQUIPPED_WEAPON_GRIP_STATE_TABLE_BYTES | 360 |
| Hand visual authority | ROCK_PROVIDER_API_V1_HAND_VISUAL_AUTHORITY_TABLE_BYTES | 376 |
| Native animation runtime provider | ROCK_PROVIDER_API_V1_NATIVE_ANIMATION_RUNTIME_PROVIDER_TABLE_BYTES | 384 |
| Equipped weapon handling | ROCK_PROVIDER_API_V1_EQUIPPED_WEAPON_HANDLING_AUTHORITY_TABLE_BYTES | 408 |
| Debug overlay publication | ROCK_PROVIDER_API_V1_DEBUG_OVERLAY_PUBLICATION_TABLE_BYTES | 424 |
| Presented hand frames | ROCK_PROVIDER_API_V1_PRESENTED_HAND_FRAMES_TABLE_BYTES | 432 |
| Extended limits and sizes | ROCK_PROVIDER_API_V1_EXTENDED_LIMITS_TABLE_BYTES | 448 |
| Owner frame callbacks | ROCK_PROVIDER_API_V1_OWNER_FRAME_CALLBACKS_TABLE_BYTES | 464 |
| Hand interaction state | ROCK_PROVIDER_API_V1_HAND_INTERACTION_STATE_TABLE_BYTES | 472 |
| Provider events | ROCK_PROVIDER_API_V1_PROVIDER_EVENTS_TABLE_BYTES | 480 |
| Equipped weapon state | ROCK_PROVIDER_API_V1_EQUIPPED_WEAPON_STATE_TABLE_BYTES | 488 |
| External scopes/contact cursor | ROCK_PROVIDER_API_V1_EXTERNAL_BODY_SCOPES_TABLE_BYTES | 512 |
| Weapon-part observability | ROCK_PROVIDER_API_V1_WEAPON_PART_OBSERVABILITY_TABLE_BYTES | 536 |
| Scope/sight state | ROCK_PROVIDER_API_V1_SCOPE_SIGHT_STATE_TABLE_BYTES | 544 |
| Weapon composition | ROCK_PROVIDER_API_V1_WEAPON_COMPOSITION_TABLE_BYTES | 560 |
| Pose readback | ROCK_PROVIDER_API_V1_POSE_READBACK_TABLE_BYTES | 576 |
| Semantic hand contacts | ROCK_PROVIDER_API_V1_SEMANTIC_HAND_CONTACTS_TABLE_BYTES | 584 |
| Player collider data | ROCK_PROVIDER_API_V1_PLAYER_COLLIDERS_TABLE_BYTES | 600 |
| Command cancellation | ROCK_PROVIDER_API_V1_COMMAND_CANCELLATION_TABLE_BYTES | 608 |
| Input observability | ROCK_PROVIDER_API_V1_INPUT_OBSERVABILITY_TABLE_BYTES | 616 |
| Offhand reservation leases | ROCK_PROVIDER_API_V1_OFFHAND_RESERVATION_LEASES_TABLE_BYTES | 648 |
| Native runtime clear | ROCK_PROVIDER_API_V1_NATIVE_ANIMATION_RUNTIME_CLEAR_TABLE_BYTES | 656 |
| Touch-grab targets | ROCK_PROVIDER_API_V1_TOUCH_GRAB_TARGETS_TABLE_BYTES | 688 |
| Equipped-weapon hand request | ROCK_PROVIDER_API_V1_EQUIPPED_WEAPON_HAND_REQUEST_TABLE_BYTES | 696 |
| World raycasts | ROCK_PROVIDER_API_V1_WORLD_RAYCASTS_TABLE_BYTES | 704 |
| Collider visualization override / full table | ROCK_PROVIDER_API_V1_COLLIDER_VISUALIZATION_OVERRIDE_TABLE_BYTES | 720 |
The numeric values are useful for diagnostics. In source, always use the named constant so a header update remains self-describing.
Feature helpers
The SDK provides combined table-and-feature predicates. Prefer them to manually testing a bit when one exists:
if (!supportsWeaponPartInteractionV1() ||
!supportsWeaponPartGripStateV1() ||
!supportsWeaponPartObservabilityV1()) {
return false;
}
Primary-word helpers have overloads that accept a cached
RockProviderLimitsV1 and overloads that query it for you. Extended-word
helpers read the negotiated descriptor or RockProviderLimitsExtV1.
Available supports… helpers:
- commands:
supportsForceGrabCommandV1,supportsForceReleaseCommandV1,supportsThrownDropCommandV1,supportsCommandCancellationV1; - input:
supportsHandInputSuppressionV1,supportsRawWandButtonStateV1,supportsPipboyInputSuppressionV1,supportsInputObservabilityV1,supportsOffhandReservationLeasesV1,supportsNativeVatsVansInputSuppressionV1; - weapons:
supportsWeaponPartInteractionV1,supportsWeaponPartGripStateV1,supportsWeaponPartRecordIdentityV1,supportsWeaponClassificationV1,supportsWeaponEmittersV1,supportsWeaponPartObservabilityV1,supportsScopeSightStateV1,supportsWeaponCompositionV1; - animation/presentation:
supportsNativeAnimationAuthorityV1,supportsAnimationPhasesV1,supportsEquippedWeaponGripStateV1,supportsHandVisualAuthorityV1,supportsNativeAnimationRuntimeProviderV1,supportsEquippedWeaponHandlingAuthorityV1,supportsEquippedWeaponHandRequestV1,supportsPresentedHandFramesV1,supportsPoseReadbackV1; - state/integration:
supportsExtendedLimitsV1,supportsOwnerFrameCallbacksV1,supportsHandInteractionStateV1,supportsProviderEventsV1,supportsEquippedWeaponStateV1,supportsExternalBodyScopesV1,supportsSemanticHandContactsV1,supportsPlayerColliderDescriptorsV1,supportsDebugOverlayPublicationV1,supportsTouchGrabTargetsV1,supportsWorldRaycastsV1,supportsColliderVisualizationOverrideV1.
Complete feature words
The descriptor and extended limits expose two 32-bit implementation words. The first currently defines:
FrameCallbacks, LifecycleFields, HandFrames, WeaponEvidence,
BodyContacts, ExternalContacts, ConsumerRegistrationV1,
OwnerFilteredExternalContactsV1, InteractionCommandQueue,
ForceGrabCommand, ForceReleaseCommand, ThrownDropCommand,
HandInputSuppression, WeaponPartInteraction, WeaponPartGripState,
WeaponPartRecordIdentity, WeaponPartTargetNonExclusive,
RawWandButtonState, PipboyInputSuppression, WeaponEmitters,
NativeAnimationAuthority, AnimationPhases, EquippedWeaponGripState,
HandVisualAuthority, NativeAnimationRuntimeProvider,
EquippedWeaponHandlingAuthority, DebugOverlayPublication,
PresentedHandFrames, EquippedWeaponHandRequest, and
ColliderVisualizationOverride.
The second currently defines:
SafeDescriptor, ExtendedLimits, PublicStructureSizes,
OwnerFrameCallbacks, HandInteractionState, ProviderEvents,
EquippedWeaponState, ExternalBodyScopes, ExternalContactCursor,
WeaponPartResolution, WeaponPartPoses, WeaponPartDriveResults,
ScopeSightState, WeaponComposition, AuthoredGripSnapshot,
PresentedHandPose, SemanticHandContacts, PlayerColliderDescriptors,
HandCollisionAvailability, CommandCancellation,
InputSuppressionState, OffhandReservationLeases, SnapshotEnrichment,
NativeAnimationRuntimeLeases, StatefulPublicationLeases,
CommandLifecycle, InputSampleMetadata,
WeaponClassificationEnrichment, ExternalContactEnrichment,
TouchGrabTargets, NativeVatsVansInputSuppression, and WorldRaycasts.
Consumer capabilities
Feature bits describe the provider. Capabilities describe one registered consumer. Request a bit only when your plugin uses that family.
| Capability | Grants access to |
|---|---|
FrameSnapshots | Owner frame callbacks and coherent equipped-weapon state. |
ExternalBodies | Legacy owner-level external body registration/clear. |
ExternalContacts | Owner or scoped external contact reads. |
OffhandReservation | Legacy reservation plus authenticated lease operations. |
InteractionCommands | Force grab/release/drop, result polling, and cancellation. |
HandInputSuppression | Per-hand suppression leases and explicit clear. |
WeaponPartInteraction | Weapon-part target and drive publications. |
NativeAnimationAuthority | Selective native arms/hands/weapon authority leases. |
AnimationPhases | Owner animation-phase callback registration. |
EquippedWeaponGripState | Exact equipped grip-baseline readback. |
HandVisualAuthority | Hand-root and finger-local visual publications. |
NativeAnimationRuntimeProvider | Native capture/runtime health publication and clear. |
EquippedWeaponHandlingAuthority | Equipped weapon handling policy/tuning lease. |
DebugOverlayPublication | Owner-scoped diagnostic line/text publication. |
ProviderEvents | Loss-aware provider event cursor. |
HandInteractionState | Pointer-free per-hand interaction state. |
ExternalBodyScopes | Authenticated child scopes and scoped cursor access. |
WeaponPartObservability | Target resolution, part poses, and drive outcomes. |
WeaponComposition | Weapon composition state and OMOD/attach rows. |
PoseReadback | Selected authored grip and final presented hand/finger pose. |
SemanticHandContacts | Begin/continued/end hand contact rows. |
PlayerColliderDescriptors | Player collider descriptions and collision availability. |
ScopeSightState | Current scope/sight anchor, bounds, and activation state. |
InputObservability | Effective per-hand suppression state and expiry. |
TouchGrabTargets | Scoped fixed-anchor, limited-hinge, and limited-prismatic targets, state, and yield. |
WorldRaycasts | Bounded owner-callback world raycasts through ROCK's validated filter. |
ColliderVisualizationOverride | Exact-body focus through ROCK's existing collider overlay. |
Capability registration is not a performance switch. It creates permission and ownership; heavier data remains on-demand.
Exact-grant pattern
constexpr auto caps =
static_cast<std::uint32_t>(
RockProviderConsumerCapabilityV1::FrameSnapshots) |
static_cast<std::uint32_t>(
RockProviderConsumerCapabilityV1::ProviderEvents) |
static_cast<std::uint32_t>(
RockProviderConsumerCapabilityV1::ScopeSightState);
RockProviderConsumerRegistrationV1 registration{};
std::snprintf(registration.modName, sizeof(registration.modName), "OpticInspector");
registration.requestedCapabilities = caps;
RockProviderConsumerHandleV1 handle{};
const auto result = RockProviderApi::inst->registerConsumerV1(
®istration, &handle);
if (result != RockProviderResultV1::Ok ||
handle.ownerToken == 0 ||
(handle.grantedCapabilities & caps) != caps) {
if (handle.ownerToken != 0) {
(void)RockProviderApi::inst->unregisterConsumerV1(handle.ownerToken);
}
return false;
}
Do not keep a partially granted owner alive if the feature cannot operate with that subset.
Limits and structure sizes
getProviderLimitsV1 is the compatible base prefix. getProviderLimitsExtV1
contains the complete capacity and lease contract. Caller-initialize either
structure with {} so its size member describes the local header; ROCK copies
only the supported prefix and writes the copied byte count back to size.
getPublicStructureSizeV1(id) returns ROCK's exact size for any of the 66 public
structure IDs, or 0 for an unknown ID. It is primarily an ABI diagnostic—not
a reason to allocate untyped memory or reinterpret unknown layouts.
Low-level helpers
The header also exposes:
queryProviderLimitsV1andqueryProviderLimitsExtV1— null/extent-safe wrappers around the table calls;providerApiTableSupportsV1— table extent checks, with or without cached base limits;providerSupportsFeature2V1— combined extended-bit and extent check;hasFeatureBitV1,hasFeatureBit2V1, andhasConsumerCapabilityV1— typed bit tests.
Use the combined high-level helper when available; use these primitives for a family that intentionally has no named predicate.