For mod developers
React to Body Language emotes from your own NeoForge mod with EmoteEvent, as an optional dependency.
Body Language posts an event on NeoForge’s event bus, on the server, whenever a player starts or stops an emote. Your mod can react to it: a pet that copies its owner, a statue that bows back, a quest that wants a wave.
The events
Both are in com.taylorgibbs.emotes.api and extend EmoteEvent, which has getPlayer() (a ServerPlayer).
| Event | When | Extra |
|---|---|---|
EmoteEvent.Started |
A player starts an emote. For a hug or high-five, it fires for both players. | getEmote(): the emote’s id, such as tgemotes:wave, tgemotes:dance_disco or tgemotes:hug. Emotes from resource packs have their own namespace. |
EmoteEvent.Stopped |
A player’s emote ends: a one-off one played to the end, or they moved. | None. |
Starting a different emote in the middle of one doesn’t send Stopped; you get a new Started instead.
The events only fire where the server has Body Language (including singleplayer). On a server without it, emotes stay on each player’s own game.
Adding it as an optional dependency
-
Put the Body Language jar in your project and add it as a compile-only dependency, for example:
dependencies { compileOnly files('libs/bodylanguage-1.21.1-1.0.0.jar') } -
Declare it as optional in your
neoforge.mods.toml:[[dependencies.yourmod]] modId = "tgemotes" type = "optional" versionRange = "[1.0.0,)" ordering = "NONE" side = "BOTH" -
Only touch Body Language’s classes when it’s installed. Keep the listener in its own class, so the game never loads it otherwise:
// In your mod's constructor: if (ModList.get().isLoaded("tgemotes")) { EmoteHooks.register(); }import com.taylorgibbs.emotes.api.EmoteEvent; import net.neoforged.neoforge.common.NeoForge; /** Only loaded when Body Language is installed. */ final class EmoteHooks { static void register() { NeoForge.EVENT_BUS.addListener(EmoteEvent.Started.class, e -> { if (e.getEmote().getPath().equals("wave")) { // e.getPlayer() just waved } }); NeoForge.EVENT_BUS.addListener(EmoteEvent.Stopped.class, e -> { // e.getPlayer()'s emote is over }); } }
The package is com.taylorgibbs.emotes and the mod id tgemotes, as they’ve always been: the move to Hardline
Interactive didn’t change them, so nothing that already uses them breaks.
That’s the whole API. If you’d like more from it, email hello@hardlineinteractive.com.