HomeJavaModsPolyMc-Extra
PolyMc-Extra
ModsJava

PolyMc-Extra

by SAGUMEDREAM · on Modrinth

Which Minecraft do you have?

Every version of the game needs its own build. Pick yours, then download — the wrong build installs fine and then does nothing in the game. This mod is built for Fabric only.

⬇ Download for 26.1–26.1.2⬇ Download for 1.21.11⬇ Download for 1.21.10⬇ Download for 1.21.6–1.21.8
I don't know my version or loader
Open the Minecraft launcher and look at the profile you play on — it names both, like fabric-loader-1.21.4. The version also shows in the bottom-right corner of the game's main menu.
No loader in the profile name? Then it's plain Minecraft, and these mods won't run — you need Fabric or NeoForge installed first.
PolyMc-Extra — screenshot 1PolyMc-Extra — screenshot 2PolyMc-Extra — screenshot 3PolyMc-Extra — screenshot 4PolyMc-Extra — screenshot 5PolyMc-Extra — screenshot 6PolyMc-Extra — screenshot 7PolyMc-Extra — screenshot 8

PolyMc-Extra

This is a server-side library and a tool for providing automatic patching mods for PolyMc. It functions similarly to PolyMc but is more powerful. It enables automatic patching of certain mods, and its patching functionality can be controlled by modifying configuration files.

The following registry entries were processed by the patch

List: Attribute, EntityType, SoundEvent, ComponentType, EnchantmentEffectComponentType, EnchantmentLocationBaseEffectType, EnchantmentEntityEffectType, StatusEffect, Potion, ScreenHandlers, ConsumeEffectType, StatType, CustomStat, PoiType, ItemGroup, Item, Block, BlockEntityType, Profession

Runtime Lifecycle:

  1. Register the built-in ExtraModelType
  2. Register Special Entity Mappings
  3. Scan and execute all module's "polymc-extra" entry points (PolyMcExtraEntrypoint.class)
  4. Before all static registry entries freeze: Read the configuration file, iterate through the registry, and patch each missing item (server-only)
  5. Verify item components integrity
  6. Scan for required resources in JAR files and generate resource packages

For player/server owners/mod pack makers:

It can automatically repair the state of corresponding polymer blocks for most mods, allowing Vanilla clients to join servers with mods.

For mod developers:

It provides several APIs and tools for developers to patch complex mods; for others, you can ask questions on Discord.

Knowledge required

You should first learn how to use some libraries.

Development Environment

  1. Create a libs folder in your module project directory.
  2. Download the JAR file and place it in the libs folder in your module project directory.
  3. Add the following content to build.gradle:
repositories {
    maven { url "https://maven.nucleoid.xyz" }
    maven { url "https://maven.tomalbrc.de" }
    maven { url "https://api.modrinth.com/maven" }
    maven { url "https://maven.architectury.dev/" }
    maven {
        url "https://maven.theepicblock.nl"
        content { includeGroup("nl.theepicblock") }
    }
    flatDir {
        dirs 'libs'
    }
}
dependencies {
    modImplementation("eu.pb4:polymer-core:[${polymer_version}]")
    modImplementation("eu.pb4:polymer-blocks:[${polymer_version}]")
    modImplementation("eu.pb4:polymer-resource-pack:[${polymer_version}]")
    modImplementation("eu.pb4:polymer-resource-pack-extras:[${polymer_version}]")
    modImplementation("eu.pb4:polymer-virtual-entity:[${polymer_version}]")
    modImplementation("eu.pb4:polymer-autohost:${polymer_version}")
    modImplementation("eu.pb4:polymer-networking:[${polymer_version}]")
    modImplementation("nl.theepicblock:resource-locator-api:${project.resource_locator_version}")
    modImplementation("eu.pb4:factorytools:[${factorytools_version}]")
    modImplementation("eu.pb4:sgui:[${sgui_version}]")
    modImplementation("xyz.nucleoid:server-translations-api:${server_translation_api_version}")
    
    modImplementation files('libs/PolyMc-Extra-XXXXXXX.jar')
    modCompileOnly 'maven.modrinth:polydex:XXXXXX'
}

Patch Code Example

public class PolymerifyRegistry implements PolyMcExtraEntrypoint {

    @Override
    public void onInitialize() {
        PolymerifyRegistry.initialize();
        PolyMcExtraPacks.NAMESPACES.add(getNamespace());
    }
    
    public static void initialize() {
        registerPolymerBlock(BlockRegistry.XXX, XXXPolymerBlock.INSTANCE);
        registerPolymerItem(BlockRegistry.XXX, new PolymerItemImpl(BlockRegistry.XXX.asItem()));
    }

    public static void registerPolymerBlock(Block block, PolymerBlock polymerBlock) {
        ResourceLocation key = BuiltInRegistries.BLOCK.getKey(block);
        PolymerBlock.registerOverlay(block, polymerBlock);
        if (polymerBlock instanceof BlockWithElementHolder elementHolder) {
            BlockWithElementHolder.registerOverlay(block, elementHolder);
        }
        PolyMcExtra.LATE_INIT.add(new Runnable() {
            @Override
            public void run() {
                if (PolymerBlockHelper.testJsonExist(block)) {
                    BlockStateModelManager.addBlock(key, block);
                }
            }
        });
    }

    public static void registerPolymerItem(ItemLike item, PolymerItem polymerItem) {
        PolymerItem.registerOverlay(item.asItem(), polymerItem);
    }
    
    @Override
    public String getNamespace() {
        return MOD_ID;
    }
}

public class XXXPolymerBlock {
    public static final BlockState OVERLAY_0 = PolymerBlockResourceUtils.requestEmpty(BlockModelType.ACTIVE_PRESSURE_PLATE);
    public static final BlockState OVERLAY_1 = PolymerBlockResourceUtils.requestEmpty(BlockModelType.KELP_BLOCK);
    public static final BaseFactoryBlock INSTANCE = new BaseFactoryBlock(OVERLAY_0, false, BlockStateModel::midRange) {
        @Override
        public BlockState getPolymerBlockState(BlockState state, PacketContext context) {
            if (state.hasProperty(BlockStateProperties.WATERLOGGED) && state.getValue(BlockStateProperties.WATERLOGGED)) {
                return OVERLAY_1;
            }
            return super.getPolymerBlockState(state, context);
        }
    };
}

Example Config:

The configuration file is located at /config/polymc-extra.json

{
	"DisabledOpaqueBlocks": [],
	"CustomBlockModelTypeMappings": {
		"citymod:stone_table": "BLOCK_DISPLAY_ENTITY",
		"citymod:road_block": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_yellow": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_yellow_connect": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_white_connect": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_yellow_double": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_zebra_crossing": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:roadblock_oblique": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:roadblock_yellow_oblique": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:roadblock_double_oblique": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:zebracrossing_oblique": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_straight": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"citymod:road_diamond": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:modern_light": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:computer_mouse": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:black_mirror": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:laptop": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:modern_clock": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:led_floor_lamp": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:shower": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:portable_laptop_stand": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:laptop_closed_portable_laptop_stand": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:cooktop": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:keyboard": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:monitor_setup": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:shower": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:socket": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:modern_chair": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"js_furniture_mod:wood_chair": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"^js_furniture_mod:midi_.+$": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"^js_furniture_mod:.*": "BLOCK_DISPLAY_ENTITY",
		"^skniro_furniture:.*_(drawer|cabinet|fridge|kitchen_sink|oven|tv_stand)$": "BLOCK_DISPLAY_ENTITY",
		"^skniro_furniture:.*_(bed|cushion|sofa|window(?:_style.*)?|plate|chair(?:_.*)?|lamp)$": "BLOCK_DISPLAY_ENTITY_NO_COLLISION",
		"^skniro_furniture:.*_window(_.*)?$": "CLOSEABLE_BLOCK",
		"^skniro_furniture:.*_(door)$": "CLOSEABLE_BLOCK",
		"^skniro_furniture:.*_glass_table": "BLOCK_DISPLAY_ENTITY",
		"terrestria:cattail": "WATER_PLANT",
		"terrestria:andisol_grass_block": "POLYMER:BIOME_TRANSPARENT_BLOCK",
		"^storagedelight:.*$": "BLOCK_DISPLAY_ENTITY",
		"^terrestria:.*_log$": "BLOCK_DISPLAY_ENTITY"
	},
	"CustomEntityModelMappings": {
		"js_furniture_mod:chair_entity": "polymc-extra:chair",
		"js_furniture_mod:sofa_entity": "polymc-extra:chair",
		"skniro_furniture:chair_entity": "polymc-extra:chair",
		"skniro_furniture:sofa_entity": "polymc-extra:chair",
		"skniro_furniture:cushion_entity": "polymc-extra:chair",
		"citymod:explode_bow_projectile": "minecraft:arrow",
		"citymod:rifle_legacy_projectile": "minecraft:arrow"
	},
	"CustomModelExpansionMappings": {
		"js_furniture_mod:sofa": 0.0,
		"js_furniture_mod:wood_light_table": 0.0,
		"js_furniture_mod:led_floor_lamp_rgb_off": 0.0,
		"js_furniture_mod:led_floor_lamp_rgb_off_2": 0.0,
		"js_furniture_mod:studio_light": 0.0,
		"citymod:road_block": 0.0,
		"citymod:road_yellow": 0.0,
		"citymod:road_yellow_connect": 0.0,
		"citymod:road_white_connect": 0.0,
		"citymod:road_yellow_double": 0.0,
		"citymod:road_zebra_crossing": 0.0
	}
}

Commands

What this library/mod doesn't do

It does not support client-side rendering.

If the module uses ASM to modify certain enums or replaces Vanilla's registry entries, it will cause some abnormal errors.

License

This mod is partially based on code from enderscape-patch and PolyMc that are licensed with GNU Lesser General Public License v3.0 and GNU Lesser General Public License 3.0

Quick facts

Install steps are the general flow for this file type — How to install Minecraft Java mods & modpacks walks through it step by step.

Verified by MCModsHub

These come from our own check of the pack file, not from the source page.

Explore more