ygopro-yrp3d-encode
v1.0.1
Published
A platform-agnostic YGOPro Unity `.yrp3d` replay packet parser and writer.
Readme
ygopro-yrp3d-encode
A platform-agnostic TypeScript parser and writer for YGOPro Unity .yrp3d replay packet files.
This package follows the API style of ygopro-yrp-encode: construct an object, call fromYrp3d() to parse bytes, inspect or modify fields, then call toYrp3d() to serialize bytes again.
It also reuses protocol classes from ygopro-msg-encode. Refer to that package for detailed YGOProMsgBase, YGOProStocChat, and YGOProStocReplay field definitions.
Install
npm i ygopro-yrp3d-encodeQuick Start
import fs from 'fs';
import { YGOProStocChat, YGOProStocReplay } from 'ygopro-msg-encode';
import { YGOProYrp3d } from 'ygopro-yrp3d-encode';
const payload = fs.readFileSync('replay.yrp3d');
const yrp3d = new YGOProYrp3d().fromYrp3d(payload);
console.log(yrp3d.name0);
console.log(yrp3d.name1);
console.log(yrp3d.masterRule);
const chats = yrp3d.messages.filter(
(message): message is YGOProStocChat => message instanceof YGOProStocChat,
);
console.log(chats.map((chat) => chat.msg));
const embeddedYrp = yrp3d.extractYrp();
console.log(embeddedYrp?.hostName);
console.log(embeddedYrp?.clientName);
const out = yrp3d.toYrp3d();
fs.writeFileSync('replay-remade.yrp3d', out);File Format
A .yrp3d file is a sequence of packets:
repeat until EOF:
uint8 packet type
uint32 payload length, little-endian
uint8[] payloadThere is no file-level magic, version field, or checksum. Invalid packet lengths throw in the raw packet reader.
High-level parsing maps packet types as follows:
| Packet type | Meaning | High-level representation |
| --- | --- | --- |
| normal GameMessage ids | OCG/YGOPro duel messages | YGOProMsgBase subclass |
| 230 | sibyl_chat | YGOProStocChat |
| 231 | sibyl_replay | YGOProStocReplay |
| 235 | sibyl_name | YGOProYrp3d name fields |
| 236 | sibyl_quit | ignored |
| unknown or unparsable packets | unsupported data | ignored |
Main API
YGOProYrp3d
Main class for reading and writing .yrp3d files.
import { YGOProYrp3d } from 'ygopro-yrp3d-encode';
const yrp3d = new YGOProYrp3d();
yrp3d.fromYrp3d(bytes);
const output = yrp3d.toYrp3d();Constructor
constructor(init?: Partial<YGOProYrp3dLike>)Creates a new replay object. When init is provided, string fields are copied and messages are deep-copied via each message object's copy() method.
const copy = new YGOProYrp3d(existing);
copy.name0 = 'changed';Fields
name0: string;
name0Tag: string;
name0Current: string;
name1: string;
name1Tag: string;
name1Current: string;
masterRule: number;
messages: YGOProYrp3dMessage[];Name fields come from the first valid 235 = sibyl_name packet. Later name packets are ignored.
Default values:
name0 = '';
name0Tag = '';
name0Current = '';
name1 = '';
name1Tag = '';
name1Current = '';
masterRule = 3;
messages = [];fromYrp3d()
fromYrp3d(payload: Uint8Array): thisParses .yrp3d bytes into this object.
Behavior:
- Clears the current object before reading.
- Reads the first valid
sibyl_namepacket into name fields. - Parses normal
GameMessagepackets intoYGOProMsgBasesubclasses withygopro-msg-encode. - Parses
sibyl_chatintoYGOProStocChat. - Parses
sibyl_replayintoYGOProStocReplay. - Ignores
sibyl_quit. - Ignores unknown or unsupported packet types.
toYrp3d()
toYrp3d(): Uint8ArraySerializes the object into .yrp3d bytes.
Behavior:
- Writes all
messagesas.yrp3dpackets. - Writes exactly one
sibyl_namepacket from the object's name fields. - If the message list contains a
YGOProMsgStartmessage, insertssibyl_nameimmediately after the first Start packet. - If the message list has no Start packet, writes
sibyl_nameas the first packet. - Writes
YGOProStocChatas230 = sibyl_chat. - Writes
YGOProStocReplayas231 = sibyl_replay. - Never writes
236 = sibyl_quit. - Does not preserve unknown packets.
extractYrp()
extractYrp(): YGOProYrp | undefinedFinds the last YGOProStocReplay message by scanning messages backwards, then returns its embedded YGOProYrp.
const yrp = yrp3d.extractYrp();
if (yrp) {
console.log(yrp.hostName, yrp.clientName);
}This is a convenience method for the common case where a .yrp3d contains an embedded standard .yrp replay. See ygopro-yrp-encode for the YGOProYrp API.
Types
YGOProYrp3dMessage
type YGOProYrp3dMessage =
| YGOProMsgBase
| YGOProStocChat
| YGOProStocReplay;These classes are provided by ygopro-msg-encode.
YGOProYrp3dLike
interface YGOProYrp3dLike {
name0: string;
name0Tag: string;
name0Current: string;
name1: string;
name1Tag: string;
name1Current: string;
masterRule: number;
messages: YGOProYrp3dMessage[];
}Used by the deep-copy constructor.
Raw Packet API
Use the raw API when you need to inspect packet boundaries directly.
import {
readYrp3dPackets,
writeYrp3dPackets,
type YGOProYrp3dRawPacket,
} from 'ygopro-yrp3d-encode';
const packets = readYrp3dPackets(bytes);
for (const packet of packets) {
console.log(packet.type, packet.payload.length);
}
const remade = writeYrp3dPackets(packets);YGOProYrp3dRawPacket
type YGOProYrp3dRawPacket = {
type: number;
payload: Uint8Array;
};readYrp3dPackets()
readYrp3dPackets(payload: Uint8Array): YGOProYrp3dRawPacket[]Reads raw .yrp3d packets. Throws if a packet header or payload length is truncated.
writeYrp3dPackets()
writeYrp3dPackets(packets: YGOProYrp3dRawPacket[]): Uint8ArrayWrites raw packets using the standard .yrp3d packet framing.
Constants
import {
YRP3D_SIBYL_CHAT,
YRP3D_SIBYL_REPLAY,
YRP3D_SIBYL_NAME,
YRP3D_SIBYL_QUIT,
} from 'ygopro-yrp3d-encode';Values:
YRP3D_SIBYL_CHAT = 230;
YRP3D_SIBYL_REPLAY = 231;
YRP3D_SIBYL_NAME = 235;
YRP3D_SIBYL_QUIT = 236;Chat Packets
230 = sibyl_chat is exposed as YGOProStocChat.
The reader accepts both known payload layouts:
uint16 player_type
utf16le null-terminated msgand the Unity-compatible variant:
uint32 player_type
utf16le null-terminated msgThe writer emits the Unity-compatible uint32 + utf16le form.
See YGOProStocChat in ygopro-msg-encode for details about player_type and chat color values.
Name Packets
235 = sibyl_name is exposed through fields on YGOProYrp3d.
Payload layout:
UTF-16LE fixed 50 chars name0
UTF-16LE fixed 50 chars name0Tag
UTF-16LE fixed 50 chars name0Current
UTF-16LE fixed 50 chars name1
UTF-16LE fixed 50 chars name1Tag
UTF-16LE fixed 50 chars name1Current
int32 masterRuleOnly the first valid name packet is read. toYrp3d() writes exactly one name packet.
Replay Packets
231 = sibyl_replay is exposed as YGOProStocReplay.
The replay payload is a complete .yrp or .yrp2 byte stream. Use extractYrp() for the common case:
const yrp = new YGOProYrp3d().fromYrp3d(bytes).extractYrp();For the embedded replay object API, refer to ygopro-yrp-encode.
Notes
- This package is not a lossless editor for unknown
.yrp3dpacket types. sibyl_quitpackets are intentionally ignored.- Unknown or unparsable packets are intentionally ignored in the high-level API.
- Use
readYrp3dPackets()if you need raw packet-level inspection.
