Java API
Midnight Thoughts fires five events. Other mods can listen to them to react to sleep, or to change how comfortable a place is considered before the mod acts on it.
Java mod developers. If you just want to script behaviour without writing a mod, use KubeJS — it exposes the same five events.
All events live in the mt.api.event package.
On Forge and NeoForge these are event bus classes, named ...Event. On Fabric the same five hooks are Fabric API callbacks, named ...Callback, each with a static EVENT field. The data they carry is identical; only the way you subscribe differs.
Events
| Event | Fires when | Cancellable |
|---|---|---|
WellRestedAppliedEvent | The Rested effect is granted | — |
WellRestedExpiredEvent | The Rested effect is removed | — |
NightmareEvent | A player falls asleep in nightmare conditions | — |
MvpDeterminedEvent | The night's MVP is chosen | — |
ComfortCalculatedEvent | Comfort is calculated for a player | mutable result |
- WellRestedApplied
- WellRestedExpired
- Nightmare
- MvpDetermined
- ComfortCalculated
public class WellRestedAppliedEvent extends Event {
public ServerPlayer getPlayer();
public int getLevel(); // 1..5
public boolean isMvp();
public int getDurationTicks();
}
Fired after waking up, from the wellrested grant command, and from the KubeJS binding.
public class WellRestedExpiredEvent extends Event {
public ServerPlayer getPlayer();
}
Fired when the timer runs out, on death, and on manual clear. Not fired if the player had no effect.
public class NightmareEvent extends Event {
public ServerPlayer getPlayer();
public int getComfortLevel();
}
Fired at the moment the player successfully falls asleep in nightmare conditions.
public class MvpDeterminedEvent extends Event {
public ServerPlayer getMvp();
}
Fired in the morning when a player clears minScoreRequired.
public class ComfortCalculatedEvent extends Event {
public ServerPlayer getPlayer();
public int getLevel();
public void setLevel(int level);
}
Fired every time comfort is recalculated. The value left in the event is the value the mod uses.
Listening
- NeoForge
- Forge
- Fabric
@EventBusSubscriber
public class SleepHooks {
@SubscribeEvent
public static void onRested(WellRestedAppliedEvent event) {
LOGGER.info("{} woke up rested at level {}",
event.getPlayer().getName().getString(), event.getLevel());
}
}
@Mod.EventBusSubscriber
public class SleepHooks {
@SubscribeEvent
public static void onRested(WellRestedAppliedEvent event) {
LOGGER.info("{} woke up rested at level {}",
event.getPlayer().getName().getString(), event.getLevel());
}
}
public class SleepHooks {
public static void register() {
WellRestedAppliedCallback.EVENT.register((player, level, mvp, durationTicks) ->
LOGGER.info("{} woke up rested at level {}",
player.getName().getString(), level));
}
}
The comfort hook returns the value instead of mutating an event, and every listener receives the result of the previous one:
ComfortCalculatedCallback.EVENT.register((player, level) ->
player.level().dimension() == Level.NETHER ? -5 : level);
Every event is fired on the server side only. There is no client-side counterpart — the client is told the result over the network, not through events.
Overriding comfort
ComfortCalculatedEvent is the extension point worth knowing about. The mod reads the level back out of the event after posting it, so whatever a listener leaves there becomes the real comfort level — driving the Rested level, nightmares, and the sleep block.
@SubscribeEvent
public static void onComfort(ComfortCalculatedEvent event) {
ServerPlayer player = event.getPlayer();
if (player.level().dimension() == Level.NETHER) {
event.setLevel(-5);
}
}
This lets another mod add its own comfort sources — a "cosy campfire" block, a biome modifier, a magic ward — without touching the tag system at all. Read the current value, adjust it, write it back.
Results are cached per player and position for a short window, so the event does not fire on every tick. Do not rely on it as a polling mechanism — treat it as "the mod is about to make a decision, last chance to influence it".
Data pack alternative
If all you want is to add blocks that make a bedroom cosier, you do not need Java at all — the comfort system is driven by block tags, and a data pack can extend them in a few lines of JSON.