-
Notifications
You must be signed in to change notification settings - Fork 0
Network Packets & Protocols
DreamVoice provides an extensible, asynchronous network packet system built for Fabric 26.1.2+. This allows client-side mods, companion utilities, and third-party Fabric mods (such as survival tech mods, spy gadgets, cassette players, or soundboard apps) to communicate with DreamVoice without requiring hard classpath dependencies.
DreamVoice's networking operates on two distinct integration tiers:
graph TD
A[External Fabric Mod] -->|Direct API Method| B[DreamVoiceAPI.get]
A -->|Custom Network Packet| C[Fabric CustomPayload]
A -->|Event Hook| D[DreamVoiceEvents.VOICE_EVENT]
C -->|ServerPacketAnnotationProcessor| E[DreamVoice Server Handlers]
E --> B
-
Direct API Integration: Using
DreamVoiceAPI.get()in your mod's server code. -
Network Packet Channel: Sending JSON-encoded
CustomPacketPayloadmessages over thedreamvoice:*channels. This allows loose coupling: your mod does not need DreamVoice as a mandatory compile dependency at runtime.
All DreamVoice packets implement Minecraft's CustomPacketPayload and are annotated with @DreamPacket(type = ...). On server initialization, PacketAnnotationProcessor automatically scans and registers all packet codecs with Fabric's PayloadTypeRegistry.
When incoming packets arrive from connected clients or other mods, ServerPacketAnnotationProcessor routes them asynchronously to the appropriate handler methods annotated with @DreamServerReceiver.
All DreamVoice packet identifiers belong to the dreamvoice namespace:
Identifier: dreamvoice:<packet_name>
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_request_config_sync |
Client |
ServerBoundRequestConfigSyncPacket |
{} |
Requests a full configuration state snapshot from the server. |
dreamvoice:client_bound_config_sync |
Server |
ClientBoundConfigSyncPacket |
{"modules": {...}} |
Broadcasts active module states to the client. |
dreamvoice:server_bound_visualizer_toggle |
Client |
ServerBoundVisualizerTogglePacket |
{"enabled": true|false} |
Toggles visualizer mode for the player. |
dreamvoice:client_bound_visualizer_sync |
Server |
ClientBoundVisualizerSyncPacket |
{"active": true|false} |
Syncs visualizer active state back to the client. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_speaker_create |
Client |
ServerBoundSpeakerCreatePacket |
{"id":"<uuid>", "name":"<str>", "world":"<id>", "x":0.0, "y":0.0, "z":0.0, "distance":32.0, "mode":"GLOBAL|RESTRICTED"} |
Creates a new 3D spatial speaker at coordinates or attached entity. |
dreamvoice:server_bound_speaker_delete |
Client |
ServerBoundSpeakerDeletePacket |
{"name":"<str>"} or {"uuid":"<uuid>"}
|
Removes an existing speaker. |
dreamvoice:server_bound_speaker_link |
Client |
ServerBoundSpeakerLinkPacket |
{"speakerName":"<str>", "playerUuid":"<uuid>"} |
Links a player's microphone to broadcast through the speaker. |
dreamvoice:server_bound_speaker_unlink |
Client |
ServerBoundSpeakerUnlinkPacket |
{"speakerName":"<str>", "playerUuid":"<uuid>"} |
Unlinks player microphone from speaker. |
dreamvoice:server_bound_speaker_play_sound |
Client |
ServerBoundSpeakerPlaySoundPacket |
{"speakerName":"<str>", "source":"<path_or_url>", "loop":false} |
Starts playback of a sound file or stream. |
dreamvoice:server_bound_speaker_stop_sound |
Client |
ServerBoundSpeakerStopSoundPacket |
{"speakerName":"<str>"} |
Stops audio playback on target speaker. |
dreamvoice:server_bound_speaker_update |
Client |
ServerBoundSpeakerUpdatePacket |
{"speakerName":"<str>", "distance":24.0, "mode":"..."} |
Updates speaker properties dynamically. |
dreamvoice:client_bound_speaker_sync |
Server |
ClientBoundSpeakerSyncPacket |
{"speakers":[...]} |
Synchronizes all registered speakers to client. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_wiretap_create |
Client |
ServerBoundWiretapCreatePacket |
{"name":"<str>", "distance":12.0, "world":"...", "x":0.0, "y":0.0, "z":0.0} |
Places a listening bug at world coordinates or entity. |
dreamvoice:server_bound_wiretap_delete |
Client |
ServerBoundWiretapDeletePacket |
{"name":"<str>"} |
Destroys an existing wiretap bug. |
dreamvoice:server_bound_wiretap_subscribe |
Client |
ServerBoundWiretapSubscribePacket |
{"name":"<str>"} |
Subscribes the sending player to eavesdrop live. |
dreamvoice:server_bound_wiretap_unsubscribe |
Client |
ServerBoundWiretapUnsubscribePacket |
{"name":"<str>"} |
Unsubscribes player from the wiretap. |
dreamvoice:client_bound_wiretap_sync |
Server |
ClientBoundWiretapSyncPacket |
{"wiretaps":[...]} |
Synchronizes active wiretaps to client. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_radio_create |
Client |
ServerBoundRadioCreatePacket |
{"channel":"142.5"} |
Allocates a new radio frequency channel. |
dreamvoice:server_bound_radio_join |
Client |
ServerBoundRadioJoinPacket |
{"channel":"142.5"} |
Tunes the sending player into a radio frequency. |
dreamvoice:server_bound_radio_leave |
Client |
ServerBoundRadioLeavePacket |
{} |
Disconnects player from their current radio channel. |
dreamvoice:client_bound_radio_sync |
Server |
ClientBoundRadioSyncPacket |
{"currentChannel":"142.5", "channels":[...]} |
Syncs current tuned channel and available frequencies. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_recording_start |
Client |
ServerBoundRecordingStartPacket |
{"targetUuid":"<uuid>"} |
Starts capturing raw Opus frames from target speaker/player. |
dreamvoice:server_bound_recording_stop |
Client |
ServerBoundRecordingStopPacket |
{"targetUuid":"<uuid>"} |
Stops voice capture and flushes .dv binary file. |
dreamvoice:server_bound_cassette_create |
Client |
ServerBoundCassetteCreatePacket |
{"recordingId":"<uuid>"} |
Spawns a physical, interactive Cassette item for player. |
dreamvoice:server_bound_recording_play |
Client |
ServerBoundRecordingPlayPacket |
{"recordingId":"<uuid>"} |
Starts private headphone playback of target recording. |
dreamvoice:server_bound_recording_stop_play |
Client |
ServerBoundRecordingStopPlayPacket |
{} |
Stops active cassette playback in player's headphones. |
dreamvoice:client_bound_recording_sync |
Server |
ClientBoundRecordingSyncPacket |
{"recordings":[...]} |
Synchronizes metadata list of available recordings. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_filter_apply |
Client |
ServerBoundFilterApplyPacket |
{"filterId":"robot", "targetUuid":"<uuid>"} |
Applies a DSP filter node to target player. |
dreamvoice:server_bound_filter_remove |
Client |
ServerBoundFilterRemovePacket |
{"filterId":"robot", "targetUuid":"<uuid>"} |
Removes specific filter node from player. |
dreamvoice:server_bound_filter_clear |
Client |
ServerBoundFilterClearPacket |
{"targetUuid":"<uuid>"} |
Clears all active DSP filters on target player. |
dreamvoice:server_bound_filter_toggle |
Client |
ServerBoundFilterTogglePacket |
{"filterId":"robot"} |
Toggles filter on the sending player. |
dreamvoice:client_bound_filter_sync |
Server |
ClientBoundFilterSyncPacket |
{"activeFilters":["radio","megaphone"]} |
Syncs active filters currently applied to the player. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_room_create |
Client |
ServerBoundRoomCreatePacket |
{"id":"studio","world":"...","minX":0,"minY":0,"minZ":0,"maxX":10,"maxY":10,"maxZ":10,"isolation":0.95} |
Defines a soundproof Cuboid zone. |
dreamvoice:server_bound_room_delete |
Client |
ServerBoundRoomDeletePacket |
{"id":"studio"} |
Deletes an acoustic room definition. |
dreamvoice:server_bound_room_update |
Client |
ServerBoundRoomUpdatePacket |
{"id":"studio","isolation":0.8} |
Modifies room acoustic parameters dynamically. |
dreamvoice:client_bound_room_sync |
Server |
ClientBoundRoomSyncPacket |
{"rooms":[...]} |
Syncs registered acoustic rooms to client. |
| Packet Identifier | Direction | Class | Payload Fields (JSON) | Description |
|---|---|---|---|---|
dreamvoice:server_bound_projection_create |
Client |
ServerBoundProjectionCreatePacket |
{"name":"cctv_1","world":"...","x":0.0,"y":0.0,"z":0.0} |
Sets up a remote voice projection anchor. |
dreamvoice:server_bound_projection_delete |
Client |
ServerBoundProjectionDeletePacket |
{"name":"cctv_1"} |
Removes a voice projection anchor. |
dreamvoice:client_bound_projection_sync |
Server |
ClientBoundProjectionSyncPacket |
{"projections":[...]} |
Syncs active voice projections to client. |
dreamvoice:server_bound_transmitter_create |
Client |
ServerBoundTransmitterCreatePacket |
{"targetUuid":"<uuid>"} |
Sets up a directional voice transmitter. |
dreamvoice:server_bound_transmitter_delete |
Client |
ServerBoundTransmitterDeletePacket |
{"targetUuid":"<uuid>"} |
Deletes a directional voice transmitter. |
dreamvoice:server_bound_transmitter_toggle |
Client |
ServerBoundTransmitterTogglePacket |
{"enabled":true} |
Toggles directional transmitter broadcast mode. |
dreamvoice:client_bound_transmitter_sync |
Server |
ClientBoundTransmitterSyncPacket |
{"active":true,"receivers":[...]} |
Syncs transmitter status and receiver list. |
Suppose you are creating a survival mod with craftable Megaphones or Public Address blocks. When a player powers a PA block with redstone, send a packet to DreamVoice:
import fr.dreamin.dreamvoice.fabric.network.model.speaker.ServerBoundSpeakerPlaySoundPacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
public class SurvivalSpeakerBlock {
public static void triggerAlarm(String speakerName) {
String jsonPayload = """
{
"speakerName": "%s",
"source": "siren.wav",
"loop": false
}
""".formatted(speakerName);
// Send packet to DreamVoice server:
ClientPlayNetworking.send(new ServerBoundSpeakerPlaySoundPacket(jsonPayload));
}
}When an operative right-clicks a door with a spy bug device:
import fr.dreamin.dreamvoice.fabric.network.model.wiretap.ServerBoundWiretapCreatePacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.core.BlockPos;
public class SpyBugItem {
public static void plantBug(String bugName, BlockPos pos, String worldId) {
String json = """
{
"name": "%s",
"world": "%s",
"x": %d,
"y": %d,
"z": %d,
"distance": 16.0
}
""".formatted(bugName, worldId, pos.getX(), pos.getY(), pos.getZ());
ClientPlayNetworking.send(new ServerBoundWiretapCreatePacket(json));
}
}If building a custom client HUD that displays whether DreamVoice visualizer mode is active:
import fr.dreamin.dreamvoice.fabric.network.model.config.ClientBoundVisualizerSyncPacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
public class VoiceVisualizerHud {
public static void registerClientReceiver() {
ClientPlayNetworking.registerGlobalReceiver(
ClientBoundVisualizerSyncPacket.TYPE,
(packet, context) -> {
context.client().execute(() -> {
// Update client HUD state:
boolean isVisualizerActive = packet.json().contains("\"active\":true");
HudOverlay.setVisualizerActive(isVisualizerActive);
});
}
);
}
}