diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/Marker.java b/api/src/main/java/com/lunarclient/apollo/module/marker/Marker.java
new file mode 100644
index 00000000..1343d512
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/Marker.java
@@ -0,0 +1,168 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker;
+
+import com.lunarclient.apollo.common.location.ApolloLocation;
+import com.lunarclient.apollo.module.marker.display.MarkerFlag;
+import com.lunarclient.apollo.module.marker.target.BlockMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.EntityMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.ItemMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.MarkerTarget;
+import com.lunarclient.apollo.module.marker.target.PlayerMarkerTarget;
+import java.awt.Color;
+import java.time.Duration;
+import java.util.UUID;
+import lombok.Builder;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Represents a marker which can be shown on the client.
+ *
+ * @since 1.2.8
+ */
+@Getter
+@Builder
+public final class Marker {
+
+ /**
+ * Returns the marker {@link String} id.
+ *
+ * @return the marker id
+ * @since 1.2.8
+ */
+ @NotNull String id;
+
+ /**
+ * Returns the marker {@link ApolloLocation}.
+ *
+ * @return the marker location
+ * @since 1.2.8
+ */
+ @NotNull ApolloLocation location;
+
+ /**
+ * Returns the marker owner's {@link UUID}.
+ *
+ *
Used to show the owner head.
+ *
+ * @return the owner uuid
+ * @since 1.2.8
+ */
+ @NotNull UUID ownerId;
+
+ /**
+ * Returns the marker owner's {@link String} name.
+ *
+ * @return the owner name
+ * @since 1.2.8
+ */
+ @NotNull String ownerName;
+
+ /**
+ * Returns the {@link MarkerFlag} (icon shape and base color) of this marker.
+ *
+ * @return the marker flag
+ * @since 1.2.8
+ */
+ @NotNull MarkerFlag flag;
+
+ /**
+ * Returns the {@link Color} override for this marker's {@link #flag}.
+ *
+ * Leave {@code null} to use the player's own configured color for the
+ * selected flag.
+ *
+ * @return the flag color override, or {@code null} to defer to the player's setting
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @Nullable Color color = null;
+
+ /**
+ * Returns the {@link MarkerTarget} describing what this marker marks.
+ *
+ * Drives the description icon and text shown on the client. One of
+ * {@link ItemMarkerTarget}, {@link BlockMarkerTarget}, {@link EntityMarkerTarget}
+ * or {@link PlayerMarkerTarget}.
+ *
+ * @return the marker target
+ * @since 1.2.8
+ */
+ @NotNull MarkerTarget target;
+
+ /**
+ * Returns the {@link Duration} the marker remains visible.
+ *
+ * Leave {@code null} to defer to the player's configured marker
+ * duration.
+ *
+ * @return the duration, or {@code null} to defer to the player's setting
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @Nullable Duration duration = null;
+
+ /**
+ * Returns whether a popup notification is shown when this marker first appears.
+ *
+ * @return whether an in-game notification is shown
+ * @since 1.2.8
+ */
+ @Builder.Default
+ boolean inGameNotification = false;
+
+ /**
+ * Returns whether a chat message is sent when this marker first appears.
+ *
+ * @return whether an in-game chat message is sent
+ * @since 1.2.8
+ */
+ @Builder.Default
+ boolean chatNotify = false;
+
+ /**
+ * Returns whether the player can middle-click to remove this marker.
+ *
+ * @return the middle-click removal state
+ * @since 1.2.8
+ */
+ @Builder.Default
+ boolean middleClickRemove = true;
+
+ /**
+ * Returns the {@link MarkerStyle} overrides applied to this marker.
+ *
+ * Set to a built {@link MarkerStyle} to drive the marker's appearance
+ * from the server; leave {@code null} to defer entirely to the player's
+ * own Markers mod settings.
+ *
+ * @return the style overrides, or {@code null} when no override is sent
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @Nullable MarkerStyle style = null;
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/MarkerModule.java b/api/src/main/java/com/lunarclient/apollo/module/marker/MarkerModule.java
new file mode 100644
index 00000000..54d048ca
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/MarkerModule.java
@@ -0,0 +1,75 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker;
+
+import com.lunarclient.apollo.module.ApolloModule;
+import com.lunarclient.apollo.module.ModuleDefinition;
+import com.lunarclient.apollo.recipients.Recipients;
+import org.jetbrains.annotations.ApiStatus;
+
+/**
+ * Represents the marker module.
+ *
+ * @since 1.2.8
+ */
+@ApiStatus.NonExtendable
+@ModuleDefinition(id = "marker", name = "Marker")
+public abstract class MarkerModule extends ApolloModule {
+
+ /**
+ * Displays the {@link Marker} to the {@link Recipients}.
+ *
+ * @param recipients the recipients that are receiving the packet
+ * @param marker the marker
+ * @since 1.2.8
+ */
+ public abstract void displayMarker(Recipients recipients, Marker marker);
+
+ /**
+ * Removes the {@link Marker} from the {@link Recipients}.
+ *
+ * @param recipients the recipients that are receiving the packet
+ * @param markerId the marker id
+ * @since 1.2.8
+ */
+ public abstract void removeMarker(Recipients recipients, String markerId);
+
+ /**
+ * Removes the {@link Marker} from the {@link Recipients}.
+ *
+ * @param recipients the recipients that are receiving the packet
+ * @param marker the marker
+ * @since 1.2.8
+ */
+ public abstract void removeMarker(Recipients recipients, Marker marker);
+
+ /**
+ * Resets all {@link Marker}s for the {@link Recipients}.
+ *
+ * @param recipients the recipients that are receiving the packet
+ * @since 1.2.8
+ */
+ public abstract void resetMarkers(Recipients recipients);
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/MarkerStyle.java b/api/src/main/java/com/lunarclient/apollo/module/marker/MarkerStyle.java
new file mode 100644
index 00000000..aa96514b
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/MarkerStyle.java
@@ -0,0 +1,138 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker;
+
+import com.lunarclient.apollo.module.marker.display.MarkerDescriptionDisplay;
+import com.lunarclient.apollo.module.marker.display.MarkerDisplayCondition;
+import com.lunarclient.apollo.module.marker.display.MarkerOwnerDisplay;
+import lombok.Builder;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Overrides for a marker's appearance, owner/description display and text on the Lunar client.
+ *
+ * @since 1.2.8
+ */
+@Getter
+@Builder
+public final class MarkerStyle {
+
+ /**
+ * The scale applied to the marker.
+ *
+ * Accepts {@code 0.5F} to {@code 2.0F}.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ float scale = 1.0F;
+
+ /**
+ * Whether the marker plays its hover animations.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ boolean animateMarkerOnHover = true;
+
+ /**
+ * Whether the marker uses the compact single-row layout.
+ *
+ * When {@code true}, {@link #ownerDisplay}, {@link #descriptionDisplay} and
+ * {@link #ownerSuffix} are ignored; the compact layout always uses the owner head,
+ * description icon and shows no suffix.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ boolean compactMode = false;
+
+ /**
+ * Whether a shadow is drawn behind the marker's text.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ boolean textShadow = true;
+
+ /**
+ * The suffix appended after the owner name.
+ *
+ * Set to an empty {@link String} to show no suffix.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull String ownerSuffix = "'s Marker";
+
+ /**
+ * How the marker's owner is displayed.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull MarkerOwnerDisplay ownerDisplay = MarkerOwnerDisplay.HEAD;
+
+ /**
+ * When the marker's owner is shown.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull MarkerDisplayCondition showOwner = MarkerDisplayCondition.ALWAYS;
+
+ /**
+ * When the marker's coordinates are shown.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull MarkerDisplayCondition showCoordinates = MarkerDisplayCondition.NEVER;
+
+ /**
+ * When the distance from the player to the marker is shown.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull MarkerDisplayCondition showDistance = MarkerDisplayCondition.HOVER;
+
+ /**
+ * When the marker's description (what was marked) is shown.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull MarkerDisplayCondition showDescription = MarkerDisplayCondition.HOVER;
+
+ /**
+ * How the marker's description is displayed.
+ *
+ * @since 1.2.8
+ */
+ @Builder.Default
+ @NotNull MarkerDescriptionDisplay descriptionDisplay = MarkerDescriptionDisplay.ICON;
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerDescriptionDisplay.java b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerDescriptionDisplay.java
new file mode 100644
index 00000000..9800bb52
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerDescriptionDisplay.java
@@ -0,0 +1,35 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.display;
+
+/**
+ * Represents how a marker's description (what was marked) is displayed.
+ *
+ * @since 1.2.8
+ */
+public enum MarkerDescriptionDisplay {
+ ICON,
+ TEXT
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerDisplayCondition.java b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerDisplayCondition.java
new file mode 100644
index 00000000..3ea829a0
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerDisplayCondition.java
@@ -0,0 +1,36 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.display;
+
+/**
+ * Represents when part of a marker (owner, description, coordinates, distance) is shown.
+ *
+ * @since 1.2.8
+ */
+public enum MarkerDisplayCondition {
+ NEVER,
+ HOVER,
+ ALWAYS
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerFlag.java b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerFlag.java
new file mode 100644
index 00000000..44a3ac8d
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerFlag.java
@@ -0,0 +1,37 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.display;
+
+/**
+ * Represents a marker flag.
+ *
+ * @since 1.2.8
+ */
+public enum MarkerFlag {
+ NORMAL,
+ DANGER,
+ INFO,
+ INTEREST
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerOwnerDisplay.java b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerOwnerDisplay.java
new file mode 100644
index 00000000..f90c467f
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/display/MarkerOwnerDisplay.java
@@ -0,0 +1,35 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.display;
+
+/**
+ * Represents how a marker's owner is displayed.
+ *
+ * @since 1.2.8
+ */
+public enum MarkerOwnerDisplay {
+ HEAD,
+ NAME
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/target/BlockMarkerTarget.java b/api/src/main/java/com/lunarclient/apollo/module/marker/target/BlockMarkerTarget.java
new file mode 100644
index 00000000..d17234dd
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/target/BlockMarkerTarget.java
@@ -0,0 +1,48 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.target;
+
+import com.lunarclient.apollo.common.icon.ItemStackIcon;
+import com.lunarclient.apollo.module.marker.Marker;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * Represents a {@link Marker} that marks a block.
+ *
+ * @since 1.2.8
+ */
+@Getter
+@Builder
+public class BlockMarkerTarget extends MarkerTarget {
+
+ /**
+ * Returns the {@link ItemStackIcon} of the marked block.
+ *
+ * @return the item stack icon
+ * @since 1.2.8
+ */
+ ItemStackIcon itemStack;
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/target/EntityMarkerTarget.java b/api/src/main/java/com/lunarclient/apollo/module/marker/target/EntityMarkerTarget.java
new file mode 100644
index 00000000..bce76c00
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/target/EntityMarkerTarget.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.target;
+
+import com.lunarclient.apollo.module.marker.Marker;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * Represents a {@link Marker} that marks an entity.
+ *
+ * @since 1.2.8
+ */
+@Getter
+@Builder
+public class EntityMarkerTarget extends MarkerTarget {
+
+ /**
+ * Returns the marked entity type's registry name.
+ *
+ * @return the entity type registry name, e.g. {@code minecraft:zombie}
+ * @since 1.2.8
+ */
+ String entityType;
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/target/ItemMarkerTarget.java b/api/src/main/java/com/lunarclient/apollo/module/marker/target/ItemMarkerTarget.java
new file mode 100644
index 00000000..3b1bd20a
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/target/ItemMarkerTarget.java
@@ -0,0 +1,48 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.target;
+
+import com.lunarclient.apollo.common.icon.ItemStackIcon;
+import com.lunarclient.apollo.module.marker.Marker;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * Represents a {@link Marker} that marks an item.
+ *
+ * @since 1.2.8
+ */
+@Getter
+@Builder
+public class ItemMarkerTarget extends MarkerTarget {
+
+ /**
+ * Returns the {@link ItemStackIcon} of the marked item.
+ *
+ * @return the item stack icon
+ * @since 1.2.8
+ */
+ ItemStackIcon itemStack;
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/target/MarkerTarget.java b/api/src/main/java/com/lunarclient/apollo/module/marker/target/MarkerTarget.java
new file mode 100644
index 00000000..133e2ef8
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/target/MarkerTarget.java
@@ -0,0 +1,39 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.target;
+
+import com.lunarclient.apollo.module.marker.Marker;
+
+/**
+ * The abstract base class for what a {@link Marker} marks, which drives the description icon
+ * and text shown on the client.
+ *
+ * Use one of {@link ItemMarkerTarget}, {@link BlockMarkerTarget}, {@link EntityMarkerTarget}
+ * or {@link PlayerMarkerTarget}.
+ *
+ * @since 1.2.8
+ */
+public abstract class MarkerTarget {
+
+}
diff --git a/api/src/main/java/com/lunarclient/apollo/module/marker/target/PlayerMarkerTarget.java b/api/src/main/java/com/lunarclient/apollo/module/marker/target/PlayerMarkerTarget.java
new file mode 100644
index 00000000..cb069d8e
--- /dev/null
+++ b/api/src/main/java/com/lunarclient/apollo/module/marker/target/PlayerMarkerTarget.java
@@ -0,0 +1,56 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker.target;
+
+import com.lunarclient.apollo.module.marker.Marker;
+import java.util.UUID;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * Represents a {@link Marker} that marks a player.
+ *
+ * @since 1.2.8
+ */
+@Getter
+@Builder
+public class PlayerMarkerTarget extends MarkerTarget {
+
+ /**
+ * Returns the marked player's {@link UUID}.
+ *
+ * @return the player uuid
+ * @since 1.2.8
+ */
+ UUID playerId;
+
+ /**
+ * Returns the marked player's {@link String} name.
+ *
+ * @return the player name
+ * @since 1.2.8
+ */
+ String playerName;
+
+}
diff --git a/common/src/main/java/com/lunarclient/apollo/module/marker/MarkerModuleImpl.java b/common/src/main/java/com/lunarclient/apollo/module/marker/MarkerModuleImpl.java
new file mode 100644
index 00000000..ccd37cec
--- /dev/null
+++ b/common/src/main/java/com/lunarclient/apollo/module/marker/MarkerModuleImpl.java
@@ -0,0 +1,219 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.module.marker;
+
+import com.lunarclient.apollo.ApolloManager;
+import com.lunarclient.apollo.marker.v1.BlockTarget;
+import com.lunarclient.apollo.marker.v1.DangerMarker;
+import com.lunarclient.apollo.marker.v1.DisplayMarkerMessage;
+import com.lunarclient.apollo.marker.v1.EntityTarget;
+import com.lunarclient.apollo.marker.v1.InfoMarker;
+import com.lunarclient.apollo.marker.v1.InterestMarker;
+import com.lunarclient.apollo.marker.v1.ItemTarget;
+import com.lunarclient.apollo.marker.v1.NormalMarker;
+import com.lunarclient.apollo.marker.v1.PlayerTarget;
+import com.lunarclient.apollo.marker.v1.RemoveMarkerMessage;
+import com.lunarclient.apollo.marker.v1.ResetMarkersMessage;
+import com.lunarclient.apollo.module.marker.display.MarkerDescriptionDisplay;
+import com.lunarclient.apollo.module.marker.display.MarkerDisplayCondition;
+import com.lunarclient.apollo.module.marker.display.MarkerFlag;
+import com.lunarclient.apollo.module.marker.display.MarkerOwnerDisplay;
+import com.lunarclient.apollo.module.marker.target.BlockMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.EntityMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.ItemMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.MarkerTarget;
+import com.lunarclient.apollo.module.marker.target.PlayerMarkerTarget;
+import com.lunarclient.apollo.network.NetworkTypes;
+import com.lunarclient.apollo.recipients.Recipients;
+import java.awt.Color;
+import java.time.Duration;
+import lombok.NonNull;
+
+import static com.lunarclient.apollo.util.Ranges.checkRange;
+
+/**
+ * Provides the marker module.
+ *
+ * @since 1.2.8
+ */
+public final class MarkerModuleImpl extends MarkerModule {
+
+ @Override
+ public void displayMarker(@NonNull Recipients recipients, @NonNull Marker marker) {
+ DisplayMarkerMessage message = this.toProtobuf(marker);
+ ApolloManager.getNetworkManager().sendPacket(recipients, message);
+ }
+
+ @Override
+ public void removeMarker(@NonNull Recipients recipients, @NonNull String markerId) {
+ RemoveMarkerMessage message = RemoveMarkerMessage.newBuilder()
+ .setId(markerId)
+ .build();
+
+ ApolloManager.getNetworkManager().sendPacket(recipients, message);
+ }
+
+ @Override
+ public void removeMarker(@NonNull Recipients recipients, @NonNull Marker marker) {
+ this.removeMarker(recipients, marker.getId());
+ }
+
+ @Override
+ public void resetMarkers(@NonNull Recipients recipients) {
+ ResetMarkersMessage message = ResetMarkersMessage.getDefaultInstance();
+ ApolloManager.getNetworkManager().sendPacket(recipients, message);
+ }
+
+ private DisplayMarkerMessage toProtobuf(Marker marker) {
+ DisplayMarkerMessage.Builder builder = DisplayMarkerMessage.newBuilder()
+ .setId(marker.getId())
+ .setLocation(NetworkTypes.toProtobuf(marker.getLocation()))
+ .setOwnerId(NetworkTypes.toProtobuf(marker.getOwnerId()))
+ .setOwnerName(marker.getOwnerName())
+ .setInGameNotification(marker.isInGameNotification())
+ .setChatNotify(marker.isChatNotify())
+ .setMiddleClickRemove(marker.isMiddleClickRemove());
+
+ this.applyFlag(builder, marker.getFlag(), marker.getColor());
+ builder.setTarget(this.toProtobuf(marker.getTarget()));
+
+ Duration duration = marker.getDuration();
+ if (duration != null) {
+ builder.setDuration(NetworkTypes.toProtobuf(duration));
+ }
+
+ MarkerStyle style = marker.getStyle();
+ if (style != null) {
+ builder.setStyle(this.toProtobuf(style));
+ }
+
+ return builder.build();
+ }
+
+ private void applyFlag(DisplayMarkerMessage.Builder builder, MarkerFlag flag, Color color) {
+ com.lunarclient.apollo.common.v1.Color protoColor = color == null ? null : NetworkTypes.toProtobuf(color);
+ com.lunarclient.apollo.marker.v1.MarkerFlag.Builder flagBuilder = com.lunarclient.apollo.marker.v1.MarkerFlag.newBuilder();
+
+ switch (flag) {
+ case NORMAL: {
+ NormalMarker.Builder normal = NormalMarker.newBuilder();
+ if (protoColor != null) {
+ normal.setColor(protoColor);
+ }
+ flagBuilder.setNormal(normal.build());
+ break;
+ }
+
+ case DANGER: {
+ DangerMarker.Builder danger = DangerMarker.newBuilder();
+ if (protoColor != null) {
+ danger.setColor(protoColor);
+ }
+ flagBuilder.setDanger(danger.build());
+ break;
+ }
+
+ case INFO: {
+ InfoMarker.Builder info = InfoMarker.newBuilder();
+ if (protoColor != null) {
+ info.setColor(protoColor);
+ }
+ flagBuilder.setInfo(info.build());
+ break;
+ }
+
+ case INTEREST: {
+ InterestMarker.Builder interest = InterestMarker.newBuilder();
+ if (protoColor != null) {
+ interest.setColor(protoColor);
+ }
+ flagBuilder.setInterest(interest.build());
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unknown marker flag: " + flag);
+ }
+ }
+
+ builder.setFlag(flagBuilder.build());
+ }
+
+ private com.lunarclient.apollo.marker.v1.MarkerTarget toProtobuf(MarkerTarget target) {
+ com.lunarclient.apollo.marker.v1.MarkerTarget.Builder builder = com.lunarclient.apollo.marker.v1.MarkerTarget.newBuilder();
+
+ if (target instanceof ItemMarkerTarget) {
+ builder.setItem(ItemTarget.newBuilder()
+ .setItemStack(NetworkTypes.toProtobuf(((ItemMarkerTarget) target).getItemStack()))
+ .build());
+ } else if (target instanceof BlockMarkerTarget) {
+ builder.setBlock(BlockTarget.newBuilder()
+ .setItemStack(NetworkTypes.toProtobuf(((BlockMarkerTarget) target).getItemStack()))
+ .build());
+ } else if (target instanceof EntityMarkerTarget) {
+ builder.setEntity(EntityTarget.newBuilder()
+ .setEntityType(((EntityMarkerTarget) target).getEntityType())
+ .build());
+ } else if (target instanceof PlayerMarkerTarget) {
+ PlayerMarkerTarget player = (PlayerMarkerTarget) target;
+ builder.setPlayer(PlayerTarget.newBuilder()
+ .setUuid(NetworkTypes.toProtobuf(player.getPlayerId()))
+ .setName(player.getPlayerName())
+ .build());
+ } else {
+ throw new IllegalArgumentException("Unknown marker target type: " + target.getClass().getName());
+ }
+
+ return builder.build();
+ }
+
+ private com.lunarclient.apollo.marker.v1.MarkerStyle toProtobuf(MarkerStyle style) {
+ return com.lunarclient.apollo.marker.v1.MarkerStyle.newBuilder()
+ .setScale(checkRange(style.getScale(), 0.5F, 2.0F, "MarkerStyle#scale"))
+ .setAnimateMarkerOnHover(style.isAnimateMarkerOnHover())
+ .setCompactMode(style.isCompactMode())
+ .setTextShadow(style.isTextShadow())
+ .setOwnerSuffix(style.getOwnerSuffix())
+ .setOwnerDisplay(this.toProtobuf(style.getOwnerDisplay()))
+ .setShowOwner(this.toProtobuf(style.getShowOwner()))
+ .setShowCoordinates(this.toProtobuf(style.getShowCoordinates()))
+ .setShowDistance(this.toProtobuf(style.getShowDistance()))
+ .setShowDescription(this.toProtobuf(style.getShowDescription()))
+ .setDescriptionDisplay(this.toProtobuf(style.getDescriptionDisplay()))
+ .build();
+ }
+
+ private com.lunarclient.apollo.marker.v1.MarkerDisplayCondition toProtobuf(MarkerDisplayCondition condition) {
+ return com.lunarclient.apollo.marker.v1.MarkerDisplayCondition.forNumber(condition.ordinal() + 1);
+ }
+
+ private com.lunarclient.apollo.marker.v1.MarkerOwnerDisplay toProtobuf(MarkerOwnerDisplay display) {
+ return com.lunarclient.apollo.marker.v1.MarkerOwnerDisplay.forNumber(display.ordinal() + 1);
+ }
+
+ private com.lunarclient.apollo.marker.v1.MarkerDescriptionDisplay toProtobuf(MarkerDescriptionDisplay display) {
+ return com.lunarclient.apollo.marker.v1.MarkerDescriptionDisplay.forNumber(display.ordinal() + 1);
+ }
+
+}
diff --git a/docs/developers/modules/_meta.json b/docs/developers/modules/_meta.json
index 1f3fba9c..182a8a35 100644
--- a/docs/developers/modules/_meta.json
+++ b/docs/developers/modules/_meta.json
@@ -12,6 +12,7 @@
"hologram": "Hologram",
"inventory": "Inventory",
"limb": "Limb",
+ "marker": "Marker",
"modsetting": "Mod Setting",
"nametag": "Nametag",
"nickhider": "Nick Hider",
diff --git a/docs/developers/modules/marker.mdx b/docs/developers/modules/marker.mdx
new file mode 100644
index 00000000..de64861a
--- /dev/null
+++ b/docs/developers/modules/marker.mdx
@@ -0,0 +1,688 @@
+import { Callout, Tab, Tabs } from 'nextra-theme-docs'
+
+# Marker Module
+
+## Overview
+
+The marker module allows you to place in-world markers from Lunar Client's Markers mod.
+
+- Place a marker at any exact location, attributed to any owner.
+- Pick the marker flag (Normal, Danger, Info, Interest) and optionally override its color.
+- Describe what is marked (an item, block, entity or player) to drive the marker's description icon and text.
+- Override the appearance per marker
+
+
+
+
+ Create your own custom indicators using the Lunar Client Markers mod.
+
+
+## Integration
+
+Explore each integration by cycling through each tab, to find the best fit for your requirements and needs.
+
+### Sample Code
+
+
+
+
+
+
+**Apollo API examples.** See [General](/apollo/developers/general) for common patterns and helpers.
+
+
+### Marking a block
+
+```java
+public void displayBlockMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("loot-chest")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(viewer.getUniqueId())
+ .ownerName("")
+ .flag(MarkerFlag.INTEREST)
+ .target(BlockMarkerTarget.builder()
+ .itemStack(ItemStackIcon.builder().itemName("minecraft:chest").build())
+ .build())
+ .duration(Duration.ofSeconds(60))
+ .style(MarkerStyle.builder()
+ .showOwner(MarkerDisplayCondition.NEVER)
+ .showDescription(MarkerDisplayCondition.ALWAYS)
+ .build())
+ .build()
+ );
+ });
+}
+```
+
+### Marking a player
+
+```java
+public void displayPlayerMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("bounty")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(viewer.getUniqueId())
+ .ownerName(viewer.getName())
+ .flag(MarkerFlag.DANGER)
+ .color(Color.RED)
+ .target(PlayerMarkerTarget.builder()
+ .playerId(UUID.fromString("f17627d8-1a97-487b-92ea-c04f413394bd"))
+ .playerName("ItsNature")
+ .build())
+ .inGameNotification(true)
+ .style(MarkerStyle.builder()
+ .showOwner(MarkerDisplayCondition.NEVER)
+ .showDescription(MarkerDisplayCondition.ALWAYS)
+ .build())
+ .build()
+ );
+ });
+}
+```
+
+### Marking an item
+
+```java
+public void displayItemMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("wither-loot")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(viewer.getUniqueId())
+ .ownerName(viewer.getName())
+ .flag(MarkerFlag.INFO)
+ .target(ItemMarkerTarget.builder()
+ .itemStack(ItemStackIcon.builder().itemName("minecraft:nether_star").build())
+ .build())
+ .chatNotify(true)
+ .style(MarkerStyle.builder()
+ .showOwner(MarkerDisplayCondition.NEVER)
+ .showDescription(MarkerDisplayCondition.ALWAYS)
+ .build())
+ .build()
+ );
+ });
+}
+```
+
+### Marking an entity
+
+```java
+public void displayEntityMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("tutorial-npc")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(UUID.randomUUID())
+ .ownerName("Tutorial NPC")
+ .flag(MarkerFlag.INTEREST)
+ .target(EntityMarkerTarget.builder()
+ .entityType("minecraft:villager")
+ .build())
+ .style(MarkerStyle.builder()
+ .scale(1.3F)
+ .ownerSuffix("")
+ .ownerDisplay(MarkerOwnerDisplay.NAME)
+ .showOwner(MarkerDisplayCondition.HOVER)
+ .showDistance(MarkerDisplayCondition.NEVER)
+ .build())
+ .build()
+ );
+ });
+}
+```
+
+### Removing markers
+
+```java
+public void removeMarkersExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ this.markerModule.removeMarker(apolloPlayer, "loot-chest");
+ this.markerModule.removeMarker(apolloPlayer, "bounty");
+ this.markerModule.removeMarker(apolloPlayer, "wither-loot");
+ this.markerModule.removeMarker(apolloPlayer, "tutorial-npc");
+ });
+}
+```
+
+### Resetting all markers
+
+```java
+public void resetMarkersExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+ apolloPlayerOpt.ifPresent(this.markerModule::resetMarkers);
+}
+```
+
+### `Marker` Options
+
+`.id(String)` should include a unique identifier for the marker. Re-sending a marker with an existing id updates it in place.
+
+```java
+.id("loot-chest")
+```
+
+`.location(ApolloLocation)` is the exact location the marker is shown at. See the [locations utilities page](/apollo/developers/utilities/locations) for more.
+
+```java
+.location(ApolloLocation.builder()
+ .world("world")
+ .x(0.5D)
+ .y(64.0D)
+ .z(0.5D)
+ .build()
+)
+```
+
+`.ownerId(UUID)` and `.ownerName(String)` set the marker's owner. The owner's head is pulled from the player's tab list; if the owner is the viewing player they are shown as themselves.
+
+```java
+.ownerId(viewer.getUniqueId())
+.ownerName(viewer.getName())
+```
+
+`.flag(MarkerFlag)` is required and is the marker's flag, which sets its icon shape and base color. One of `NORMAL`, `DANGER`, `INFO`, `INTEREST`.
+
+```java
+.flag(MarkerFlag.DANGER)
+```
+
+`.color(java.awt.Color)` overrides the color for the chosen flag. Supports alpha. Leave unset to use the player's own configured color for that flag. See the [colors page](/apollo/developers/utilities/colors) for more.
+
+```java
+.color(Color.RED)
+```
+
+`.target(MarkerTarget)` is required and describes what is marked, which drives the description icon and text. Use an `ItemMarkerTarget` or `BlockMarkerTarget` (each wrapping an `ItemStackIcon` a block uses its item form), an `EntityMarkerTarget` (entity registry name) or a `PlayerMarkerTarget` (a player UUID + name).
+
+```java
+.target(BlockMarkerTarget.builder()
+ .itemStack(ItemStackIcon.builder().itemName("minecraft:chest").build())
+ .build())
+```
+
+`.duration(java.time.Duration)` is how long the marker stays visible. Leave unset to defer to the player's configured marker visible-duration.
+
+```java
+.duration(Duration.ofSeconds(60))
+```
+
+`.inGameNotification(boolean)` shows a Lunar pop-up when the marker first appears. Defaults to `false`.
+
+```java
+.inGameNotification(false)
+```
+
+`.chatNotify(boolean)` posts a chat message when the marker first appears. Defaults to `false`.
+
+```java
+.chatNotify(false)
+```
+
+`.middleClickRemove(boolean)` lets the player middle-click the marker to remove it. Defaults to `true`.
+
+```java
+.middleClickRemove(true)
+```
+
+`.style(MarkerStyle)` overrides the marker's appearance and text. Leave unset (or `null`) to defer entirely to the player's own Markers mod settings.
+
+
+When `compactMode` is enabled the marker uses a compact single-row layout, and
+`ownerDisplay`, `descriptionDisplay` and `ownerSuffix` are ignored.
+
+
+```java
+.style(MarkerStyle.builder()
+ .scale(1.0F) // 0.5F to 2.0F
+ .animateMarkerOnHover(true)
+ .compactMode(false)
+ .textShadow(true)
+ .ownerSuffix("'s Marker") // "" hides the suffix
+ .ownerDisplay(MarkerOwnerDisplay.HEAD)
+ .showOwner(MarkerDisplayCondition.ALWAYS)
+ .showCoordinates(MarkerDisplayCondition.NEVER)
+ .showDistance(MarkerDisplayCondition.HOVER)
+ .showDescription(MarkerDisplayCondition.HOVER)
+ .descriptionDisplay(MarkerDescriptionDisplay.ICON)
+ .build()
+)
+```
+
+
+
+
+
+
+**Lightweight Protobuf examples.** See [Lightweight Protobuf](/apollo/developers/lightweight/protobuf) for setup.
+
+
+
+ Make sure the server is sending the world name to the client as shown in the [Player Detection](/apollo/developers/lightweight/protobuf/player-detection) example.
+
+
+**Marking a block**
+
+```java
+public void displayBlockMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("loot-chest")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(viewer.getUniqueId()))
+ .setOwnerName("")
+ .setFlag(MarkerFlag.newBuilder()
+ .setInterest(InterestMarker.getDefaultInstance())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setBlock(BlockTarget.newBuilder()
+ .setItemStack(ProtobufUtil.createItemStackIconProto("minecraft:chest", 0))
+ .build())
+ .build())
+ .setDuration(ProtobufUtil.createDurationProto(Duration.ofSeconds(60)))
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.0F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("'s Marker")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_HEAD)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_ALWAYS)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Marking a player**
+
+```java
+public void displayPlayerMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("bounty")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(viewer.getUniqueId()))
+ .setOwnerName(viewer.getName())
+ .setFlag(MarkerFlag.newBuilder()
+ .setDanger(DangerMarker.newBuilder()
+ .setColor(ProtobufUtil.createColorProto(Color.RED))
+ .build())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setPlayer(PlayerTarget.newBuilder()
+ .setUuid(ProtobufUtil.createUuidProto(UUID.fromString("f17627d8-1a97-487b-92ea-c04f413394bd")))
+ .setName("ItsNature")
+ .build())
+ .build())
+ .setInGameNotification(true)
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.0F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("'s Marker")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_HEAD)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_ALWAYS)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Marking an item**
+
+```java
+public void displayItemMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("wither-loot")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(viewer.getUniqueId()))
+ .setOwnerName(viewer.getName())
+ .setFlag(MarkerFlag.newBuilder()
+ .setInfo(InfoMarker.getDefaultInstance())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setItem(ItemTarget.newBuilder()
+ .setItemStack(ProtobufUtil.createItemStackIconProto("minecraft:nether_star", 0))
+ .build())
+ .build())
+ .setChatNotify(true)
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.0F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("'s Marker")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_HEAD)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_ALWAYS)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Marking an entity**
+
+```java
+public void displayEntityMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("tutorial-npc")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(UUID.randomUUID()))
+ .setOwnerName("Tutorial NPC")
+ .setFlag(MarkerFlag.newBuilder()
+ .setInterest(InterestMarker.getDefaultInstance())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setEntity(EntityTarget.newBuilder()
+ .setEntityType("minecraft:villager")
+ .build())
+ .build())
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.3F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_NAME)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Removing markers**
+
+```java
+public void removeMarkersExample(Player viewer) {
+ List markerIds = Arrays.asList("loot-chest", "bounty", "wither-loot", "tutorial-npc");
+ for (String id : markerIds) {
+ RemoveMarkerMessage message = RemoveMarkerMessage.newBuilder()
+ .setId(id)
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+}
+```
+
+**Resetting all markers**
+
+```java
+public void resetMarkersExample(Player viewer) {
+ ResetMarkersMessage message = ResetMarkersMessage.getDefaultInstance();
+ ProtobufPacketUtil.sendPacket(viewer, message);
+}
+```
+
+
+
+
+
+
+**Lightweight JSON examples.** See [Lightweight JSON](/apollo/developers/lightweight/json) for setup.
+
+
+
+ Make sure the server is sending the world name to the client as shown in the [Player Detection](/apollo/developers/lightweight/json/player-detection) example.
+
+
+**Marking a block**
+
+```java
+public void displayBlockMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "loot-chest");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(viewer.getUniqueId()));
+ message.addProperty("owner_name", "");
+
+ JsonObject flag = new JsonObject();
+ flag.add("interest", new JsonObject());
+ message.add("flag", flag);
+
+ JsonObject itemStack = new JsonObject();
+ itemStack.addProperty("item_name", "minecraft:chest");
+ JsonObject block = new JsonObject();
+ block.add("item_stack", itemStack);
+ JsonObject target = new JsonObject();
+ target.add("block", block);
+ message.add("target", target);
+
+ message.addProperty("duration", JsonUtil.createDurationObject(Duration.ofSeconds(60)));
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.0F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "'s Marker");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_HEAD");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_ALWAYS");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Marking a player**
+
+```java
+public void displayPlayerMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "bounty");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(viewer.getUniqueId()));
+ message.addProperty("owner_name", viewer.getName());
+
+ JsonObject danger = new JsonObject();
+ danger.add("color", JsonUtil.createColorObject(Color.RED));
+ JsonObject flag = new JsonObject();
+ flag.add("danger", danger);
+ message.add("flag", flag);
+
+ JsonObject player = new JsonObject();
+ player.add("uuid", JsonUtil.createUuidObject(UUID.fromString("f17627d8-1a97-487b-92ea-c04f413394bd")));
+ player.addProperty("name", "ItsNature");
+ JsonObject target = new JsonObject();
+ target.add("player", player);
+ message.add("target", target);
+
+ message.addProperty("in_game_notification", true);
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.0F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "'s Marker");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_HEAD");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_ALWAYS");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Marking an item**
+
+```java
+public void displayItemMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "wither-loot");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(viewer.getUniqueId()));
+ message.addProperty("owner_name", viewer.getName());
+
+ JsonObject flag = new JsonObject();
+ flag.add("info", new JsonObject());
+ message.add("flag", flag);
+
+ JsonObject itemStack = new JsonObject();
+ itemStack.addProperty("item_name", "minecraft:nether_star");
+ JsonObject item = new JsonObject();
+ item.add("item_stack", itemStack);
+ JsonObject target = new JsonObject();
+ target.add("item", item);
+ message.add("target", target);
+
+ message.addProperty("chat_notify", true);
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.0F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "'s Marker");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_HEAD");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_ALWAYS");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Marking an entity**
+
+```java
+public void displayEntityMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "tutorial-npc");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(UUID.randomUUID()));
+ message.addProperty("owner_name", "Tutorial NPC");
+
+ JsonObject flag = new JsonObject();
+ flag.add("interest", new JsonObject());
+ message.add("flag", flag);
+
+ JsonObject entity = new JsonObject();
+ entity.addProperty("entity_type", "minecraft:villager");
+ JsonObject target = new JsonObject();
+ target.add("entity", entity);
+ message.add("target", target);
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.3F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_NAME");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+}
+```
+
+**Removing markers**
+
+```java
+public void removeMarkersExample(Player viewer) {
+ List markerIds = Arrays.asList("loot-chest", "bounty", "wither-loot", "tutorial-npc");
+ for (String id : markerIds) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.RemoveMarkerMessage");
+ message.addProperty("id", id);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+}
+```
+
+**Resetting all markers**
+
+```java
+public void resetMarkersExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.ResetMarkersMessage");
+
+ JsonPacketUtil.sendPacket(viewer, message);
+}
+```
+
+
+
+
diff --git a/docs/public/modules/marker/overview.gif b/docs/public/modules/marker/overview.gif
new file mode 100644
index 00000000..a84d934e
Binary files /dev/null and b/docs/public/modules/marker/overview.gif differ
diff --git a/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/ApolloApiExamplePlatform.java b/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/ApolloApiExamplePlatform.java
index 5b26d6f8..2ae26a66 100644
--- a/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/ApolloApiExamplePlatform.java
+++ b/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/ApolloApiExamplePlatform.java
@@ -42,6 +42,7 @@
import com.lunarclient.apollo.example.api.module.GlowApiExample;
import com.lunarclient.apollo.example.api.module.HologramApiExample;
import com.lunarclient.apollo.example.api.module.LimbApiExample;
+import com.lunarclient.apollo.example.api.module.MarkerApiExample;
import com.lunarclient.apollo.example.api.module.ModSettingsApiExample;
import com.lunarclient.apollo.example.api.module.NametagApiExample;
import com.lunarclient.apollo.example.api.module.NickHiderApiExample;
@@ -94,6 +95,7 @@ public void registerModuleExamples() {
this.setGlowExample(new GlowApiExample());
this.setHologramExample(new HologramApiExample());
this.setLimbExample(new LimbApiExample());
+ this.setMarkerExample(new MarkerApiExample());
this.setModSettingsExample(new ModSettingsApiExample());
this.setNametagExample(new NametagApiExample());
this.setNickHiderExample(new NickHiderApiExample());
diff --git a/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/module/MarkerApiExample.java b/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/module/MarkerApiExample.java
new file mode 100644
index 00000000..ce51ea85
--- /dev/null
+++ b/example/bukkit/api/src/main/java/com/lunarclient/apollo/example/api/module/MarkerApiExample.java
@@ -0,0 +1,203 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.example.api.module;
+
+import com.lunarclient.apollo.Apollo;
+import com.lunarclient.apollo.common.icon.ItemStackIcon;
+import com.lunarclient.apollo.common.location.ApolloLocation;
+import com.lunarclient.apollo.example.module.impl.MarkerExample;
+import com.lunarclient.apollo.module.marker.Marker;
+import com.lunarclient.apollo.module.marker.MarkerModule;
+import com.lunarclient.apollo.module.marker.MarkerStyle;
+import com.lunarclient.apollo.module.marker.display.MarkerDisplayCondition;
+import com.lunarclient.apollo.module.marker.display.MarkerFlag;
+import com.lunarclient.apollo.module.marker.display.MarkerOwnerDisplay;
+import com.lunarclient.apollo.module.marker.target.BlockMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.EntityMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.ItemMarkerTarget;
+import com.lunarclient.apollo.module.marker.target.PlayerMarkerTarget;
+import com.lunarclient.apollo.player.ApolloPlayer;
+import java.awt.Color;
+import java.time.Duration;
+import java.util.Optional;
+import java.util.UUID;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+public class MarkerApiExample extends MarkerExample {
+
+ private final MarkerModule markerModule = Apollo.getModuleManager().getModule(MarkerModule.class);
+
+ @Override
+ public void displayBlockMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("loot-chest")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(viewer.getUniqueId())
+ .ownerName("")
+ .flag(MarkerFlag.INTEREST)
+ .target(BlockMarkerTarget.builder()
+ .itemStack(ItemStackIcon
+ .builder()
+ .itemName("minecraft:chest")
+ .build())
+ .build())
+ .duration(Duration.ofSeconds(60))
+ .style(MarkerStyle.builder()
+ .showOwner(MarkerDisplayCondition.NEVER)
+ .showDescription(MarkerDisplayCondition.ALWAYS)
+ .build())
+ .build()
+ );
+ });
+ }
+
+ @Override
+ public void displayPlayerMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("bounty")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(viewer.getUniqueId())
+ .ownerName(viewer.getName())
+ .flag(MarkerFlag.DANGER)
+ .color(Color.RED)
+ .target(PlayerMarkerTarget.builder()
+ .playerId(UUID.fromString("f17627d8-1a97-487b-92ea-c04f413394bd"))
+ .playerName("ItsNature")
+ .build())
+ .inGameNotification(true)
+ .style(MarkerStyle.builder()
+ .showOwner(MarkerDisplayCondition.NEVER)
+ .showDescription(MarkerDisplayCondition.ALWAYS)
+ .build())
+ .build()
+ );
+ });
+ }
+
+ @Override
+ public void displayItemMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("wither-loot")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(viewer.getUniqueId())
+ .ownerName(viewer.getName())
+ .flag(MarkerFlag.INFO)
+ .target(ItemMarkerTarget.builder()
+ .itemStack(ItemStackIcon
+ .builder()
+ .itemName("minecraft:nether_star")
+ .build())
+ .build())
+ .style(MarkerStyle.builder()
+ .showOwner(MarkerDisplayCondition.NEVER)
+ .showDescription(MarkerDisplayCondition.ALWAYS)
+ .build())
+ .build()
+ );
+ });
+ }
+
+ @Override
+ public void displayEntityMarkerExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ Location location = viewer.getLocation();
+
+ this.markerModule.displayMarker(apolloPlayer, Marker.builder()
+ .id("tutorial-npc")
+ .location(ApolloLocation.builder()
+ .world(location.getWorld().getName())
+ .x(location.getX())
+ .y(location.getY())
+ .z(location.getZ())
+ .build())
+ .ownerId(UUID.randomUUID())
+ .ownerName("Tutorial NPC")
+ .flag(MarkerFlag.INTEREST)
+ .target(EntityMarkerTarget.builder()
+ .entityType("minecraft:villager")
+ .build())
+ .style(MarkerStyle.builder()
+ .scale(1.3F)
+ .ownerSuffix("")
+ .ownerDisplay(MarkerOwnerDisplay.NAME)
+ .showOwner(MarkerDisplayCondition.HOVER)
+ .showDistance(MarkerDisplayCondition.NEVER)
+ .build())
+ .build()
+ );
+ });
+ }
+
+ @Override
+ public void removeMarkersExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+
+ apolloPlayerOpt.ifPresent(apolloPlayer -> {
+ this.markerModule.removeMarker(apolloPlayer, "loot-chest");
+ this.markerModule.removeMarker(apolloPlayer, "bounty");
+ this.markerModule.removeMarker(apolloPlayer, "wither-loot");
+ this.markerModule.removeMarker(apolloPlayer, "tutorial-npc");
+ });
+ }
+
+ @Override
+ public void resetMarkersExample(Player viewer) {
+ Optional apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
+ apolloPlayerOpt.ifPresent(this.markerModule::resetMarkers);
+ }
+
+}
diff --git a/example/bukkit/api/src/main/resources/plugin.yml b/example/bukkit/api/src/main/resources/plugin.yml
index 9bc92e8b..57422037 100644
--- a/example/bukkit/api/src/main/resources/plugin.yml
+++ b/example/bukkit/api/src/main/resources/plugin.yml
@@ -42,6 +42,8 @@ commands:
description: "Inventory!"
limb:
description: "Limb!"
+ marker:
+ description: "Markers!"
modsettings:
description: "ModSettings!"
nametag:
diff --git a/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/ApolloExamplePlugin.java b/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/ApolloExamplePlugin.java
index 9d29803e..c39d80f2 100644
--- a/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/ApolloExamplePlugin.java
+++ b/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/ApolloExamplePlugin.java
@@ -37,6 +37,7 @@
import com.lunarclient.apollo.example.command.HologramCommand;
import com.lunarclient.apollo.example.command.InventoryCommand;
import com.lunarclient.apollo.example.command.LimbCommand;
+import com.lunarclient.apollo.example.command.MarkerCommand;
import com.lunarclient.apollo.example.command.ModSettingsCommand;
import com.lunarclient.apollo.example.command.NametagCommand;
import com.lunarclient.apollo.example.command.NickHiderCommand;
@@ -70,6 +71,7 @@
import com.lunarclient.apollo.example.module.impl.HologramExample;
import com.lunarclient.apollo.example.module.impl.InventoryExample;
import com.lunarclient.apollo.example.module.impl.LimbExample;
+import com.lunarclient.apollo.example.module.impl.MarkerExample;
import com.lunarclient.apollo.example.module.impl.ModSettingsExample;
import com.lunarclient.apollo.example.module.impl.NametagExample;
import com.lunarclient.apollo.example.module.impl.NickHiderExample;
@@ -115,6 +117,7 @@ public abstract class ApolloExamplePlugin extends JavaPlugin {
private HologramExample hologramExample;
private InventoryExample inventoryExample;
private LimbExample limbExample;
+ private MarkerExample markerExample;
private ModSettingsExample modSettingsExample;
private NametagExample nametagExample;
private NickHiderExample nickHiderExample;
@@ -173,6 +176,7 @@ private void registerCommonCommands() {
this.getCommand("hologram").setExecutor(new HologramCommand());
this.getCommand("inventory").setExecutor(new InventoryCommand());
this.getCommand("limb").setExecutor(new LimbCommand());
+ this.getCommand("marker").setExecutor(new MarkerCommand());
this.getCommand("modsettings").setExecutor(new ModSettingsCommand());
this.getCommand("nametag").setExecutor(new NametagCommand());
this.getCommand("nickhider").setExecutor(new NickHiderCommand());
diff --git a/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/command/MarkerCommand.java b/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/command/MarkerCommand.java
new file mode 100644
index 00000000..c62b6a1f
--- /dev/null
+++ b/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/command/MarkerCommand.java
@@ -0,0 +1,97 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.example.command;
+
+import com.lunarclient.apollo.example.ApolloExamplePlugin;
+import com.lunarclient.apollo.example.module.impl.MarkerExample;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class MarkerCommand implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ if (!(sender instanceof Player)) {
+ sender.sendMessage("Player only!");
+ return true;
+ }
+
+ Player player = (Player) sender;
+
+ if (args.length != 1) {
+ player.sendMessage("Usage: /marker ");
+ return true;
+ }
+
+ MarkerExample markerExample = ApolloExamplePlugin.getInstance().getMarkerExample();
+
+ switch (args[0].toLowerCase()) {
+ case "chest": {
+ markerExample.displayBlockMarkerExample(player);
+ player.sendMessage("Marking a block....");
+ break;
+ }
+
+ case "player": {
+ markerExample.displayPlayerMarkerExample(player);
+ player.sendMessage("Marking a player....");
+ break;
+ }
+
+ case "item": {
+ markerExample.displayItemMarkerExample(player);
+ player.sendMessage("Marking an item....");
+ break;
+ }
+
+ case "entity": {
+ markerExample.displayEntityMarkerExample(player);
+ player.sendMessage("Marking an entity....");
+ break;
+ }
+
+ case "remove": {
+ markerExample.removeMarkersExample(player);
+ player.sendMessage("Removing markers....");
+ break;
+ }
+
+ case "reset": {
+ markerExample.resetMarkersExample(player);
+ player.sendMessage("Resetting markers...");
+ break;
+ }
+
+ default: {
+ player.sendMessage("Usage: /marker ");
+ break;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/module/impl/MarkerExample.java b/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/module/impl/MarkerExample.java
new file mode 100644
index 00000000..14b91cf0
--- /dev/null
+++ b/example/bukkit/common/src/main/java/com/lunarclient/apollo/example/module/impl/MarkerExample.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.example.module.impl;
+
+import com.lunarclient.apollo.example.module.ApolloModuleExample;
+import org.bukkit.entity.Player;
+
+public abstract class MarkerExample extends ApolloModuleExample {
+
+ public abstract void displayBlockMarkerExample(Player viewer);
+
+ public abstract void displayPlayerMarkerExample(Player viewer);
+
+ public abstract void displayItemMarkerExample(Player viewer);
+
+ public abstract void displayEntityMarkerExample(Player viewer);
+
+ public abstract void removeMarkersExample(Player viewer);
+
+ public abstract void resetMarkersExample(Player viewer);
+
+}
diff --git a/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/ApolloJsonExamplePlatform.java b/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/ApolloJsonExamplePlatform.java
index 7240c067..391c46d7 100644
--- a/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/ApolloJsonExamplePlatform.java
+++ b/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/ApolloJsonExamplePlatform.java
@@ -38,6 +38,7 @@
import com.lunarclient.apollo.example.json.module.GlowJsonExample;
import com.lunarclient.apollo.example.json.module.HologramJsonExample;
import com.lunarclient.apollo.example.json.module.LimbJsonExample;
+import com.lunarclient.apollo.example.json.module.MarkerJsonExample;
import com.lunarclient.apollo.example.json.module.ModSettingsJsonExample;
import com.lunarclient.apollo.example.json.module.NametagJsonExample;
import com.lunarclient.apollo.example.json.module.NickHiderJsonExample;
@@ -82,6 +83,7 @@ public void registerModuleExamples() {
this.setGlowExample(new GlowJsonExample());
this.setHologramExample(new HologramJsonExample());
this.setLimbExample(new LimbJsonExample());
+ this.setMarkerExample(new MarkerJsonExample());
this.setModSettingsExample(new ModSettingsJsonExample());
this.setNametagExample(new NametagJsonExample());
this.setNickHiderExample(new NickHiderJsonExample());
diff --git a/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/module/MarkerJsonExample.java b/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/module/MarkerJsonExample.java
new file mode 100644
index 00000000..80b6f260
--- /dev/null
+++ b/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/module/MarkerJsonExample.java
@@ -0,0 +1,216 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.example.json.module;
+
+import com.google.gson.JsonObject;
+import com.lunarclient.apollo.example.json.util.JsonPacketUtil;
+import com.lunarclient.apollo.example.json.util.JsonUtil;
+import com.lunarclient.apollo.example.module.impl.MarkerExample;
+import java.awt.Color;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import org.bukkit.entity.Player;
+
+public class MarkerJsonExample extends MarkerExample {
+
+ @Override
+ public void displayBlockMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "loot-chest");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(viewer.getUniqueId()));
+ message.addProperty("owner_name", "");
+
+ JsonObject flag = new JsonObject();
+ flag.add("interest", new JsonObject());
+ message.add("flag", flag);
+
+ JsonObject itemStack = new JsonObject();
+ itemStack.addProperty("item_name", "minecraft:chest");
+ JsonObject block = new JsonObject();
+ block.add("item_stack", itemStack);
+ JsonObject target = new JsonObject();
+ target.add("block", block);
+ message.add("target", target);
+
+ message.addProperty("duration", JsonUtil.createDurationObject(Duration.ofSeconds(60)));
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.0F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "'s Marker");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_HEAD");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_ALWAYS");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void displayPlayerMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "bounty");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(viewer.getUniqueId()));
+ message.addProperty("owner_name", viewer.getName());
+
+ JsonObject danger = new JsonObject();
+ danger.add("color", JsonUtil.createColorObject(Color.RED));
+ JsonObject flag = new JsonObject();
+ flag.add("danger", danger);
+ message.add("flag", flag);
+
+ JsonObject player = new JsonObject();
+ player.add("uuid", JsonUtil.createUuidObject(UUID.fromString("f17627d8-1a97-487b-92ea-c04f413394bd")));
+ player.addProperty("name", "ItsNature");
+ JsonObject target = new JsonObject();
+ target.add("player", player);
+ message.add("target", target);
+
+ message.addProperty("in_game_notification", true);
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.0F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "'s Marker");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_HEAD");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_ALWAYS");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void displayItemMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "wither-loot");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(viewer.getUniqueId()));
+ message.addProperty("owner_name", viewer.getName());
+
+ JsonObject flag = new JsonObject();
+ flag.add("info", new JsonObject());
+ message.add("flag", flag);
+
+ JsonObject itemStack = new JsonObject();
+ itemStack.addProperty("item_name", "minecraft:nether_star");
+ JsonObject item = new JsonObject();
+ item.add("item_stack", itemStack);
+ JsonObject target = new JsonObject();
+ target.add("item", item);
+ message.add("target", target);
+
+ message.addProperty("chat_notify", true);
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.0F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "'s Marker");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_HEAD");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_ALWAYS");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void displayEntityMarkerExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.DisplayMarkerMessage");
+ message.addProperty("id", "tutorial-npc");
+ message.add("location", JsonUtil.createLocationObject(viewer.getLocation()));
+ message.add("owner_id", JsonUtil.createUuidObject(UUID.randomUUID()));
+ message.addProperty("owner_name", "Tutorial NPC");
+
+ JsonObject flag = new JsonObject();
+ flag.add("interest", new JsonObject());
+ message.add("flag", flag);
+
+ JsonObject entity = new JsonObject();
+ entity.addProperty("entity_type", "minecraft:villager");
+ JsonObject target = new JsonObject();
+ target.add("entity", entity);
+ message.add("target", target);
+
+ JsonObject style = new JsonObject();
+ style.addProperty("scale", 1.3F);
+ style.addProperty("animate_marker_on_hover", true);
+ style.addProperty("compact_mode", false);
+ style.addProperty("text_shadow", true);
+ style.addProperty("owner_suffix", "");
+ style.addProperty("owner_display", "MARKER_OWNER_DISPLAY_NAME");
+ style.addProperty("show_owner", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("show_coordinates", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_distance", "MARKER_DISPLAY_CONDITION_NEVER");
+ style.addProperty("show_description", "MARKER_DISPLAY_CONDITION_HOVER");
+ style.addProperty("description_display", "MARKER_DESCRIPTION_DISPLAY_ICON");
+ message.add("style", style);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void removeMarkersExample(Player viewer) {
+ List markerIds = Arrays.asList("loot-chest", "bounty", "wither-loot", "tutorial-npc");
+ for (String id : markerIds) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.RemoveMarkerMessage");
+ message.addProperty("id", id);
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+ }
+
+ @Override
+ public void resetMarkersExample(Player viewer) {
+ JsonObject message = new JsonObject();
+ message.addProperty("@type", "type.googleapis.com/lunarclient.apollo.marker.v1.ResetMarkersMessage");
+
+ JsonPacketUtil.sendPacket(viewer, message);
+ }
+
+}
diff --git a/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/util/JsonPacketUtil.java b/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/util/JsonPacketUtil.java
index 63fc5801..31617883 100644
--- a/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/util/JsonPacketUtil.java
+++ b/example/bukkit/json/src/main/java/com/lunarclient/apollo/example/json/util/JsonPacketUtil.java
@@ -41,7 +41,7 @@
public final class JsonPacketUtil {
private static final List APOLLO_MODULES = Arrays.asList("auto_text_hotkey", "beam", "border", "chat", "colored_fire", "combat", "cooldown",
- "cosmetic", "entity", "glint", "glow", "hologram", "inventory", "limb", "mod_setting", "nametag", "nick_hider", "notification", "pay_now", "packet_enrichment",
+ "cosmetic", "entity", "glint", "glow", "hologram", "inventory", "limb", "marker", "mod_setting", "nametag", "nick_hider", "notification", "pay_now", "packet_enrichment",
"rich_presence", "saturation", "server_link", "server_rule", "staff_mod", "stopwatch", "team", "tebex", "title", "tnt_countdown", "transfer", "vignette", "waypoint"
);
diff --git a/example/bukkit/json/src/main/resources/plugin.yml b/example/bukkit/json/src/main/resources/plugin.yml
index 12672845..5290ab7d 100644
--- a/example/bukkit/json/src/main/resources/plugin.yml
+++ b/example/bukkit/json/src/main/resources/plugin.yml
@@ -38,6 +38,8 @@ commands:
description: "Inventory!"
limb:
description: "Limb!"
+ marker:
+ description: "Markers!"
modsettings:
description: "ModSettings!"
nametag:
diff --git a/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/ApolloProtoExamplePlatform.java b/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/ApolloProtoExamplePlatform.java
index 9112f059..94578ad4 100644
--- a/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/ApolloProtoExamplePlatform.java
+++ b/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/ApolloProtoExamplePlatform.java
@@ -38,6 +38,7 @@
import com.lunarclient.apollo.example.proto.module.GlowProtoExample;
import com.lunarclient.apollo.example.proto.module.HologramProtoExample;
import com.lunarclient.apollo.example.proto.module.LimbProtoExample;
+import com.lunarclient.apollo.example.proto.module.MarkerProtoExample;
import com.lunarclient.apollo.example.proto.module.ModSettingsProtoExample;
import com.lunarclient.apollo.example.proto.module.NametagProtoExample;
import com.lunarclient.apollo.example.proto.module.NickHiderProtoExample;
@@ -82,6 +83,7 @@ public void registerModuleExamples() {
this.setGlowExample(new GlowProtoExample());
this.setHologramExample(new HologramProtoExample());
this.setLimbExample(new LimbProtoExample());
+ this.setMarkerExample(new MarkerProtoExample());
this.setModSettingsExample(new ModSettingsProtoExample());
this.setNametagExample(new NametagProtoExample());
this.setNickHiderExample(new NickHiderProtoExample());
diff --git a/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/module/MarkerProtoExample.java b/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/module/MarkerProtoExample.java
new file mode 100644
index 00000000..998a1d73
--- /dev/null
+++ b/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/module/MarkerProtoExample.java
@@ -0,0 +1,210 @@
+/*
+ * This file is part of Apollo, licensed under the MIT License.
+ *
+ * Copyright (c) 2026 Moonsworth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.lunarclient.apollo.example.proto.module;
+
+import com.lunarclient.apollo.example.module.impl.MarkerExample;
+import com.lunarclient.apollo.example.proto.util.ProtobufPacketUtil;
+import com.lunarclient.apollo.example.proto.util.ProtobufUtil;
+import com.lunarclient.apollo.marker.v1.BlockTarget;
+import com.lunarclient.apollo.marker.v1.DangerMarker;
+import com.lunarclient.apollo.marker.v1.DisplayMarkerMessage;
+import com.lunarclient.apollo.marker.v1.EntityTarget;
+import com.lunarclient.apollo.marker.v1.InfoMarker;
+import com.lunarclient.apollo.marker.v1.InterestMarker;
+import com.lunarclient.apollo.marker.v1.ItemTarget;
+import com.lunarclient.apollo.marker.v1.MarkerDescriptionDisplay;
+import com.lunarclient.apollo.marker.v1.MarkerDisplayCondition;
+import com.lunarclient.apollo.marker.v1.MarkerFlag;
+import com.lunarclient.apollo.marker.v1.MarkerOwnerDisplay;
+import com.lunarclient.apollo.marker.v1.MarkerStyle;
+import com.lunarclient.apollo.marker.v1.MarkerTarget;
+import com.lunarclient.apollo.marker.v1.PlayerTarget;
+import com.lunarclient.apollo.marker.v1.RemoveMarkerMessage;
+import com.lunarclient.apollo.marker.v1.ResetMarkersMessage;
+import java.awt.Color;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import org.bukkit.entity.Player;
+
+public class MarkerProtoExample extends MarkerExample {
+
+ @Override
+ public void displayBlockMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("loot-chest")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(viewer.getUniqueId()))
+ .setOwnerName("")
+ .setFlag(MarkerFlag.newBuilder()
+ .setInterest(InterestMarker.getDefaultInstance())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setBlock(BlockTarget.newBuilder()
+ .setItemStack(ProtobufUtil.createItemStackIconProto("minecraft:chest", 0))
+ .build())
+ .build())
+ .setDuration(ProtobufUtil.createDurationProto(Duration.ofSeconds(60)))
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.0F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("'s Marker")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_HEAD)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_ALWAYS)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void displayPlayerMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("bounty")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(viewer.getUniqueId()))
+ .setOwnerName(viewer.getName())
+ .setFlag(MarkerFlag.newBuilder()
+ .setDanger(DangerMarker.newBuilder()
+ .setColor(ProtobufUtil.createColorProto(Color.RED))
+ .build())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setPlayer(PlayerTarget.newBuilder()
+ .setUuid(ProtobufUtil.createUuidProto(UUID.fromString("f17627d8-1a97-487b-92ea-c04f413394bd")))
+ .setName("ItsNature")
+ .build())
+ .build())
+ .setInGameNotification(true)
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.0F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("'s Marker")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_HEAD)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_ALWAYS)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void displayItemMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("wither-loot")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(viewer.getUniqueId()))
+ .setOwnerName(viewer.getName())
+ .setFlag(MarkerFlag.newBuilder()
+ .setInfo(InfoMarker.getDefaultInstance())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setItem(ItemTarget.newBuilder()
+ .setItemStack(ProtobufUtil.createItemStackIconProto("minecraft:nether_star", 0))
+ .build())
+ .build())
+ .setChatNotify(true)
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.0F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("'s Marker")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_HEAD)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_ALWAYS)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void displayEntityMarkerExample(Player viewer) {
+ DisplayMarkerMessage message = DisplayMarkerMessage.newBuilder()
+ .setId("tutorial-npc")
+ .setLocation(ProtobufUtil.createLocationProto(viewer.getLocation()))
+ .setOwnerId(ProtobufUtil.createUuidProto(UUID.randomUUID()))
+ .setOwnerName("Tutorial NPC")
+ .setFlag(MarkerFlag.newBuilder()
+ .setInterest(InterestMarker.getDefaultInstance())
+ .build())
+ .setTarget(MarkerTarget.newBuilder()
+ .setEntity(EntityTarget.newBuilder()
+ .setEntityType("minecraft:villager")
+ .build())
+ .build())
+ .setStyle(MarkerStyle.newBuilder()
+ .setScale(1.3F)
+ .setAnimateMarkerOnHover(true)
+ .setCompactMode(false)
+ .setTextShadow(true)
+ .setOwnerSuffix("")
+ .setOwnerDisplay(MarkerOwnerDisplay.MARKER_OWNER_DISPLAY_NAME)
+ .setShowOwner(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setShowCoordinates(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDistance(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_NEVER)
+ .setShowDescription(MarkerDisplayCondition.MARKER_DISPLAY_CONDITION_HOVER)
+ .setDescriptionDisplay(MarkerDescriptionDisplay.MARKER_DESCRIPTION_DISPLAY_ICON)
+ .build())
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+
+ @Override
+ public void removeMarkersExample(Player viewer) {
+ List markerIds = Arrays.asList("loot-chest", "bounty", "wither-loot", "tutorial-npc");
+ for (String id : markerIds) {
+ RemoveMarkerMessage message = RemoveMarkerMessage.newBuilder()
+ .setId(id)
+ .build();
+
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+ }
+
+ @Override
+ public void resetMarkersExample(Player viewer) {
+ ResetMarkersMessage message = ResetMarkersMessage.getDefaultInstance();
+ ProtobufPacketUtil.sendPacket(viewer, message);
+ }
+
+}
diff --git a/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/util/ProtobufPacketUtil.java b/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/util/ProtobufPacketUtil.java
index b0ba4ac1..f8a0e17c 100644
--- a/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/util/ProtobufPacketUtil.java
+++ b/example/bukkit/proto/src/main/java/com/lunarclient/apollo/example/proto/util/ProtobufPacketUtil.java
@@ -42,7 +42,7 @@
public final class ProtobufPacketUtil {
private static final List APOLLO_MODULES = Arrays.asList("auto_text_hotkey", "beam", "border", "chat", "colored_fire", "combat", "cooldown",
- "cosmetic", "entity", "glint", "glow", "hologram", "inventory", "limb", "mod_setting", "nametag", "nick_hider", "notification", "pay_now", "packet_enrichment",
+ "cosmetic", "entity", "glint", "glow", "hologram", "inventory", "limb", "marker", "mod_setting", "nametag", "nick_hider", "notification", "pay_now", "packet_enrichment",
"rich_presence", "saturation", "server_link", "server_rule", "staff_mod", "stopwatch", "team", "tebex", "title", "tnt_countdown", "transfer", "vignette", "waypoint"
);
diff --git a/example/bukkit/proto/src/main/resources/plugin.yml b/example/bukkit/proto/src/main/resources/plugin.yml
index ef931e21..44fdb87e 100644
--- a/example/bukkit/proto/src/main/resources/plugin.yml
+++ b/example/bukkit/proto/src/main/resources/plugin.yml
@@ -38,6 +38,8 @@ commands:
description: "Inventory!"
limb:
description: "Limb!"
+ marker:
+ description: "Markers!"
modsettings:
description: "ModSettings!"
nametag:
diff --git a/platform/bukkit/src/main/java/com/lunarclient/apollo/ApolloBukkitPlatform.java b/platform/bukkit/src/main/java/com/lunarclient/apollo/ApolloBukkitPlatform.java
index 220be9b1..6de2e988 100644
--- a/platform/bukkit/src/main/java/com/lunarclient/apollo/ApolloBukkitPlatform.java
+++ b/platform/bukkit/src/main/java/com/lunarclient/apollo/ApolloBukkitPlatform.java
@@ -55,6 +55,8 @@
import com.lunarclient.apollo.module.inventory.InventoryModule;
import com.lunarclient.apollo.module.limb.LimbModule;
import com.lunarclient.apollo.module.limb.LimbModuleImpl;
+import com.lunarclient.apollo.module.marker.MarkerModule;
+import com.lunarclient.apollo.module.marker.MarkerModuleImpl;
import com.lunarclient.apollo.module.modsetting.ModSettingModule;
import com.lunarclient.apollo.module.modsettings.ModSettingModuleImpl;
import com.lunarclient.apollo.module.nametag.NametagModule;
@@ -150,6 +152,7 @@ public void onEnable() {
.addModule(HologramModule.class, new HologramModuleImpl())
.addModule(InventoryModule.class)
.addModule(LimbModule.class, new LimbModuleImpl())
+ .addModule(MarkerModule.class, new MarkerModuleImpl())
.addModule(ModSettingModule.class, new ModSettingModuleImpl())
.addModule(NametagModule.class, new NametagModuleImpl())
.addModule(NickHiderModule.class, new NickHiderModuleImpl())
diff --git a/platform/bungee/src/main/java/com/lunarclient/apollo/ApolloBungeePlatform.java b/platform/bungee/src/main/java/com/lunarclient/apollo/ApolloBungeePlatform.java
index 76cad083..a5f50d27 100644
--- a/platform/bungee/src/main/java/com/lunarclient/apollo/ApolloBungeePlatform.java
+++ b/platform/bungee/src/main/java/com/lunarclient/apollo/ApolloBungeePlatform.java
@@ -50,6 +50,8 @@
import com.lunarclient.apollo.module.hologram.HologramModuleImpl;
import com.lunarclient.apollo.module.limb.LimbModule;
import com.lunarclient.apollo.module.limb.LimbModuleImpl;
+import com.lunarclient.apollo.module.marker.MarkerModule;
+import com.lunarclient.apollo.module.marker.MarkerModuleImpl;
import com.lunarclient.apollo.module.modsetting.ModSettingModule;
import com.lunarclient.apollo.module.modsettings.ModSettingModuleImpl;
import com.lunarclient.apollo.module.nametag.NametagModule;
@@ -131,6 +133,7 @@ public void onEnable() {
.addModule(EntityModule.class, new EntityModuleImpl())
.addModule(HologramModule.class, new HologramModuleImpl())
.addModule(LimbModule.class, new LimbModuleImpl())
+ .addModule(MarkerModule.class, new MarkerModuleImpl())
.addModule(ModSettingModule.class, new ModSettingModuleImpl())
.addModule(NametagModule.class, new NametagModuleImpl())
.addModule(NotificationModule.class, new NotificationModuleImpl())
diff --git a/platform/folia/src/main/java/com/lunarclient/apollo/ApolloFoliaPlatform.java b/platform/folia/src/main/java/com/lunarclient/apollo/ApolloFoliaPlatform.java
index ecf29b87..19a4878b 100644
--- a/platform/folia/src/main/java/com/lunarclient/apollo/ApolloFoliaPlatform.java
+++ b/platform/folia/src/main/java/com/lunarclient/apollo/ApolloFoliaPlatform.java
@@ -52,6 +52,8 @@
import com.lunarclient.apollo.module.hologram.HologramModuleImpl;
import com.lunarclient.apollo.module.limb.LimbModule;
import com.lunarclient.apollo.module.limb.LimbModuleImpl;
+import com.lunarclient.apollo.module.marker.MarkerModule;
+import com.lunarclient.apollo.module.marker.MarkerModuleImpl;
import com.lunarclient.apollo.module.modsetting.ModSettingModule;
import com.lunarclient.apollo.module.modsettings.ModSettingModuleImpl;
import com.lunarclient.apollo.module.nametag.NametagModule;
@@ -138,6 +140,7 @@ public void onEnable() {
.addModule(GlowModule.class, new GlowModuleImpl())
.addModule(HologramModule.class, new HologramModuleImpl())
.addModule(LimbModule.class, new LimbModuleImpl())
+ .addModule(MarkerModule.class, new MarkerModuleImpl())
.addModule(ModSettingModule.class, new ModSettingModuleImpl())
.addModule(NametagModule.class, new NametagModuleImpl())
.addModule(NickHiderModule.class, new NickHiderModuleImpl())
diff --git a/platform/minestom/src/main/java/com/lunarclient/apollo/ApolloMinestomPlatform.java b/platform/minestom/src/main/java/com/lunarclient/apollo/ApolloMinestomPlatform.java
index ceb47d1e..caf5d4b2 100644
--- a/platform/minestom/src/main/java/com/lunarclient/apollo/ApolloMinestomPlatform.java
+++ b/platform/minestom/src/main/java/com/lunarclient/apollo/ApolloMinestomPlatform.java
@@ -54,6 +54,8 @@
import com.lunarclient.apollo.module.inventory.InventoryModule;
import com.lunarclient.apollo.module.limb.LimbModule;
import com.lunarclient.apollo.module.limb.LimbModuleImpl;
+import com.lunarclient.apollo.module.marker.MarkerModule;
+import com.lunarclient.apollo.module.marker.MarkerModuleImpl;
import com.lunarclient.apollo.module.modsetting.ModSettingModule;
import com.lunarclient.apollo.module.modsettings.ModSettingModuleImpl;
import com.lunarclient.apollo.module.nametag.NametagModule;
@@ -172,6 +174,7 @@ public static void init(ApolloMinestomProperties properties) {
.addModule(HologramModule.class, new HologramModuleImpl())
.addModule(InventoryModule.class)
.addModule(LimbModule.class, new LimbModuleImpl())
+ .addModule(MarkerModule.class, new MarkerModuleImpl())
.addModule(ModSettingModule.class, new ModSettingModuleImpl())
.addModule(NametagModule.class, new NametagModuleImpl())
.addModule(NickHiderModule.class, new NickHiderModuleImpl())
diff --git a/platform/velocity/src/main/java/com/lunarclient/apollo/ApolloVelocityPlatform.java b/platform/velocity/src/main/java/com/lunarclient/apollo/ApolloVelocityPlatform.java
index e9b04e67..e19a3b00 100644
--- a/platform/velocity/src/main/java/com/lunarclient/apollo/ApolloVelocityPlatform.java
+++ b/platform/velocity/src/main/java/com/lunarclient/apollo/ApolloVelocityPlatform.java
@@ -50,6 +50,8 @@
import com.lunarclient.apollo.module.hologram.HologramModuleImpl;
import com.lunarclient.apollo.module.limb.LimbModule;
import com.lunarclient.apollo.module.limb.LimbModuleImpl;
+import com.lunarclient.apollo.module.marker.MarkerModule;
+import com.lunarclient.apollo.module.marker.MarkerModuleImpl;
import com.lunarclient.apollo.module.modsetting.ModSettingModule;
import com.lunarclient.apollo.module.modsettings.ModSettingModuleImpl;
import com.lunarclient.apollo.module.nametag.NametagModule;
@@ -198,6 +200,7 @@ public void onProxyInitialization(ProxyInitializeEvent event) {
.addModule(EntityModule.class, new EntityModuleImpl())
.addModule(HologramModule.class, new HologramModuleImpl())
.addModule(LimbModule.class, new LimbModuleImpl())
+ .addModule(MarkerModule.class, new MarkerModuleImpl())
.addModule(ModSettingModule.class, new ModSettingModuleImpl())
.addModule(NametagModule.class, new NametagModuleImpl())
.addModule(NotificationModule.class, new NotificationModuleImpl())