### Install Dependencies and Start Dev Server Source: https://github.com/neoforged/documentation/blob/main/README.md Install project dependencies and start the Docusaurus live development server to preview documentation changes locally. Most changes reflect without a server restart. ```bash npm install npm run start ``` -------------------------------- ### Example Model Provider Setup Source: https://github.com/neoforged/documentation/blob/main/docs/resources/client/models/datagen.md Sets up a `ModelProvider` for a mod, overriding `registerModels` to define block models. ```java public class ExampleModelProvider extends ModelProvider { public ExampleModelProvider(PackOutput output) { // Replace "examplemod" with your own mod id. super(output, "examplemod"); } @Override protected void registerModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels) { // Placeholders, their usages should be replaced with real values. See above for how to use the model builder, // and below for the helpers the model builder offers. Block block = MyBlocksClass.EXAMPLE_BLOCK.get(); // Create a simple block model with the same texture on each side. // The texture must be located at assets//textures/block/.png, where // and are the block's registry name's namespace and path, respectively. // Used by the majority of (full) blocks, such as planks, cobblestone or bricks. blockModels.createTrivialCube(block); // Overload that accepts a `TexturedModel.Provider` to use. blockModels.createTrivialBlock(block, EXAMPLE_TEMPLATE_PROVIDER); // Block items have a model generated automatically // But let's assume you want to generate a different item, such as a flat item blockModels.registerSimpleFlatItemModel(block); // Adds a log block model. Requires two textures at assets//textures/block/.png and // assets//textures/block/_top.png, referencing the side and top texture, respectively. // Note that the block input here is limited to RotatedPillarBlock, which is the class vanilla logs use. blockModels.woodProvider(block).log(block); // Like WoodProvider#logWithHorizontal. Used by quartz pillars and similar blocks. blockModels.createRotatedPillarWithHorizontalVariant(block, TexturedModel.COLUMN_ALT, TexturedModel.COLUMN_HORIZONTAL_ALT); // Using the `ExtendedModelTemplate` to specify the render type to use. blockModels.createRotatedPillarWithHorizontalVariant(block, TexturedModel.COLUMN_ALT.updateTemplate(template -> template.extend().renderType("minecraft:cutout").build() ), TexturedModel.COLUMN_HORIZONTAL_ALT.updateTemplate(template -> template.extend().renderType(this.mcLocation("cutout_mipped")).build() ) ); // Specifies a horizontally-rotatable block model with a side texture, a front texture, and a top texture. // The bottom will use the side texture as well. If you don't need the front or top texture, // just pass in the side texture twice. Used by e.g. furnaces and similar blocks. blockModels.createHorizontallyRotatedBlock( block, TexturedModel.Provider.ORIENTABLE_ONLY_TOP.updateTexture(mapping -> mapping.put(TextureSlot.SIDE, this.modLocation("block/example_texture_side")) .put(TextureSlot.FRONT, this.modLocation("block/example_texture_front")) .put(TextureSlot.TOP, this.modLocation("block/example_texture_top")) ) ); // Specifies a horizontally-rotatable block model that is attached to a face, e.g. for buttons. // Accounts for placing the block on the ground and on the ceiling, and rotates them accordingly. blockModels.familyWithExistingFullBlock(block).button(block); // Create a model to use for blockstatefiles Identifier modelLoc = TexturedModel.CUBE.create(block, blockModels.modelOutput); // Create a common variant to transform Variant variant = new Variant(modelLoc); // Basic single variant model blockModels.blockStateOutput.accept( MultiVariantGenerator.dispatch( block, new MultiVariant( WeightedList.of( new Weighted<>( // Set model variant // Set rotations around the x and y axes .with(VariantMutator.X_ROT.withValue(Quadrant.R90)) .with(VariantMutator.Y_ROT.withValue(Quadrant.R180)) // Set a uvlock ``` -------------------------------- ### Install NeoForge Server on UNIX-like Systems Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Run the downloaded NeoForge installer JAR with the --installServer argument to set up the server files. This command should be executed in the directory where you want to install the server. ```shell java -jar /path/to/neoforge-installer.jar --installServer ``` -------------------------------- ### Example Java Version Output Source: https://github.com/neoforged/documentation/blob/main/user/docs/index.md This is an example of the expected output when Java is installed and the command `java -version` is executed. Verify the version number against Minecraft requirements. ```text openjdk version "21.0.4" 2024-07-16 LTS OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing) ``` -------------------------------- ### Access Transformer Configuration Examples Source: https://github.com/neoforged/documentation/blob/main/docs/advanced/accesstransformers.md Examples demonstrating how to change visibility and modifiers for classes, fields, and methods using Access Transformer syntax. ```text # Makes public the ByteArrayToKeyFunction interface in Crypt public net.minecraft.util.Crypt$ByteArrayToKeyFunction # Makes protected and removes the final modifier from 'random' in MinecraftServer protected-f net.minecraft.server.MinecraftServer random # Makes public the 'makeExecutor' method in Util, # accepting a String and returns a TracingExecutor public net.minecraft.Util makeExecutor(Ljava/lang/String;)Lnet/minecraft/TracingExecutor; # Makes public the 'leastMostToIntArray' method in UUIDUtil, # accepting two longs and returning an int[] public net.minecraft.core.UUIDUtil leastMostToIntArray(JJ)[I ``` -------------------------------- ### Start NeoForge Server on UNIX-like Systems Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Execute the run.sh script to start the NeoForge server. The server will shut down on the first run, requiring EULA acceptance. ```shell ./run.sh ``` -------------------------------- ### Run Documentation Locally Source: https://github.com/neoforged/documentation/blob/main/src/pages/contributing.md Commands to initialize and start the local documentation server. ```bash nvm use # or nvs use on Windows npm install npm run start ``` -------------------------------- ### Start NeoForge Server on Windows Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Execute the run.bat script to start the NeoForge server. The server will shut down on the first run, requiring EULA acceptance. ```batch .\run.bat ``` -------------------------------- ### Install Node.js Version Source: https://github.com/neoforged/documentation/blob/main/README.md Use this command to install or switch to the required Node.js version for the documentation project. Supports version managers like NVM. ```bash nvm install # or 'nvs use' ``` -------------------------------- ### Install OpenJDK 21 on Windows Server using winget Source: https://github.com/neoforged/documentation/blob/main/user/docs/index.md Use this command to install OpenJDK version 21 on Windows Server. Ensure you have winget installed and configured. ```bash winget install -e --id=Microsoft.OpenJDK.21 ``` -------------------------------- ### Example Trigger Instance Codec Implementation Source: https://github.com/neoforged/documentation/blob/main/docs/resources/server/advancements.md An example implementation of a Codec for ExampleTriggerInstance using RecordCodecBuilder, including fields for player and item predicates. ```java public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(ExampleTriggerInstance::player), ItemPredicate.CODEC.fieldOf("item").forGetter(ExampleTriggerInstance::item) ).apply(instance, ExampleTriggerInstance::new)); ``` -------------------------------- ### Download NeoForge Installer for FreeBSD Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Use fetch to download the NeoForge installer JAR file on FreeBSD systems. Ensure you replace version numbers and beta labels as needed. ```shell fetch https://maven.neoforged.net/releases/net/neoforged/neoforge/21.4.111-beta/neoforge-21.4.111-beta-installer.jar ``` -------------------------------- ### Download NeoForge Installer for OpenBSD Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Use ftp to download the NeoForge installer JAR file on OpenBSD systems. Ensure you replace version numbers and beta labels as needed. ```shell ftp https://maven.neoforged.net/releases/net/neoforged/neoforge/21.4.111-beta/neoforge-21.4.111-beta-installer.jar ``` -------------------------------- ### Download NeoForge Installer for Windows Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Use curl to download the NeoForge installer JAR file on Windows systems. Ensure you replace version numbers and beta labels as needed. ```shell curl -O https://maven.neoforged.net/releases/net/neoforged/neoforge/21.4.111-beta/neoforge-21.4.111-beta-installer.jar ``` -------------------------------- ### Download NeoForge Installer for GNU/Linux Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Use wget to download the NeoForge installer JAR file on GNU/Linux systems. Ensure you replace version numbers and beta labels as needed. ```shell wget https://maven.neoforged.net/releases/net/neoforged/neoforge/21.4.111-beta/neoforge-21.4.111-beta-installer.jar ``` -------------------------------- ### Example: Replicating Default Data Generator Arguments Source: https://github.com/neoforged/documentation/blob/main/docs/resources/index.md An example of how to specify arguments in build.gradle to replicate the default behavior of the data generator, including mod ID, output path, and enabling all generator modes. ```groovy runs { // other run configurations here clientData { arguments.addAll '--mod', 'examplemod', // insert your own mod id '--output', file('src/generated/resources').getAbsolutePath(), '--all' } } ``` -------------------------------- ### Encoded JSON Examples for SomeObject Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md Example JSON representations of the SomeObject class, demonstrating field presence, defaults, and error cases. ```json5 // Encoded SomeObject { "s": "value", "i": 5, "b": false } // Another encoded SomeObject { "s": "value2", // i is omitted, defaults to 0 "b": true } // Another encoded SomeObject { "s": "value2", // Will throw an error as lenientOptionalFieldOf is not used "i": "bad_value", "b": true } ``` -------------------------------- ### Implement Pseudocode Method Source: https://github.com/neoforged/documentation/blob/main/src/pages/contributing.md Example of a pseudocode-style method using comments as placeholders for custom logic. ```java // In some class public float applyDiscount(float price) { float newPrice = price; // Apply discount to newPrice // ... return newPrice; } ``` -------------------------------- ### Example Referral URL in TOML Source: https://github.com/neoforged/documentation/blob/main/docs/gettingstarted/modfiles.md A URL to the download page of the dependency. Currently unused. ```toml referralUrl="https://library.example.com/" ``` -------------------------------- ### Access Transformer syntax examples Source: https://github.com/neoforged/documentation/blob/main/docs/advanced/accesstransformers.md Syntax patterns for targeting classes, fields, and methods in an access transformer configuration file. ```text ``` ```text ``` ```text () ``` -------------------------------- ### Example of Item Rendering Configuration Source: https://github.com/neoforged/documentation/blob/main/docs/resources/client/models/items.md This snippet shows an example of configuring item rendering properties, including texture identifiers, rotation, masking, and lighting. It's used when defining custom item models or rendering behaviors. ```java Optional.of(Identifier.fromNamespaceAndPath("neoforge", "item/mask/bucket_fluid_cover")) ), // When true, rotates the model 180 degrees // Defaults to false true, // When true, uses the cover texture as a mask for the base texture // Defaults to true true, // When true, sets the lightmap of the fluid texture layer to its max value // Defaults to true false ) ); } ``` -------------------------------- ### Example of Package Collision Source: https://github.com/neoforged/documentation/blob/main/docs/gettingstarted/structuring.md Demonstrates how identical class names in the same package across different JAR files can lead to loading conflicts. ```text a.jar - com.example.ExampleClass b.jar - com.example.ExampleClass // This class will not normally be loaded ``` -------------------------------- ### Registering Capability for All BucketItems Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/capabilities.md Example of registering a capability for all instances of a specific item class (BucketItem) by iterating through the item registry. ```java // For reference, you can find this code in the `CapabilityHooks` class. for (Item item : BuiltInRegistries.ITEM) { if (item.getClass() == BucketItem.class) { event.registerItem(Capabilities.Fluid.ITEM, (stack, itemAccess) -> new BucketResourceHandler(itemAccess), item); } } ``` -------------------------------- ### Analyze Profiling Results Source: https://github.com/neoforged/documentation/blob/main/docs/misc/debugprofiler.md Example output format from the profiling.txt file showing hierarchical execution data. ```text [00] tick(201/1) - 41.46%/41.46% [01] | levels(201/1) - 96.62%/40.05% [02] | | ServerLevel[New World] minecraft:overworld(201/1) - 98.80%/39.58% [03] | | | tick(201/1) - 99.98%/39.57% [04] | | | | entities(201/1) - 56.83%/22.49% [05] | | | | | tick(44717/222) - 95.81%/21.54% [06] | | | | | | minecraft:skeleton(4585/23) - 13.91%/3.00% [07] | | | | | | | #tickNonPassenger 4585/22 [07] | | | | | | | travel(4573/23) - 33.12%/0.99% [08] | | | | | | | | #getChunkCacheMiss 7/0 [08] | | | | | | | | #getChunk 47227/234 [08] | | | | | | | | move(4573/23) - 40.10%/0.40% [09] | | | | | | | | | #getEntities 4573/22 [09] | | | | | | | | | #getChunkCacheMiss 1353/6 [09] | | | | | | | | | #getChunk 28482/141 [08] | | | | | | | | unspecified(4573/23) - 36.24%/0.36% [08] | | | | | | | | rest(4573/23) - 23.66%/0.23% [09] | | | | | | | | | #getChunkCacheMiss 59/0 [09] | | | | | | | | | #getChunk 65867/327 [09] | | | | | | | | | #getChunkNow 531/2 ``` -------------------------------- ### Configure Mod Metadata Properties Source: https://github.com/neoforged/documentation/blob/main/docs/gettingstarted/modfiles.md Examples of setting various mod metadata fields in the configuration file. ```toml credits="The person over here and there." ``` ```toml authors="Example Person" ``` ```toml displayURL="https://neoforged.net/" ``` ```toml enumExtensions="META_INF/enumextensions.json" ``` ```toml featureFlags="META-INF/feature_flags.json" ``` -------------------------------- ### Define a Custom Resource Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/transactions.md Provides an example of creating a custom Resource implementation, including its backing object, equality, and isEmpty logic. ```java // Let's assume we are trying to represent the following object: public class ExampleObject { public static final ExampleObject EMPTY = new ExampleObject(-1, 0, Map.of()); public static final Codec CODEC = RecordCodecBuilder.of(instance -> instance.group( ExtraCodecs.NON_NEGATIVE_INT.fieldOf("id").forGetter(ExampleObject::id), ExtraCodecs.NON_NEGATIVE_INT.optionalFieldOf("count", 1).forGetter(ExampleObject::count), Codec.unboundedMap(Codec.STRING, Codec.BOOL).optionalFieldOf("flags", Map::of).forGetter(ExampleObject::flags) ).apply(instance, ExampleObject::new) ); private final int id; private final Map flags; private int count; public ExampleObject(int id, int count, Map flags) { // ... } public int id() { return this.id; } public int count() { return this.count; } public void setCount(int count) { this.count = count; } public Map flags() { return this.flags; } } // Create our resource. public final class ExampleResource implements Resource { private final ExampleObject object; public ExampleResource(ExampleObject object) { // Enforce immutability and ignore count. this.object = new ExampleObject( object.id(), 1, ImmutableMap.copyOf(object.flags()) ); } public int id() { return this.object.id(); } public Map flags() { return this.object.flags(); } // Defines when the backing object is considered empty. // This is the only method that `Resource` defines. @Override public boolean isEmpty() { return this.object.id() == -1; } // Equality for classes is defined by implementing `hashCode` // and `equals`. Records already do this for you. @Override public int hashCode() { // Since our backing object is not unique by itself, we // extract the components that make it unique and construct // the hash. return Objects.hash(this.object.id(), this.object.flags()); } @Override public boolean equals(Object obj) { // Check identity equality. if (this == obj) return true; // Check if same class. if (obj == null || this.getClass() != obj.getClass()) return false; // Check the individual components of the resource. ExampleResource other = (ExampleResource) obj; return this.object.id() == other.object.id() && this.object.flags().equals(other.object.flags()); } // Just an ease of convenience to more easily understand what // the resource is representing. @Override public String toString() { return Integer.toString(this.object.id()) + "[" + this.object.flags().size() + "]"; } } ``` -------------------------------- ### Encoded Xor Examples Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md Examples of encoding for `Either.Left` (a number object) and `Either.Right` (a text object) using a xor codec. An example of a failed decode is also shown. ```json5 // Encoded Either.Left { "number": 4 } // Encoded Either.Right { "text": "value" } // Throws an error as both can be decoded { "number": 4, "text": "value" } ``` -------------------------------- ### Screen Initialization with Widgets Source: https://github.com/neoforged/documentation/blob/main/docs/rendering/screens.md Demonstrates the initialization of a screen, including adding a renderable widget. This method is called on initial setup and when the game window is resized. ```java @Override protected void init() { super.init(); // Add widgets and precomputed values this.addRenderableWidget(new EditBox(/* ... */)); } ``` -------------------------------- ### Encoded Either Examples Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md Examples of encoding for `Either.Left` (an integer) and `Either.Right` (a string) using an either codec. ```json5 // Encoded Either.Left 5 // Encoded Either.Right "value" ``` -------------------------------- ### Build Static Documentation Source: https://github.com/neoforged/documentation/blob/main/README.md Generate a static version of the documentation website for deployment. The output is placed in the 'build' directory and can be hosted by any static hosting service. ```bash npm run build ``` -------------------------------- ### Get Data Component from DataComponentHolder Source: https://github.com/neoforged/documentation/blob/main/docs/items/datacomponents.md Retrieves a data component using the DataComponentHolder interface, which delegates to DataComponentMap#get. ```java // For some DataComponentHolder holder // Delegates to 'DataComponentMap#get' @Nullable DyeColor color = holder.get(DataComponents.BASE_COLOR); ``` -------------------------------- ### Tag JSON Structure Example Source: https://github.com/neoforged/documentation/blob/main/docs/resources/server/tags.md An example of the JSON structure generated for a tag provider, showing 'values' and 'remove' arrays. ```json { "values": [ "minecraft:dirt", "minecraft:cobblestone", { "id": "botania:pure_daisy", "required": false }, "#minecraft:planks", "#minecraft:logs", "#minecraft:wooden_slabs", { "id": "c:ingots/tin", "required": false }, { "id": "c:nuggets/tin", "required": false }, { "id": "c:storage_blocks/tin", "required": false } ], "remove": [ "minecraft:crimson_slab", "minecraft:warped_slab" ] } ``` -------------------------------- ### Check Java Version Source: https://github.com/neoforged/documentation/blob/main/user/docs/index.md Use this command in your terminal to check if Java is installed and to determine its version. An error indicates Java is not installed. ```bash java -version ``` -------------------------------- ### Encoded Recursive Object Example Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md An example of an encoded recursive object, showing nested 'inner' fields representing the recursive structure. ```json5 // An encoded recursive object { "inner": { "inner": {} } } ``` -------------------------------- ### Encoded Pair Example Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md An example showing how a `Pair` is encoded, with 'left' and 'right' keys corresponding to the pair elements. ```json5 // Encoded Pair { "left": 5, // fieldOf looks up 'left' key for left object "right": "value" // fieldOf looks up 'right' key for right object } ``` -------------------------------- ### Basic Container Implementation Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/container.md A sample implementation of the Container interface for a 27-slot container, demonstrating methods for item manipulation and state management. Use NeoForge's ItemStacksResourceHandler if possible. ```java public class MyContainer implements Container { private final NonNullList items = NonNullList.withSize( // The size of the list, i.e. the amount of slots in our container. 27, // The default value to be used in place of where you'd use null in normal lists. ItemStack.EMPTY ); // The amount of slots in our container. @Override public int getContainerSize() { return 27; } // Whether the container is considered empty. @Override public boolean isEmpty() { return this.items.stream().allMatch(ItemStack::isEmpty); } // Return the item stack in the specified slot. @Override public ItemStack getItem(int slot) { return this.items.get(slot); } // Remove the specified amount of items from the given slot, returning the stack that was just removed. // We defer to ContainerHelper here, which does this as expected for us. // However, we must call #setChanged manually. @Override public ItemStack removeItem(int slot, int amount) { ItemStack stack = ContainerHelper.removeItem(this.items, slot, amount); this.setChanged(); return stack; } // Remove all items from the specified slot, returning the stack that was just removed. // We again defer to ContainerHelper here, and we again have to call #setChanged manually. @Override public ItemStack removeItemNoUpdate(int slot) { ItemStack stack = ContainerHelper.takeItem(this.items, slot); this.setChanged(); return stack; } // Set the given item stack in the given slot. Limit to the max stack size of the container first. @Override public void setItem(int slot, ItemStack stack) { stack.limitSize(this.getMaxStackSize(stack)); this.items.set(slot, stack); this.setChanged(); } // Call this when changes are done to the container, i.e. when item stacks are added, modified, or removed. // For example, you could call BlockEntity#setChanged here. @Override public void setChanged() { } // Whether the container is considered "still valid" for the given player. For example, chests and // similar blocks check if the player is still within a given distance of the block here. @Override public boolean stillValid(Player player) { return true; } // Clear the internal storage, setting all slots to empty again. @Override public void clearContent() { items.clear(); this.setChanged(); } } ``` -------------------------------- ### Implement ExampleModelProvider Source: https://github.com/neoforged/documentation/blob/main/docs/resources/client/models/datagen.md Extend `ModelProvider` and override `registerModels` to define your model generation logic. Replace 'examplemod' with your mod ID. ```java public class ExampleModelProvider extends ModelProvider { public ExampleModelProvider(PackOutput output) { // Replace "examplemod" with your own mod id. super(output, "examplemod"); } @Override protected void registerModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels) { // Generate models and associated files here } } ``` -------------------------------- ### Implement PlacementInfo in a Recipe Source: https://github.com/neoforged/documentation/blob/main/docs/resources/server/recipes/custom.md Demonstrates creating PlacementInfo using createFromOptionals to handle potential empty slots in a custom recipe. ```java public class RightClickBlockRecipe implements Recipe { // other stuff here private PlacementInfo info; @Override public PlacementInfo placementInfo() { // This delegate is in case the ingredient is not fully populated at this point in time // Tags and recipes are loaded at the same time, which is why this might be the case. if (this.info == null) { // Use optional ingredient as the block state may have an item representation List> ingredients = new ArrayList<>(); Item stateItem = this.inputState.getBlock().asItem(); ingredients.add(stateItem != Items.AIR ? Optional.of(Ingredient.of(stateItem)): Optional.empty()); ingredients.add(Optional.of(this.inputItem)); // Create placement info this.info = PlacementInfo.createFromOptionals(ingredients); } return this.info; } } ``` -------------------------------- ### Encoded Unbounded Map Example Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md An example of how a `Map` is encoded, where keys are strings and values are BlockPos objects represented as arrays. ```json5 // Encoded Map { "key1": [1, 2, 3], // key1 -> BlockPos(1, 2, 3) "key2": [4, 5, 6], // key2 -> BlockPos(4, 5, 6) "key3": [7, 8, 9] // key3 -> BlockPos(7, 8, 9) } ``` -------------------------------- ### Implementing Blockstate Properties in a Block Class Source: https://github.com/neoforged/documentation/blob/main/docs/blocks/states.md Example demonstrating the registration of properties and setting the default state within a block class. ```java public class EndPortalFrameBlock extends Block { // Note: It is possible to directly use the values in BlockStateProperties instead of referencing them here again. // However, for the sake of simplicity and readability, it is recommended to add constants like this. public static final EnumProperty FACING = BlockStateProperties.FACING; public static final BooleanProperty EYE = BlockStateProperties.EYE; public EndPortalFrameBlock(BlockBehaviour.Properties properties) { super(properties); // stateDefinition.any() returns a random BlockState from an internal set, // we don't care because we're setting all values ourselves anyway this.registerDefaultState(stateDefinition.any() .setValue(FACING, Direction.NORTH) .setValue(EYE, false) ); } @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { // this is where the properties are actually added to the state builder.add(FACING, EYE); } @Override @Nullable public BlockState getStateForPlacement(BlockPlaceContext ctx) { // code that determines which state will be used when // placing down this block, depending on the BlockPlaceContext } } ``` -------------------------------- ### Encoded Alternative Codec Examples Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/codecs.md Examples demonstrating decoding a `BlockPos` using its normal array format and an alternative object format with x, y, and z fields. ```json5 // Normal method to decode BlockPos [ 1, 2, 3 ] // Alternative method to decode BlockPos { "x": 1, "y": 2, "z": 3 } ``` -------------------------------- ### Java Package Structure Example Source: https://github.com/neoforged/documentation/blob/main/docs/gettingstarted/modfiles.md Demonstrates the expected Java source code directory structure based on the group ID and mod ID. ```text com - example (top-level package specified in group property) - mymod (the mod id) - MyMod.java (renamed ExampleMod.java) ``` -------------------------------- ### Create Item and Fluid Resources Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/transactions.md Demonstrates how to create ItemResource and FluidResource instances using static factory methods. ```java ItemResource item = ItemResource.of(Items.EMERALD); ItemStack stack = new ItemStack(Items.APPLE); stack.set(DataComponents.CUSTOM_NAME, Component.literal("Apple?")); ItemResource itemWithComponents = ItemResource.of(stack); FluidResource fluid = FluidResource.of(Fluids.WATER); ``` -------------------------------- ### Opening a Menu with SimpleMenuProvider Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/menus.md Demonstrates how to open a custom menu for a player using SimpleMenuProvider. This is typically done on the server-side. ```java serverPlayer.openMenu(new SimpleMenuProvider( (containerId, playerInventory, player) -> new MyMenu(containerId, playerInventory, /* server parameters */), Component.translatable("menu.title.examplemod.mymenu") )); ``` -------------------------------- ### Download NeoForge Installer for macOS Source: https://github.com/neoforged/documentation/blob/main/user/docs/server.md Use curl to download the NeoForge installer JAR file on macOS. Ensure you replace version numbers and beta labels as needed. ```shell curl -LO https://maven.neoforged.net/releases/net/neoforged/neoforge/21.4.111-beta/neoforge-21.4.111-beta-installer.jar ``` -------------------------------- ### Concrete Example: Query Item Handler Block Capability Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/capabilities.md Example of querying an item handler capability for a block from a specific direction (NORTH). Handles cases where the handler might not be present. ```java ResourceHandler handler = level.getCapability(Capabilities.Item.BLOCK, pos, Direction.NORTH); if (handler != null) { // Use the handler for some item-related operation. } ``` -------------------------------- ### Example Test Instance JSON Configuration Source: https://github.com/neoforged/documentation/blob/main/docs/misc/gametest.md This JSON file configures a custom test instance for use in a datapack. It includes fields for `TestData` and the custom `ExampleTestInstance` parameters. ```json5 // For some game test examplemod:example_test // In 'data/examplemod/test_instance/example_test.json' { // `TestData` "environment": "examplemod:example_environment", "structure": "examplemod:example_structure", "max_ticks": 400, "setup_ticks": 50, "required": true, "rotation": "clockwise_90", "manual_only": true, "max_attempts": 3, "required_successes": 1, "sky_access": false, // `ExampleTestInstance` "type": "examplemod:example_test_instance", "value1": 0, "value2": true } ``` -------------------------------- ### Wrapping Vanilla Inventories with Resource Handlers Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/transactions.md Shows how to create ResourceHandlers that wrap around existing vanilla game inventories such as containers, player inventories, and entity equipment. ```java Container container = new SimpleContainer(5); ResourceHandler containerWrapper = VanillaContainerWrapper.of(container); ``` ```java ResourceHandler playerInv = PlayerInventoryWrapper.of(player); ``` ```java ResourceHandler head = LivingEntityEquipmentWrapper.of(entity, EquipmentSlot.HEAD); ``` -------------------------------- ### Menu Access Constructors Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/menus.md Demonstrates server and client constructors for menu access, utilizing ContainerLevelAccess. ```java // Client menu constructor public MyMenuAccess(int containerId, Inventory playerInventory) { this(containerId, playerInventory, ContainerLevelAccess.NULL); } // Server menu constructor public MyMenuAccess(int containerId, Inventory playerInventory, ContainerLevelAccess access) { // ... } // Assume this menu is attached to Supplier MY_BLOCK @Override public boolean stillValid(Player player) { return AbstractContainerMenu.stillValid(this.access, player, MY_BLOCK.get()); } ``` -------------------------------- ### Define Equipment Asset JSON Source: https://github.com/neoforged/documentation/blob/main/docs/items/armor.md Example of a JSON configuration for equipment textures. ```json "texture": "examplemod:copper/nautilus", "use_player_texture": true } ] } } ``` -------------------------------- ### Get data from a CompoundTag Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/nbt.md Retrieve values from a tag, which are returned as Optional objects. ```java Optional color = tag.getInt("Color"); Optional level = tag.getString("Level"); Optional d = tag.getDouble("IAmRunningOutOfIdeasForNamesHere"); ``` -------------------------------- ### Implementing MenuProvider for Blocks Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/menus.md Shows how to implement MenuProvider in a Block subclass to allow players to open a menu by interacting with the block. This also supports spectator mode viewing. ```java @Override public MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) { return new SimpleMenuProvider(/* ... */); } @Override public InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult result) { if (!level.isClientSide() && player instanceof ServerPlayer serverPlayer) { serverPlayer.openMenu(state.getMenuProvider(level, pos)); } return InteractionResult.SUCCESS; } ``` -------------------------------- ### Registering Default Attributes Source: https://github.com/neoforged/documentation/blob/main/docs/entities/attributes.md Example of how to register default attributes for a LivingEntity using the `EntityAttributeCreationEvent`. ```APIDOC ## Registering Default Attributes When creating a `LivingEntity`, it is required to register a set of default attributes for them. This is done during the `EntityAttributeCreationEvent`. ### Event Subscription ```java @SubscribeEvent // on the mod event bus public static void createDefaultAttributes(EntityAttributeCreationEvent event) { event.put( // Your entity type. MY_ENTITY.get(), // An AttributeSupplier. This is typically created by calling LivingEntity#createLivingAttributes, // setting your values on it, and calling #build. You can also create the AttributeSupplier from scratch // if you want, see the source of LivingEntity#createLivingAttributes for an example. LivingEntity.createLivingAttributes() // Add an attribute with its default value. .add(Attributes.MAX_HEALTH) // Add an attribute with a non-default value. .add(Attributes.MAX_HEALTH, 50) // Build the AttributeSupplier. .build() ); } ``` ### Note on Specialized Methods Some classes have specialized versions of `LivingEntity#createLivingAttributes`. For example, the `Monster` class has a method named `Monster#createMonsterAttributes` that can be used instead. ``` -------------------------------- ### Define EquipmentClientInfo JSON Source: https://github.com/neoforged/documentation/blob/main/docs/items/armor.md Example configuration for copper armor rendering, including humanoid, wolf, horse, and nautilus layers with optional tinting and texture overrides. ```json // In assets/examplemod/equipment/copper.json { // The layer map "layers": { // The serialized name of the EquipmentClientInfo.LayerType to apply. // For humanoid head, chest, and feet "humanoid": [ // A list of layers to render in the order provided { // The relative texture of the armor // Points to assets/examplemod/textures/entity/equipment/humanoid/copper/outer.png "texture": "examplemod:copper/outer" }, { // The overlay texture // Points to assets/examplemod/textures/entity/equipment/humanoid/copper/outer_overlay.png "texture": "examplemod:copper/outer_overlay", // When specified, allows the texture to be tinted the color in DataComponents#DYED_COLOR // Otherwise, cannot be tinted "dyeable": { // An RGB value (always opaque color) // 0x7683DE as decimal // When not specified, set to 0 (meaning transparent or invisible) "color_when_undyed": 7767006 } } ], // For humanoid legs "humanoid_leggings": [ { // Points to assets/examplemod/textures/entity/equipment/humanoid_leggings/copper/inner.png "texture": "examplemod:copper/inner" }, { // Points to assets/examplemod/textures/entity/equipment/humanoid_leggings/copper/inner_overlay.png "texture": "examplemod:copper/inner_overlay", "dyeable": { "color_when_undyed": 7767006 } } ], // For wolf armor "wolf_body": [ { // Points to assets/examplemod/textures/entity/equipment/wolf_body/copper/wolf.png "texture": "examplemod:copper/wolf", // When true, uses the texture passed into the layer renderer instead "use_player_texture": true } ], // For horse armor "horse_body": [ { // Points to assets/examplemod/textures/entity/equipment/horse_body/copper/horse.png "texture": "examplemod:copper/horse", "use_player_texture": true } ], // For nautilus armor "nautilus_body": [ { // Points to assets/examplemod/textures/entity/equipment/nautilus_body/copper/nautilus.png "texture": "examplemod:copper/nautilus" } ] } } ``` -------------------------------- ### Get data with defaults Source: https://github.com/neoforged/documentation/blob/main/docs/datastorage/nbt.md Retrieve values with a specified default fallback if the key is missing. ```java int color = tag.getIntOr("Color", 0xffffff); String level = tag.getStringOr("Level", "minecraft:overworld"); double d = tag.getDoubleOr("IAmRunningOutOfIdeasForNamesHere", 1d); ``` -------------------------------- ### Implement a BlockTagsProvider Source: https://github.com/neoforged/documentation/blob/main/docs/resources/server/tags.md Example implementation of a custom block tag provider using the IntrinsicHolderTagsProvider pattern. ```java public class MyBlockTagsProvider extends BlockTagsProvider { // Get parameters from one of the `GatherDataEvent`s. public MyBlockTagsProvider(PackOutput output, CompletableFuture lookupProvider) { super(output, lookupProvider, ExampleMod.MOD_ID); } // Add your tag entries here. @Override protected void addTags(HolderLookup.Provider lookupProvider) { // Create a TagAppender of registry objects for our tag. This could also be e.g. a vanilla or NeoForge tag. this.tag(MY_TAG) // Add entries. This is a vararg parameter. // Key tag providers must provide ResourceKeys here instead of the actual objects. .add(Blocks.DIRT, Blocks.COBBLESTONE) // Add optional entries that will be ignored if absent. This example uses Botania's Pure Daisy. // This is not a vararg parameter. .add(TagEntry.optionalElement(Identifier.fromNamespaceAndPath("botania", "pure_daisy"))) // Add a tag entry. .addTag(BlockTags.PLANKS) // Add multiple tag entries. This is a vararg parameter. // Can cause unchecked warnings that can safely be suppressed. .addTags(BlockTags.LOGS, BlockTags.WOODEN_SLABS) // Add an optional tag entry that will be ignored if absent. .addOptionalTag(ItemTags.create(Identifier.fromNamespaceAndPath("c", "ingots/tin"))) // Add multiple optional tag entries. This is a vararg parameter. // Can cause unchecked warnings that can safely be suppressed. ``` -------------------------------- ### Creating a KeyMapping with GUI Context and Mouse Input Source: https://github.com/neoforged/documentation/blob/main/docs/misc/keymappings.md Create a KeyMapping that is only active in GUI contexts, uses mouse input, and is assigned to a specific category. ```java import net.minecraft.client.KeyMapping; import net.minecraft.client.KeyConflictContext; import net.minecraft.client.InputConstants; import org.lwjgl.glfw.GLFW; new KeyMapping( "key.examplemod.example2", KeyConflictContext.GUI, // Mapping can only be used when a screen is open InputConstants.Type.MOUSE, // Default mapping is on the mouse GLFW.GLFW_MOUSE_BUTTON_LEFT, // Default mouse input is the left mouse button EXAMPLE_CATEGORY // Mapping will be in the new example category ) ``` -------------------------------- ### Add dependencies for 1.21.9+ Source: https://github.com/neoforged/documentation/blob/main/toolchain/docs/dependencies/nonmclibs.md Add a library to the classpath for both compile and runtime environments. ```gradle // This adds the library at compile and runtime // In practice, this should be wrapped with 'jarJar' // to include the library in your jar implementation 'com.example:example:1.0' ``` -------------------------------- ### ExampleResourceHandler Implementation Source: https://github.com/neoforged/documentation/blob/main/docs/inventories/transactions.md This Java code demonstrates how to implement SnapshotJournal within a custom ResourceHandler. It includes methods for creating snapshots, reverting to previous states, and handling resource insertions and extractions while ensuring transactional integrity. ```java public class ExampleResourceHandler extends SnapshotJournal implements ResourceHandler { private ExampleObject object; public ExampleResourceHandler(ExampleObject object) { // ... } // ... @Override protected ExampleObject createSnapshot() { // Create a snapshot of the object. // This should be immutable. ExampleObject original = this.object; this.object = new ExampleObject( original.id(), original.count(), ImmutableMap.copyOf(original.flags()) ); return original; } @Override protected void revertToSnapshot(ExampleObject snapshot) { // Reverts the state of the handler to the snapshot. this.object = snapshot; } // We need to update the insert and extract methods to make snapshots before // every modification. @Override public int insert(int index, ExampleResource resource, int amount, TransactionContext transaction) { // Inserts the resource into the given index, returning the amount put in. // Validate arguments. Objects.checkIndex(index, size()); TransferPreconditions.checkNonEmptyNonNegative(resource, amount); // Check whether the resource can be inserted from this location. ExampleObject current = this.object; if (current.count() == 0 || (current.id() == resource.id() && current.flags().equals(resource.flags()) && this.isValid(index, resource))) { // Compute the amount to insert. int insertedAmount = Math.min(amount, this.getCapacityAsInt(index, resource) - current.count()); if (insertedAmount > 0) { // Snapshot the handler before modifying the contents. this.updateSnapshots(transaction); // Update the content. if (current.count() == 0) { this.object = new ExampleObject( resource.id(), insertedAmount, new HashMap<>(resource.flags()) ); } else { this.object.setCount(current.count() + insertedAmount); } // Return the amount inserted. return insertedAmount; } } // If not matching, insert nothing. return 0; } @Override public int extract(int index, ExampleResource resource, int amount, TransactionContext transaction) { // Extracts the contents from the given index, returning the amount taken out. // Validate arguments. Objects.checkIndex(index, size()); TransferPreconditions.checkNonEmptyNonNegative(resource, amount); // Check whether the resource can be extracted from this location. ExampleObject current = this.object; if (current.id() == resource.id() && current.flags().equals(resource.flags())) { // Compute the amount to extract. int extracted = Math.min(current.count(), amount); if (extracted > 0) { // Snapshot the handler before modifying the contents. this.updateSnapshots(transaction); // Update the content. this.object.setCount(current.count() - extracted); // Return the amount extracted. return extracted; } } // If not matching, extract nothing. return 0; } } ``` -------------------------------- ### Get Stack Count with ItemInstance Source: https://github.com/neoforged/documentation/blob/main/docs/items/index.md Retrieve the stack size from an ItemInstance, which can be either an ItemStack or ItemStackTemplate. ```java count ```