by Pivec Labs
Template Guide Customize output

Template Guide

Customise the NetCrafter Relay code generator output with template overrides.

NetCrafter Relay generates code by substituting placeholders in .tpl text files. The nine built-in templates live at:

text
Assets/PivecLabs/NetCrafterRelay/Templates/

You must never edit files in this folder directly. The Template Override System lets you customise the output for a specific schema while leaving the global templates untouched.

01

How the override system works#

When Use Custom Templates is enabled in Settings → Project Settings, the generator checks the schema's override folder before loading each template:

text
Definitions/{SchemaName}/Templates/{TemplateName}.tpl

If the override file exists, it is used instead of the global template. If it does not exist, the global template is used as a fallback. You can override any subset of the nine templates — you do not need to provide all of them.

02

Setting up overrides#

  1. Open Settings → Project Settings for your schema.
  2. Enable Use Custom Templates.
  3. Click Create Override Folder.

This creates Definitions/{SchemaName}/Templates/ and copies all nine global templates into it. Each copied file receives a header comment:

text
// NetCrafter Template Override
// Schema: MyGame
// Template: RequestClass.tpl
// Modified: 2026-06-06
// This file overrides the global template for this schema only.
// Delete this file to revert to the global template.

The Template Files grid shows a green [✓] next to each template that exists in the override folder. Templates marked [ ] use the global fallback.

03

Reverting an override#

Click Reset next to any template in the grid. This deletes the override file; the next generation will use the global template for that file. Alternatively, delete the file manually from Definitions/{SchemaName}/Templates/.

04

Template reference#

RequestClass.tpl

Generates one file per ClientToHost/ClientToHostBroadcast message: {MessageName}Request.cs.

Placeholder Replaced with
{{NAMESPACE}} The C# namespace from Project Settings
{{REQUEST_NAME}} The message name
{{FIELDS}} Public field declarations, one per message field
{{WRITE_FIELDS}} writer.Write*(value) statements for Serialize()
{{READ_FIELDS}} req.field = reader.Read*() statements for Deserialize() (used host-side by HostActionRouter)

EventClass.tpl

Generates one file per HostToClient event: {EventName}Event.cs.

Placeholder Replaced with
{{NAMESPACE}} The C# namespace
{{EVENT_NAME}} The event name
{{FIELDS}} Public field declarations
{{WRITE_FIELDS}} writer.Write*(value) statements for Serialize() (built host-side before broadcasting)
{{READ_FIELDS}} ev.field = reader.Read*() statements for Deserialize() (used by the receiving peer)

ModelClass.tpl

Generates one file per Data Definition: {ModelName}.cs.

Placeholder Replaced with
{{NAMESPACE}} The C# namespace
{{MODEL_NAME}} The model name
{{FIELDS}} Public field declarations
{{WRITE_FIELDS}} Serialisation statements for WriteTo(RelayWriter)
{{READ_FIELDS}} Deserialisation statements for ReadFrom(RelayReader)

RelayConnectionManager.tpl

Generates one RelayConnectionManager.cs per schema — owns the StunTurnClient, the join/host flow, and the send/receive envelope.

Placeholder Replaced with
{{NAMESPACE}} The C# namespace
{{RELAY_HOST}} Relay host from Relay Settings
{{RELAY_PORT}} TURN port
{{RENDEZVOUS_URL}} Rendezvous service URL
{{CREDENTIAL_MODE}} StaticSecret or RestApi
{{EVENT_SWITCH}} One case block per HostToClient event
{{EVENT_HANDLERS}} One handler stub method per HostToClient event

HandlerSwitch.tpl

Generates the case block injected into {{EVENT_SWITCH}}. One instance is generated per HostToClient event.

Placeholder Replaced with
{{EVENT_NAME}} The event name

EventHandler.tpl

Generates the handler method stub injected into {{EVENT_HANDLERS}}. One instance per HostToClient event.

Placeholder Replaced with
{{EVENT_NAME}} The event name

HostActionRouter.tpl

Generates one HostActionRouter.cs per schema — the host-side logic that used to be a separate Java server extension. It compiles straight into the same client build; there's no deploy step.

Placeholder Replaced with
{{NAMESPACE}} The C# namespace
{{HANDLER_CASES}} One case block per Host Action, dispatching to its handler method
{{HANDLER_METHODS}} One handler method per Host Action (see HostActionHandler.tpl)

HostActionHandler.tpl

Generates one handler method per Host Action, injected into {{HANDLER_METHODS}}.

Placeholder Replaced with
{{HANDLER_NAME}} The Host Action's handler name
{{METHOD_BODY}} Trigger deserialization, response construction, and the BroadcastAll/SenderOnly/TargetUser/Custom dispatch logic

RelayConfig.tpl

Generates RelayConfig.json — a small config file with the relay connection settings, replacing the old SFS3 zone XML entirely (no zone/room/AOI concepts apply here).

Placeholder Replaced with
{{RELAY_HOST}} Relay host from Relay Settings
{{RELAY_PORT}} TURN port
{{RENDEZVOUS_URL}} Rendezvous service URL
{{CREDENTIAL_MODE}} StaticSecret or RestApi
05

Example: add a log line to every request#

This adds a Debug.Log call at the top of every request's Serialize() method.

  1. Enable Use Custom Templates and click Create Override Folder.
  2. Open Definitions/{SchemaName}/Templates/RequestClass.tpl.
  3. Find the Serialize method body and add one line before the RelayWriter is created:
text
        public byte[] Serialize()
        {
            Debug.Log("[Net] Sending {{REQUEST_NAME}}");
            var writer = new PivecLabs.NetCrafterRelay.RelayWriter();
{{WRITE_FIELDS}}
            return writer.ToArray();
        }
  1. Click Generate All Files. Every request class in the schema will now include the log line with the correct message name substituted in.
06

Placeholder validation#

Each time you generate with Use Custom Templates on, NetCrafter Relay checks every override template for required placeholders and logs a [NetCrafter Relay] Warning in the Unity console for any that are missing. Generation still proceeds, but the output will be malformed if a required placeholder is absent. The same check runs when you click Create Override Folder.