qti-neon-client
qti-neon-client
qti-neon-client provides the Neon networking client package for Clockwork.
It includes:
- Neon protocol packet header/payload encode/decode helpers
- Typed packet registry for game packet serialization
- Transport abstraction with mock and Tauri UDP implementations
- Client state machine with connect, reconnect, ping, and reliability handling
- Clockwork plugin integration for fixed-tick receive/send orchestration
Install
JavaScript/TypeScript:
npm i qti-neon-client
Register the Plugin
TypeScript:
import { AppBuilder } from 'qti-clockwork-app'
import { NeonPlugin, MockTransport } from 'qti-neon-client'
const [clientTransport] = MockTransport.createPair()
const app = new AppBuilder()
.use(
NeonPlugin({
transport: clientTransport,
playerName: 'PlayerOne',
gameIdentifier: 0x1234
})
)
.build()
JavaScript:
import { AppBuilder } from 'qti-clockwork-app'
import { NeonPlugin, MockTransport } from 'qti-neon-client'
const [clientTransport] = MockTransport.createPair()
const app = new AppBuilder()
.use(
NeonPlugin({
transport: clientTransport,
playerName: 'PlayerOne',
gameIdentifier: 0x1234
})
)
.build()
For Neon integration see https://projectneon-jd.quietterminal.co.uk
Packets and Registry
TypeScript:
import { NeonPacketRegistry, type PacketDescriptor } from 'qti-neon-client'
type Coord = { x: number; y: number }
const registry = new NeonPacketRegistry()
const coordDescriptor: PacketDescriptor<Coord> = {
id: 0x10,
name: 'Coord',
serialize(payload, view, offset) {
view.setFloat32(offset, payload.x, true)
view.setFloat32(offset + 4, payload.y, true)
return 8
},
deserialize(view, offset) {
return {
x: view.getFloat32(offset, true),
y: view.getFloat32(offset + 4, true)
}
}
}
registry.register(coordDescriptor)
JavaScript:
import { NeonPacketRegistry } from 'qti-neon-client'
const registry = new NeonPacketRegistry()
registry.register({
id: 0x10,
name: 'Coord',
serialize(payload, view, offset) {
view.setFloat32(offset, payload.x, true)
view.setFloat32(offset + 4, payload.y, true)
return 8
},
deserialize(view, offset) {
return {
x: view.getFloat32(offset, true),
y: view.getFloat32(offset + 4, true)
}
}
})
For Neon integration see https://projectneon-jd.quietterminal.co.uk
Client Usage
TypeScript:
import { NeonClient, MockTransport } from 'qti-neon-client'
const [clientTransport] = MockTransport.createPair()
const client = new NeonClient({
transport: clientTransport,
playerName: 'PlayerOne',
gameIdentifier: 0x1234
})
await client.connect('127.0.0.1', 7777, 42)
client.processIncoming()
client.tickReliability(Date.now())
JavaScript:
import { NeonClient, MockTransport } from 'qti-neon-client'
const [clientTransport] = MockTransport.createPair()
const client = new NeonClient({
transport: clientTransport,
playerName: 'PlayerOne',
gameIdentifier: 0x1234
})
await client.connect('127.0.0.1', 7777, 42)
client.processIncoming()
client.tickReliability(Date.now())
For Neon integration see https://projectneon-jd.quietterminal.co.uk
Notes
NeonPlugininstalls receive and send systems inFixedUpdateand stores client state in a resource.MockTransportis useful for deterministic tests and local packet-flow validation.TauriUdpTransportprovides runtime UDP I/O when running in Tauri.