https://github.com/dockyardmc/tide
Codecs library made for DockyardMC
https://github.com/dockyardmc/tide
Last synced: 12 months ago
JSON representation
Codecs library made for DockyardMC
- Host: GitHub
- URL: https://github.com/dockyardmc/tide
- Owner: DockyardMC
- Created: 2025-04-10T15:32:26.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-29T19:03:26.000Z (about 1 year ago)
- Last Synced: 2025-06-03T19:52:56.973Z (about 1 year ago)
- Language: Kotlin
- Size: 159 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README

[](https://mvn.devos.one/#/releases/io/github/dockyardmc/dockyard)
[](https://kotlinlang.org/)
[](https://wakatime.com/badge/github/DockyardMC/Dockyard)
[](https://discord.gg/SA9nmfMkdc)
[](https://ko-fi.com/LukynkaCZE)
Tide is a Kotlin codec library that allows for serializing to network protocol and JSON while allowing other formats to be integrated via use custom Transcoders.
It is purpose built for the [DockyardMC](https://github.com/DockyardMC/Dockyard) project which is reimplementation of the Minecraft server protocol so **some primitive types like **`Strings`**, **`Lists`** and **`Maps`** are not using the standard format, but they are following the Minecraft protocol's implementation**
## Installation
**Kotlin DSL**
```kotlin
repositories {
maven {
name = "devOS"
url = uri("https://mvn.devos.one/releases")
}
}
dependencies {
implementation("io.github.dockyardmc:tide:1.7")
}
```
---
## Usage
You can create a codec like this:
```kotlin
data class Person(val name: String, val age: Int) {
companion object {
val codec = Codec.of {
field("name", Primitives.String, Person::name)
field("age", Primitives.Int, Person::age)
}
}
}
```
You can either serialize it into a network type by calling the `Codec#writeNetwork` or into json by calling `Codec#writeJson`
---
You can include other codecs inside a codec to create more complex types:
```kotlin
data class Bus(val model: String, val driver: Person, val passengers: List) {
companion object {
val codec = Codec.of {
field("name", Primitives.String, Bus::model)
field("driver", Person.codec, Bus::driver)
field("passengers", Person.codec.list(), Bus::passengers)
}
}
}
```
---
To use lists you can simply call `Codec#list` on existing codec like this:
```kotlin
data class Book(val pages: List) {
companion object {
val codec = Codec.of {
field("pages", Primitives.String.list(), Book::pages)
}
}
}
```
---
To use maps, you can either use `Codec#mapAsKeyTo` which will create map of the current codec as key and provided codec as value or Codec#mapAsValueTo which will use the current coded as value and provided coded as key:
```kotlin
data class WarehouseInventory(val iceCreamFlavours: Map, val cookieFlavours: Map) {
companion object {
val codec = Codec.of {
field("ice_cream_flavours", Primitives.String.mapAsKeyTo(Primitives.VarInt), WarehouseInventory::iceCreamFlavours) //uses current as key of the map
field("cookie_flavours", Primitives.Int.mapAsValueTo(Primitives.String), WarehouseInventory::cookieFlavours) // uses current as value of the map
}
}
}
```
---
Optionals are Minecraft protocol specific type. They represent the Java `Optional` class. Optionals in protocol consist of a `boolean` field which indicates if the value is present or not and the actual value. To make things simple, Tide returns **nullable values** instead of the java `Optional` classes
You can use the `Codec#optional` to make the field optional:
```kotlin
data class Book(val pages: List, val synopsis: String?) {
companion object {
val codec = Codec.of {
field("pages", Primitives.String.list(), Book::pages)
field("synopsis", Primitives.String.optional(), Book::synopsis)
}
}
}
```
---
Enums are a special case because in the Minecraft protocol they are represented by VarInt type which is a variable length integer. The value is the ordinal (the index in the entries) of the enum value
You will need to use `Codec#enum` to create this codec which has a class field to provide the class of the enum for inner reflection shenanigans:
```kotlin
data class Book(val pages: List, val synopsis: String?, val type: Book.Type) {
enum class Type {
HORROR,
SCI_FI,
MEDIEVAL,
FANTASY,
FICTION,
ADVENTURE,
THRILLER,
MANGA,
HENTAI
}
companion object {
val codec = Codec.of {
field("pages", Primitives.String.list(), Book::pages)
field("synopsis", Primitives.String.optional(), Book::synopsis)
field("type", Codec.enum(Book.Type::class), Book::type)
}
}
}
```