-
Notifications
You must be signed in to change notification settings - Fork 93
Information for Mod Developers
This page collects everything a mod developer needs to integrate with Carry On: excluding your own blocks and entities from being picked up, the events Carry On fires so protection mods can veto a pickup or placement, and the legacy IMC API.
- Adding Carry On to your workspace
- Blacklisting your own Blocks and Entities
- Events
- IMC (legacy)
- Datapack features
repositories {
maven {
url "https://maven.blamejared.com/"
}
}
dependencies {
deobfCompile "tschipp.carryon:carryon-LOADER-MCVERSION:MODVERSION"
}Replace LOADER, MCVERSION and MODVERSION with the appropriate values, for example tschipp.carryon:carryon-forge-1.19.2:2.0.0.5.
You only need this dependency if you want to listen to Carry On's own events. Blacklisting via tags requires no dependency at all.
The recommended way to exclude your content is tags. Ship the files below in your own mod's data folder. They merge with the tags of Carry On and every other mod, they work on all loaders, and they are silently ignored when Carry On is not installed — so no dependency and no compat code is needed.
| Tag | Registry | File in your mod | Effect |
|---|---|---|---|
carryon:block_blacklist |
Block | data/carryon/tags/blocks/block_blacklist.json |
Block can never be picked up |
carryon:entity_blacklist |
Entity Type | data/carryon/tags/entity_types/entity_blacklist.json |
Entity can never be picked up |
carryon:stacking_blacklist |
Entity Type | data/carryon/tags/entity_types/stacking_blacklist.json |
Nothing can be stacked on top of this entity |
carryon:block_whitelist |
Block | data/carryon/tags/blocks/block_whitelist.json |
Block can be picked up in whitelist mode |
carryon:entity_whitelist |
Entity Type | data/carryon/tags/entity_types/entity_whitelist.json |
Entity can be picked up in whitelist mode |
carryon:stacking_whitelist |
Entity Type | data/carryon/tags/entity_types/stacking_whitelist.json |
Entity can be stacked on in whitelist mode |
Example — data/carryon/tags/blocks/block_blacklist.json:
{
"replace": false,
"values": [
"yourmod:fragile_machine",
"yourmod:multiblock_controller"
]
}Always use "replace": false, otherwise you wipe every other mod's entries.
Blacklist and whitelist are never active at the same time. The config options useWhitelistBlocks, useWhitelistEntities and useWhitelistStacking switch each category over: when a whitelist is enabled, the corresponding blacklist is not consulted at all, and only tagged/listed content can be picked up.
Most packs use blacklist mode, but if your blocks should also work in a whitelist-mode pack, add them to the whitelist tag as well.
Tag contents are merged with the user's config lists (blacklist.forbiddenTiles, blacklist.forbiddenEntities, blacklist.forbiddenStacking and the whitelist.* counterparts). See Black- and Whitelist Config for the config format, which additionally supports * wildcards and #namespace:tag entries.
Both lists are rebuilt whenever tags are (re)loaded — on world load and on /reload.
-
Baby mobs. A blacklisted
AgeableMobcan still be picked up while it is a baby, as long as theallowBabiesconfig option is enabled. Give your entity a pickup-blocking script if this matters for you. -
Scripts. A Carry On script with
overrideChecksskips most guards. The block blacklist is still enforced, but the entity blacklist is not.
Even without a blacklist entry, Carry On refuses to pick up:
- Blocks using the vanilla
DoorBlock.HALFproperty type (double blocks) - Blocks whose block entity NBT has a non-empty
Locktag - Unbreakable blocks (destroy speed
-1) in Survival, unlesspickupUnbreakableBlocksis enabled - Blocks without a block entity, unless
pickupAllBlocksis enabled
For entities: tamed animals belonging to another player, entities with active invulnerability frames, hostile mobs in Survival while pickupHostileMobs is off, and entities exceeding maxEntityHeight / maxEntityWidth in Survival.
If your mod is already released and you cannot ship a tag, open a Blacklist Request issue and the entry can be added to Carry On's own tag file.
All Carry On events fire server-side only and before the world is modified. Cancelling one aborts the pickup or placement; Carry On then falls through to the normal interaction.
tschipp.carryon.events.EntityPickupEvent — fired right before a player picks up an entity. Available on NeoForge and Forge; there is no Fabric equivalent.
NeoForge — a cancellable Event with the public fields player and target, posted on NeoForge.EVENT_BUS:
@SubscribeEvent
public static void onCarryPickup(EntityPickupEvent event) {
if (event.target instanceof YourEntity)
event.setCanceled(true);
}Forge — a RecordEvent with its own bus, player() and target() accessors, listener returns true to cancel:
EntityPickupEvent.BUS.addListener(event -> {
return event.target() instanceof YourEntity;
});There is no equivalent block pickup event of Carry On's own — block pickup is vetoed through the loader's block break event, see below.
So that protection, claim and anti-grief mods keep working without knowing anything about Carry On, every pickup and placement is announced through the loader's regular events. If you already listen to these, you are covered.
| Action | NeoForge | Forge | Fabric |
|---|---|---|---|
| Block pickup | BreakBlockEvent |
BlockEvent.BreakEvent |
PlayerBlockBreakEvents.BEFORE |
| Block placement | BlockEvent.EntityPlaceEvent |
BlockEvent.EntityPlaceEvent |
Architectury BlockEvent.PLACE
|
| Entity pickup | EntityPickupEvent |
EntityPickupEvent |
– |
| Entity placement | MobSpawnEvent.PositionCheck |
FinalizeSpawn |
– |
Notes:
- Cancelling the break/place event denies the pickup or placement. For
MobSpawnEvent.PositionCheckon NeoForge, return the resultFAIL. - Entity placement events are only posted for entities that are a
Mob. - On Fabric, the block placement event is only posted when Architectury is installed, since Fabric itself has no block place event.
- Entity stacking (putting a carried mob on top of another mob) posts no event.
- Placement of a carried block also happens on player death and on disconnect. Those paths do not post a place event.
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (carry.isCarrying(CarryType.BLOCK))
BlockState state = carry.getBlock();
if (carry.isCarrying(CarryType.ENTITY))
Entity entity = carry.getEntity(level);CarryType is one of BLOCK, ENTITY or PLAYER. The data is synced to clients, so it can be read on both sides. Write to it only on the server, and call CarryOnDataManager.setCarryData(player, carry) afterwards to sync the change.
Carry On still processes IMC messages during InterModProcessEvent on Forge and NeoForge.
Use tags instead. The black- and whitelists are rebuilt when tags load, which happens after mod loading — so entries added through IMC are dropped again before the world is playable. IMC is kept for compatibility with old mods only.
| Method | Argument | Meaning |
|---|---|---|
blacklistBlock |
block name | Add a block to the blacklist |
whitelistBlock |
block name | Add a block to the whitelist |
blacklistEntity |
entity name | Add an entity to the blacklist |
whitelistEntity |
entity name | Add an entity to the whitelist |
blacklistStacking |
entity name | Nothing can be stacked on top of this entity |
whitelistStacking |
entity name | Entity can be stacked on in whitelist mode |
addModelOverride |
Model Override string | No longer implemented |
1.13 and newer:
InterModComms.sendTo("carryon", "blacklistBlock", () -> "minecraft:stone");
InterModComms.sendTo("carryon", "whitelistEntity", () -> "minecraft:zombie");1.12:
FMLInterModComms.sendMessage("carryon", "blacklistBlock", "minecraft:stone");
FMLInterModComms.sendMessage("carryon", "whitelistEntity", "minecraft:zombie");
FMLInterModComms.sendMessage("carryon", "addModelOverride", "minecraft:hopper->(block)minecraft:hopper");These are aimed at pack makers, but they are just as usable from a mod's built-in datapack:
- Scripting — full control over what can be picked up and what happens when it is
- Custom Pickup Conditions — require a permission, score or block state before a pickup is allowed
- Model Overrides — change how a carried block is rendered
- Black- and Whitelist Config — the config-side counterpart to the tags above