Repository navigation
HUD Panels
Look at a block → a small panel tells the player what is inside and what to do next. Foundation draws the panel (position, scaling, background). You only describe the content.
public class ShelfInfoProvider implements BlockInfoProvider {
@Override
public List<InfoSection> describe(Level level, BlockPos pos, BlockState state, @Nullable BlockHitResult hit) {
if (!(level.getBlockEntity(pos) instanceof ShelfBlockEntity shelf)) {
return List.of(); // not my block → next provider
}
return List.of(
InfoSection.icons(Component.translatable("hud.mymod.on_shelf"), shelf.getItems(), InfoSection.ROW_COLUMNS),
InfoSection.title(Component.translatable("hud.mymod.take_hint").withStyle(ChatFormatting.GRAY))
);
}
}BlockInfoOverlay.registerProvider(new ShelfInfoProvider());The first provider that returns a non-empty list wins.
| Factory | Shows |
|---|---|
InfoSection.title(text) |
one line of text |
InfoSection.icons(title, items, columns) |
title + item grid (ROW_COLUMNS = 6, GRID_COLUMNS = 3) |
InfoSection.lines(title, lines) |
title + several text lines |
InfoSection.rows(title, rows) |
title + icon/text rows (Row.item(...), Row.sprite(...)) |
InfoSection.image(title, texture, size) |
title + a picture (e.g. a "toss!" icon) |
Modifiers: withLines(...), withRows(...), withPlaceholder(texture), withDecorations().
-
Panels for blocks you don't look at – e.g. "your wok needs a toss":
Your provider then gets
BlockInfoOverlay.registerTracker(() -> myTrackedPositions);
hit == nullfor those positions. -
Coloured border – override
beforeBackground(...)and callTooltipBorder.markHot()/markSoul()/mark(top, bottom). -
Short notice –
BlockInfoOverlay.showNotice(pos, message). -
Server data the client doesn't have – register a
BlockInfoSync.Handleron the server, read it on the client:BlockInfoSync.registerHandler((level, pos, player, tag) -> tag.putInt("stock", myStock(level, pos))); CompoundTag data = BlockInfoSync.poll(level, pos); // in describe(...)
Every panel is switched by your mod's config. Return List.of() from describe when your mod's "block info" option is off.
Foundation's own config only has showBlockNotices, which hides the notices from BlockNotice.send(...) (see Config).
BlockInfoOverlay.showNotice(pos, text) shows a short golden notice at a block, client side. From the server use BlockNotice.send(serverPlayer, pos, text), or send(serverPlayer, pos, title, lines) for a title with more lines below.
Same idea for mobs and other entities: look at it, get a panel above it.
public class CowInfoProvider implements EntityInfoProvider {
@Override
public List<InfoSection> describe(Level level, Entity entity, EntityHitResult hit) {
if (!MyConfig.showCowInfo() || !(entity instanceof Cow cow)) {
return List.of();
}
CompoundTag data = EntityInfoSync.poll(cow);
return List.of(
InfoSection.title(Component.translatable("hud.mymod.cow.milk", data.getInt("milk")).withStyle(ChatFormatting.GRAY)),
InfoSection.title(Component.translatable("hud.mymod.cow.hint").withStyle(ChatFormatting.GRAY))
);
}
}BlockInfoOverlay.registerEntityProvider(new CowInfoProvider());- The first provider that returns a non-empty list wins, like for blocks.
- Override
beforeBackground(level, entity)for a coloured border (TooltipBorder). - Server data:
EntityInfoSync.registerHandler((level, entity, player, tag) -> ...)on the server,EntityInfoSync.poll(entity)indescribe. The client asks every 10 ticks, only for entities within 8 blocks. Until the answer arrivespollreturns an empty tag.
A notice in the top middle of the screen, not tied to a block:
BlockInfoOverlay.showScreenNotice(Component.translatable("hud.mymod.timer.done"), List.of());
BlockInfoOverlay.clearScreenNotice();It stays for about 2 seconds and fades out. Call showScreenNotice again every tick to keep it on screen (e.g. while a timer runs), clearScreenNotice() removes it right away.
Client side only.