WIRESYNDICATEDocumentation

Spatial Triggers & Telemetry

WireSyndicate operates on a strict zero-trust telemetry model. Impressions are not simply "counted" when an asset loads; they are cryptographically validated by our Edge Nodes based on actual player line-of-sight and physical proximity.

Placement Nodes

The Zero-Trust architecture utilizes unified, autonomous nodes. Every ad unit in your game requires exactly ONE component that handles both cryptographic telemetry (Gaze Verification) and visual rendering automatically.

1. WS Placement Dynamic (2D Texture Injector)

When to use: For flat surfaces like billboards, posters, or terminal screens.

This acts as the rendering engine. It securely fetches dynamic 2D images, caches them to disk, and injects them onto your geometry at runtime using non-destructive MaterialPropertyBlock memory mapping.

  • Target Renderer: This is a fallback reference used for bounds checking. You can completely ignore this—leave it blank. The script will auto-detect what it needs from the array below.
  • Target Renderers (Array): This allows you to specify exactly which MeshRenderers should display the ad. For example, if you have LODs (Level of Detail meshes), you want the ad on all of them. However, if you leave the array size at 0, the SDK will automatically crawl through all the children of the GameObject and apply the ad to every LOD renderer it finds. Leave it at 0 for an automatic setup.
  • Texture Property Name: The engine does not read the Display Name of your shader property (e.g., "Base Map"). It strictly requires the internal Reference ID.
    • How to find it: Open your shader in Unity's Shader Graph. Open the Blackboard -> Click your Texture Node -> Open Node Settings -> Copy the string in the Reference field.
    • Common Defaults: _BaseMap (URP/HDRP), _MainTex (Standard 3D), _Map (Custom Unlit).
  • Material Index: If your object has multiple materials on it (like one for the metal frame, and one for the screen), you specify which material index is the screen. 0 is the first material, 1 is the second. Note: In rare cases with third-party assets, the visual order in the Inspector may not match the raw geometry (Submesh) order baked into the 3D model. If your ad applies to the wrong part of the mesh, try swapping the index!

PRO TIP: Material Indexing If you look at your Mesh Renderer in the Inspector and see:

  • Element 0: Metal_Frame
  • Element 1: Neon_Screen

You typically must set the Material Index to 1. If left at 0, WireSyndicate will paint the network advertisement onto the metal frame of the billboard instead of the screen!

Handling Texture Atlases & UV Grids

Modern environments often combine multiple textures into a single Atlas Material to save draw calls. When a texture is atlased, Unity relies on the material's Scale and Transform (ST) properties, or custom shader properties like Rows and Columns, to only display a small tile of the larger image. Since injected network ads are single full-resolution images, atlased materials will slice and distort them.

  • Override UV Scale Offset: If you check this box, the SDK forces the image to stretch 1-to-1 across your mesh, completely ignoring any custom tiling your material might have. It's a great quick-fix if your ad looks distorted or cropped. Leave this checked unless your mesh has custom, hardcoded UV unwrapping that explicitly requires tile offsets.
  • Shader Property Overrides: This is incredibly powerful for custom shaders. If your material uses a sprite sheet or texture atlas, it likely slices the texture using custom properties (like _Rows and _Columns). To make our single WireSyndicate image fit the whole mesh, you must add those properties here and force their values to 1. This tells the shader to use the whole image instead of slicing it!
    • How to use: Add an element to the list. Set the Value to 1.
    • IMPORTANT - The Property Name: You must use the internal Shader Reference Name, not the Display Name shown in the material Inspector! The Reference Name almost always begins with an underscore.
    • Finding the Reference Name: Open your shader in Unity's Shader Graph. Open the Blackboard -> Click your property (e.g. "Rows") -> Open Node Settings -> Copy the string in the Reference field (e.g., _Rows, _GridX, _Tile).

Architectural Note: The engine utilizes a MaterialPropertyBlock to execute the texture swap and float overrides. This is a non-destructive operation that prevents memory leaks and ensures your base materials remain untouched in the project hierarchy.

Rich Media & Video Placements

WireSyndicate supports dynamic injection of .mp4 and .webm video ads directly onto your geometry. The SDK detects the creative format and seamlessly instantiates a Unity VideoPlayer.

  • Dynamic Generation: By default, the SDK automatically creates a 16:9 RenderTexture in memory, streams the video into it, and maps it to your MaterialPropertyBlock.
  • Target Render Texture (Memory Override): If you are strictly managing VRAM and want to manually allocate a specific resolution (e.g. 512x512) or color format, you can assign a pre-made RenderTexture in the Inspector. The VideoPlayer will bypass dynamic generation and pipe the video stream into your assigned asset.
// Example: Programmatic assignment of a low-res RenderTexture override
void Start() {
    WSPlacementDynamic dynamicPlacement = GetComponent<WSPlacementDynamic>();
    // Pre-allocate a highly optimized texture
    RenderTexture customRT = new RenderTexture(640, 360, 0, RenderTextureFormat.RGB565);
    // Bind it to the placement before the payload resolves
    dynamicPlacement.targetRenderTexture = customRT;
}

2. Global Texture Injection: WS Shared Material Node

When to use: When you have multiple objects in your scene (like 10 banners) that all share the exact same Unity Material asset.

This script drastically reduces draw calls and network load by applying the ad directly to the global Material asset in memory. Instead of attaching a node to every single banner, you attach one global node.

  • Placement ID: Your unique Supabase placement ID.
  • Target Material: Drag the shared Material asset directly from your Project window (or from the MeshRenderer of one of the banners) into this slot.
  • Texture Property Name: The Shader Reference ID (e.g. _MainTex, _BaseMap, or _Map).
  • Primary Gaze Target: The telemetry engine still needs a physical object in the scene to run line-of-sight raycasts against. Pick just one of your banners in the scene and drag its Collider into this slot. This acts as the physical anchor for viewability verification.

Atlas & Shader Overrides

Just like dynamic placements, if your shared Material uses a texture atlas, the single ad image will get cropped.

  • Check Override UV Scale & Offset to forcefully hijack standard _ST scaling to 1x1.
  • If using custom float properties (like _Rows or _Tile), add them to the Shader Property Overrides list and set their values to 1 so the Material scales to show the full ad!

Component-Based Tagging & API Auto-Sync

When managing massive environments with hundreds or thousands of ad nodes, manual coordinate entry is impossible. WireSyndicate provides a zero-touch Auto-Sync architecture directly integrated into the Unity Editor.

The WireSyndicateNode Component

Instead of matching materials, the SDK relies on a lightweight C# script: WireSyndicateNode.cs. You simply attach this component to any GameObject you wish to serve as an ad placement. The component exposes a single field in the Inspector:

  • Placement ID: Retrieve this UUID directly from your WireSyndicate Developer Console and paste it into the node. This allows you to cleanly segment your inventory (e.g., "Downtown Billboards" vs. "Highway Billboards").

One-Click Network Synchronization

The SDK includes a custom Editor Window to automatically sync your entire environment directly to the production database.

  1. Open the Auto-Sync Tool: In the Unity Editor, navigate to WireSyndicate > Network Sync.
  2. Execute Sync: Click the Sync to Network button.
  3. The Editor Script will automatically iterate through your entire active scene and find every instance of WireSyndicateNode.
  4. It groups the nodes by their Placement ID, extracts their global transform matrices (Position, Rotation, Scale), and securely clamps the floating-point values to exactly 4 decimal places for precision optimization.
  5. The script fires a secure UnityWebRequest (POST) directly to the Edge API (/api/v1/developer/placements/sync).

[!IMPORTANT] Authentication: The SDK Editor script requires your Game's unique network_key. It injects this key into the Authorization: Bearer <network_key> header of the POST request. Ensure your network_key is securely configured in your SDK project settings so the server can verify your identity and authorize the payload.


3. WS Placement 3D (AssetBundles)

When to use: For spawning fully interactive 3D branded models (e.g., a branded soda can on a table).

  • Action: Attach this to an empty GameObject (or fallback mesh) acting as your anchor. It fetches a compiled Unity AssetBundle, extracts the 3D GameObject, and spawns it dynamically as a child of your anchor. It will only disable your fallback mesh after the new 3D ad successfully spawns. If the network drops or there is no active campaign, your fallback mesh remains visually intact.

Important: Every single ad unit in your game must have a unique Placement ID from your Developer Portal. The Edge Node relies on this ID to differentiate campaigns and ensure the correct brand asset loads onto the correct object.

The Gaze-Tracking Engine

The WS Gaze Verification Engine runs a highly optimized background loop performing structural Raycast operations against your WS Placement Node components.

An impression is only fired to the Telemetry Reconciliation Engine when all three of the following conditions are mathematically satisfied:

  1. Line of Sight: An unobstructed Raycast hits the placement's Collider.
  2. Proximity: The camera is within the maximum viewing distance defined by the ad format.
  3. Algorithmic Dynamic Gaze Thresholds: The player maintains line of sight according to the following strict spatial constraints:
    • Minimum Viewability Threshold: < 1.5% screen coverage. Note: The 3D asset or texture is always loaded and rendered instantly upon spawn to ensure graphical integrity. However, if it occupies less than 1.5% of the screen, the Gaze Engine instantly rejects it from the billable telemetry queue to save CPU raycasting cycles, as it is too small to provide advertising value.
    • The Ceiling (1500ms Dwell): 1.5% to 4.99% coverage, or steep viewing angles up to 60 degrees.
    • Minimum Floor (500ms Dwell): >= 5% coverage and < 25 degree viewing angle. The asset is in the primary focal cone and brand registration happens almost instantly.

This Black-Box Protocol requires zero developer configuration. Once these vectors are mathematically satisfied, the SDK autonomously batches and dispatches the impression event. You do not need to manually trigger telemetry.