diff --git a/.gitignore b/.gitignore index fc56de01d..a308797f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Folders /node_modules /.vitepress/cache +/.vitepress/.temp /.vitepress/dist .idea/ .obsidian/ diff --git a/.vitepress/config.mts b/.vitepress/config.mts index b17aba294..e66afb7ba 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -17,6 +17,9 @@ export default defineVersionedConfig( lastUpdated: true, + // Reduce the size of the dist by using a separate js file for the metadata. + metaChunk: true, + locales: loadLocales(__dirname), markdown: { @@ -49,6 +52,14 @@ export default defineVersionedConfig( themeConfig: { search: { + options: { + _render(src, env, md) { + if (env.frontmatter?.search === false) return ""; + if (env.relativePath.startsWith("translated/")) return ""; + if (env.relativePath.startsWith("versions/")) return ""; + return md.render(src, env); + }, + }, provider: "local", }, }, @@ -56,7 +67,7 @@ export default defineVersionedConfig( transformPageData, versioning: { - latestVersion: "1.21", + latestVersion: "1.21.4", rewrites: { localePrefix: "translated", }, diff --git a/.vitepress/sidebars/versioned/1.21.json b/.vitepress/sidebars/versioned/1.21.json new file mode 100644 index 000000000..84418b803 --- /dev/null +++ b/.vitepress/sidebars/versioned/1.21.json @@ -0,0 +1,324 @@ +{ + "/players/": [ + { + "text": "players.title", + "link": "/players/", + "items": [ + { + "text": "players.faq", + "link": "/players/faq" + }, + { + "text": "players.installingJava", + "collapsed": true, + "items": [ + { + "text": "players.installingJava.windows", + "link": "/players/installing-java/windows" + }, + { + "text": "players.installingJava.macOS", + "link": "https://fabricmc.net/wiki/player:tutorials:java:mac", + "process": false + }, + { + "text": "players.installingJava.linux", + "link": "/players/installing-java/linux" + } + ] + }, + { + "text": "players.installingFabric", + "link": "/players/installing-fabric" + }, + { + "text": "players.findingMods", + "link": "/players/finding-mods" + }, + { + "text": "players.installingMods", + "link": "/players/installing-mods" + }, + { + "text": "players.troubleshooting", + "items": [ + { + "text": "players.troubleshooting.uploadingLogs", + "link": "/players/troubleshooting/uploading-logs" + }, + { + "text": "players.troubleshooting.crashReports", + "link": "/players/troubleshooting/crash-reports" + } + ] + }, + { + "text": "players.updatingFabric", + "link": "/players/updating-fabric" + } + ] + } + ], + "/develop/": [ + { + "text": "develop.title", + "link": "/develop/", + "collapsed": false, + "items": [ + { + "text": "Fabric API GitHub", + "translatable": false, + "link": "https://github.com/FabricMC/fabric" + }, + { + "text": "Yarn GitHub", + "translatable": false, + "link": "https://github.com/FabricMC/yarn" + }, + { + "text": "Loom GitHub", + "translatable": false, + "link": "https://github.com/FabricMC/fabric-loom" + } + ] + }, + { + "text": "develop.gettingStarted", + "collapsed": false, + "items": [ + { + "text": "develop.gettingStarted.introduction", + "link": "/develop/getting-started/introduction-to-fabric-and-modding" + }, + { + "text": "develop.gettingStarted.devEnvSetup", + "link": "/develop/getting-started/setting-up-a-development-environment" + }, + { + "text": "develop.gettingStarted.creatingProject", + "link": "/develop/getting-started/creating-a-project" + }, + { + "text": "develop.gettingStarted.projectStructure", + "link": "/develop/getting-started/project-structure" + }, + { + "text": "develop.gettingStarted.launchGame", + "link": "/develop/getting-started/launching-the-game" + } + ] + }, + { + "text": "develop.items", + "collapsed": true, + "items": [ + { + "text": "develop.items.first-item", + "link": "/develop/items/first-item" + }, + { + "text": "develop.items.food", + "link": "/develop/items/food" + }, + { + "text": "develop.items.custom-tools", + "link": "/develop/items/custom-tools" + }, + { + "text": "develop.items.custom-armor", + "link": "/develop/items/custom-armor" + }, + { + "text": "develop.items.custom-item-groups", + "link": "/develop/items/custom-item-groups" + }, + { + "text": "develop.items.custom-item-interactions", + "link": "/develop/items/custom-item-interactions" + }, + { + "text": "develop.items.custom-enchantment-effects", + "link": "/develop/items/custom-enchantment-effects" + }, + { + "text": "develop.items.custom-data-components", + "link": "/develop/items/custom-data-components" + }, + { + "text": "develop.items.potions", + "link": "/develop/items/potions" + } + ] + }, + { + "text": "develop.blocks", + "collapsed": true, + "items": [ + { + "text": "develop.blocks.first-block", + "link": "/develop/blocks/first-block" + }, + { + "text": "develop.blocks.blockstates", + "link": "/develop/blocks/blockstates" + }, + { + "text": "develop.blocks.block-entities", + "link": "/develop/blocks/block-entities", + "items": [ + { + "text": "develop.blocks.block-entity-renderer", + "link": "/develop/blocks/block-entity-renderer" + } + ] + } + ] + }, + { + "text": "develop.entities", + "collapsed": true, + "items": [ + { + "text": "develop.entities.effects", + "link": "/develop/entities/effects" + }, + { + "text": "develop.entities.damage-types", + "link": "/develop/entities/damage-types" + } + ] + }, + { + "text": "develop.sounds", + "collapsed": true, + "items": [ + { + "text": "develop.sounds.using-sounds", + "link": "/develop/sounds/using-sounds" + }, + { + "text": "develop.sounds.custom", + "link": "/develop/sounds/custom" + }, + { + "text": "develop.sounds.dynamic-sounds", + "link": "/develop/sounds/dynamic-sounds" + } + ] + }, + { + "text": "develop.commands", + "collapsed": true, + "items": [ + { + "text": "develop.commands.basics", + "link": "/develop/commands/basics" + }, + { + "text": "develop.commands.arguments", + "link": "/develop/commands/arguments" + }, + { + "text": "develop.commands.suggestions", + "link": "/develop/commands/suggestions" + } + ] + }, + { + "text": "develop.rendering", + "collapsed": true, + "items": [ + { + "text": "develop.rendering.basicConcepts", + "link": "/develop/rendering/basic-concepts" + }, + { + "text": "develop.rendering.drawContext", + "link": "/develop/rendering/draw-context" + }, + { + "text": "develop.rendering.hud", + "link": "/develop/rendering/hud" + }, + { + "text": "develop.rendering.gui", + "items": [ + { + "text": "develop.rendering.gui.customScreens", + "link": "/develop/rendering/gui/custom-screens" + }, + { + "text": "develop.rendering.gui.customWidgets", + "link": "/develop/rendering/gui/custom-widgets" + } + ] + }, + { + "text": "develop.rendering.particles", + "items": [ + { + "text": "develop.rendering.particles.creatingParticles", + "link": "/develop/rendering/particles/creating-particles" + } + ] + } + ] + }, + { + "text": "develop.dataGeneration", + "collapsed": true, + "items": [ + { + "text": "develop.dataGeneration.setup", + "link": "/develop/data-generation/setup" + }, + { + "text": "develop.dataGeneration.tags", + "link": "/develop/data-generation/tags" + }, + { + "text": "develop.dataGeneration.translations", + "link": "/develop/data-generation/translations" + }, + { + "text": "develop.dataGeneration.advancements", + "link": "/develop/data-generation/advancements" + }, + { + "text": "develop.dataGeneration.recipes", + "link": "/develop/data-generation/recipes" + }, + { + "text": "develop.dataGeneration.lootTables", + "link": "/develop/data-generation/loot-tables" + } + ] + }, + { + "text": "develop.misc", + "collapsed": true, + "items": [ + { + "text": "develop.misc.codecs", + "link": "/develop/codecs" + }, + { + "text": "develop.misc.events", + "link": "/develop/events" + }, + { + "text": "develop.misc.text-and-translations", + "link": "/develop/text-and-translations" + }, + { + "text": "develop.misc.ideTipsAndTricks", + "link": "/develop/ide-tips-and-tricks" + }, + { + "text": "develop.misc.automatic-testing", + "link": "/develop/automatic-testing" + } + ] + } + ] +} \ No newline at end of file diff --git a/.vitepress/theme/components/VersionReminder.vue b/.vitepress/theme/components/VersionReminder.vue index 97fa48a52..bafb65aab 100644 --- a/.vitepress/theme/components/VersionReminder.vue +++ b/.vitepress/theme/components/VersionReminder.vue @@ -4,7 +4,7 @@ import { ref, watchEffect } from "vue"; const data = useData(); const route = useRoute(); -const LATEST = "1.21"; +const LATEST = "1.21.4"; const path = ref(""); const text = ref(""); diff --git a/.vitepress/update.ts b/.vitepress/update.ts index 229582841..91cbcee91 100644 --- a/.vitepress/update.ts +++ b/.vitepress/update.ts @@ -1,6 +1,5 @@ import * as glob from "glob"; import fs from "node:fs"; -import { EOL } from "node:os"; import prompts from "prompts"; import develop from "./sidebars/develop"; @@ -138,40 +137,11 @@ import players from "./sidebars/players"; console.log("Updated internal links."); - console.log("Adding search:false frontmatter to all markdown files..."); - - for (const file of versionedMarkdownFiles) { - const data = fs.readFileSync(file, "utf-8"); - // Check if the file has frontmatter - if (data.startsWith("---")) { - // Find the end of the frontmatter - const endOfFrontmatter = data.indexOf("---", 3); - - // Extract the frontmatter - let frontmatter = data.slice(0, endOfFrontmatter); - - // Add 'search: false' to the frontmatter - if (!frontmatter.includes("search:")) { - frontmatter += EOL + "search: false"; - - // Replace the old frontmatter with the updated one - const updatedData = frontmatter + data.slice(endOfFrontmatter); - - // Write the updated data back to the file - fs.writeFile(file, updatedData, function (err) { - if (err) { - console.log(err); - } - }); - } - } - } - console.log("Adding warning box to index.md..."); fs.writeFileSync( - `./versions/${oldVersion}index.md`, + `./versions/${oldVersion}/index.md`, fs - .readFileSync(`./versions/${oldVersion}index.md`, "utf-8") + .readFileSync(`./versions/${oldVersion}/index.md`, "utf-8") .replace( /^---\n\n/m, [ diff --git a/develop/blocks/block-entity-renderer.md b/develop/blocks/block-entity-renderer.md index 8cf93f200..b014a4186 100644 --- a/develop/blocks/block-entity-renderer.md +++ b/develop/blocks/block-entity-renderer.md @@ -7,7 +7,7 @@ authors: # Block Entity Renderers {#block-entity-renderers} -Sometimes, using Minecraft's model format is not enough. If you need to add dynamic rendering to it, you will need to use a `BlockEntityRenderer`. +Sometimes, using Minecraft's model format is not enough. If you need to add dynamic rendering to your block's visuals, you will need to use a `BlockEntityRenderer`. For example, let's make the Counter Block from the [Block Entities article](../blocks/block-entities) show the number of clicks on its top side. @@ -24,7 +24,7 @@ Also, by including a constructor like this, it becomes possible to use the const @[code transcludeWith=:::1](@/reference/latest/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java) -Add the entrypoint to the `fabric.mod.json` file, so that the renderer is registered. +You should register block entity renderers in your `ClientModInitializer` class. `BlockEntityRendererFactories` is a registry that maps each `BlockEntityType` with custom rendering code to its respective `BlockEntityRenderer`. diff --git a/develop/blocks/blockstates.md b/develop/blocks/blockstates.md index 815d9ecf3..cfdcc77ee 100644 --- a/develop/blocks/blockstates.md +++ b/develop/blocks/blockstates.md @@ -40,7 +40,7 @@ Since the pillar block has two positions, horizontal and vertical, we'll need to An example of the `condensed_oak_log_horizontal.json` file: -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) --- @@ -56,7 +56,7 @@ Next, we need to create a blockstate file. The blockstate file is where the magi - `axis=y` - When the block is placed along the Y axis, we will use the normal vertical model. - `axis=z` - When the block is placed along the Z axis, we will rotate the model to face the positive X direction. -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) As always, you'll need to create a translation for your block, and an item model which parents either of the two models. @@ -82,10 +82,6 @@ You'll also have to set a default state for the `activated` property in the cons @[code transcludeWith=:::3](@/reference/latest/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) -::: warning -Don't forget to register your block using the custom class instead of `Block`! -::: - ### Using The Property {#using-the-property} This example flips the boolean `activated` property when the player interacts with the block. We can override the `onUse` method for this: @@ -108,6 +104,10 @@ Since this block only has two possible variants, as it only has one property (`a @[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) +::: tip +Dont forget to add an [Item Model Description](../items/first-item#creating-the-item-model-description) for the block so that it will show in the inventory! +::: + --- Since the example block is a lamp, we also need to make it emit light when the `activated` property is true. This can be done through the block settings passed to the constructor when registering the block. diff --git a/develop/blocks/first-block.md b/develop/blocks/first-block.md index 1119a6dc8..a7a4c8c33 100644 --- a/develop/blocks/first-block.md +++ b/develop/blocks/first-block.md @@ -49,6 +49,9 @@ We will not cover all the options here—you can view the class yourself to see For example purposes, we will be creating a simple block that has the properties of dirt, but is a different material. +- We need a `RegistryKey` which is used as a unique identifier for our block, this is passed into `Registry.register` in the previous utility method. +- The `RegistryKey` is also required by the `AbstractBlock.Settings` builder. + ::: tip You can also use `AbstractBlock.Settings.copy(AbstractBlock block)` to copy the settings of an existing block, in this case, we could have used `Blocks.DIRT` to copy the settings of dirt, but for example purposes we'll use the builder. ::: @@ -57,13 +60,15 @@ You can also use `AbstractBlock.Settings.copy(AbstractBlock block)` to copy the To automatically create the block item, we can pass `true` to the `shouldRegisterItem` parameter of the `register` method we created in the previous step. -### Adding Your Block to an Item Group {#adding-your-block-to-an-item-group} +### Adding Your Block's Item to an Item Group {#adding-your-block-s-item-to-an-item-group} Since the `BlockItem` is automatically created and registered, to add it to an item group, you must use the `Block.asItem()` method to get the `BlockItem` instance. For this example, we'll use a custom item group created in the [Custom Item Groups](../items/custom-item-groups) page. -@[code transcludeWith=:::3](@/reference/latest/src/main/java/com/example/docs/block/ModBlocks.java) +@[code transcludeWith=:::6](@/reference/latest/src/main/java/com/example/docs/block/ModBlocks.java) + +You should place this within the `initialize()` function of your class. --- @@ -93,18 +98,17 @@ All block textures can be found in the `assets//textures/block` fol Texture -To make the texture show up in-game, you must create a block and item model which can be found in the respective locations for the "Condensed Dirt" block: +To make the texture show up in-game, you must create a block model which can be found in the `assets//models/block/condensed_dirt.json` file for the "Condensed Dirt" block. For this block, we're going to use the `block/cube_all` model type. -- `assets//models/block/condensed_dirt.json` -- `assets//models/item/condensed_dirt.json` +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_dirt.json) -The item model is pretty simple, it can just use the block model as a parent - since most block models have support for being rendered in a GUI: +For the block to show in your inventory, you will need to create an [Item Model Description](../items/first-item#creating-the-item-model-description) that points to your block model. For this example, the item model description for the "Condensed Dirt" block can be found at `assets//items/condensed_dirt.json`. -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_dirt.json) -The block model however, in our case, must parent the `block/cube_all` model: - -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) +::: tip +You only need to create an item model description if you've registered a `BlockItem` along with your block! +::: When you load into the game, you may notice that the texture is still missing. This is because you need to add a blockstate definition. @@ -116,9 +120,11 @@ For the example block, which doesn't have a complex blockstate, only one entry i This file should be located in the `assets/mod_id/blockstates` folder, and its name should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_dirt`, the file should be named `condensed_dirt.json`. -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_dirt.json) -Blockstates are really complex, which is why they are addressed in an upcoming page: [Block States](./blockstates) +::: tip +Blockstates are incredibly complex, which is why they will be covered next in [their own separate page](./blockstates). +::: Restarting the game, or reloading via F3+T to apply changes - you should be able to see the block texture in the inventory and physically in the world: @@ -153,7 +159,7 @@ This example adds the "Condensed Dirt" block to the `shovel` tag. @[code](@/reference/latest/src/main/resources/data/minecraft/tags/mineable/shovel.json) -If you wish for a tool to be required to mine the block, you'll want to append `.requiresTool()` to your block settings, as well as add the appropriate mining tag. +If you wish for a tool to be required to mine the block, you'll want to append `.requiresTool()` to your block settings, as well as add the appropriate mining level tag. ## Mining Levels {#mining-levels} @@ -167,4 +173,4 @@ The file has the same format as the harvesting tool file - a list of items to be ## Extra Notes {#extra-notes} -If you're adding multiple blocks to your mod, you may want to consider using [Data Generation](https://fabricmc.net/wiki/tutorial:datagen_setup) to automate the process of creating block and item models, blockstate definitions, and loot tables. +If you're adding multiple blocks to your mod, you may want to consider using [Data Generation](../data-generation/setup) to automate the process of creating block and item models, blockstate definitions, and loot tables. diff --git a/develop/data-generation/advancements.md b/develop/data-generation/advancements.md index 9f8a1fd98..1afb9fe7e 100644 --- a/develop/data-generation/advancements.md +++ b/develop/data-generation/advancements.md @@ -24,7 +24,7 @@ First, we need to make our provider. Create a class that `extends FabricAdvancem To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. -@[code lang=java transclude={24-24}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) +@[code lang=java transclude={25-25}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) ## Advancement Structure {#advancement-structure} @@ -42,8 +42,12 @@ Here's a simple advancement for getting a dirt block: @[code lang=java transcludeWith=:::datagen-advancements:simple-advancement](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) +::: warning +When building your advancement entries, remember that the function accepts the `Identifier` of the advancement in `String` format! +::: + ::: details JSON Output -@[code lang=json](@/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/fabric-docs-reference/get_dirt.json) +@[code lang=json](@/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/get_dirt.json) ::: ## One More Example {#one-more-example} @@ -52,20 +56,6 @@ Just to get the hang of it, let's add one more advancement. We'll practice addin @[code lang=java transcludeWith=:::datagen-advancements:second-advancement](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) -Don't forget to generate them! Use the terminal command below or the run configuration in IntelliJ. - -::: code-group - -```sh [Windows] -gradlew runDatagen -``` - -```sh [Linux] -./gradlew runDatagen -``` - -::: - ## Custom Criteria {#custom-criteria} ::: warning @@ -136,7 +126,7 @@ Run the datagen task again, and you've got your new advancement to play with! This is all well and good, but what if we want to only grant an advancement once we've done something 5 times? And why not another one at 10 times? For this, we need to give our condition a parameter. You can stay with `UseToolCriterion`, or you can follow along with a new `ParameterizedUseToolCriterion`. In practice, you should only have the parameterized one, but we'll keep both for this tutorial. -Let's work bottom-up. We'll need to check if the requirements are met, so let's edit our `Condtions#requirementsMet` method: +Let's work bottom-up. We'll need to check if the requirements are met, so let's edit our `Conditions#requirementsMet` method: @[code lang=java transcludeWith=:::datagen-advancements:new-requirements-met](@/reference/latest/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) diff --git a/develop/data-generation/setup.md b/develop/data-generation/setup.md index 1bf278687..651859054 100644 --- a/develop/data-generation/setup.md +++ b/develop/data-generation/setup.md @@ -55,7 +55,7 @@ Finally, we need to tell Fabric about the entrypoint in our `fabric.mod.json`: // ... ], "fabric-datagen": [ // [!code ++] - "com.exmaple.docs.datagen.FabricDocsReferenceDataGenerator" // [!code ++] + "com.example.docs.datagen.FabricDocsReferenceDataGenerator" // [!code ++] ] // [!code ++] } } diff --git a/develop/data-generation/tags.md b/develop/data-generation/tags.md index db8b0ede1..2e28a781b 100644 --- a/develop/data-generation/tags.md +++ b/develop/data-generation/tags.md @@ -17,7 +17,7 @@ Make sure you've completed the [datagen setup](./setup) process first. ## Setup {#setup} -First, create your own class that `extends FabricTagProvider`, where `T` is the type of thing you'd like to provide a tag for. This is your **provider**. Here we'll show how to create `Item` tags, but the same principal applies for other things. Let your IDE fill in the required code, then replace the `registryKey` constructor parameter with the `RegistryKey` for your type: +First, create your own class that `extends FabricTagProvider`, where `T` is the type of thing you'd like to provide a tag for. This is your **provider**. Here we'll show how to create `Item` tags, but the same principle applies for other things. Let your IDE fill in the required code, then replace the `registryKey` constructor parameter with the `RegistryKey` for your type: @[code lang=java transcludeWith=:::datagen-tags:provider](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) @@ -27,7 +27,7 @@ You will need a different provider for each type of tag (eg. one `FabricTagProvi To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. -@[code lang=java transclude={28-28}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) +@[code lang=java transclude={29-29}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) ## Creating a Tag {#creating-a-tag} diff --git a/develop/data-generation/translations.md b/develop/data-generation/translations.md index 62f985ad5..ebb408732 100644 --- a/develop/data-generation/translations.md +++ b/develop/data-generation/translations.md @@ -25,12 +25,12 @@ First, we'll make our **provider**. Remember, providers are what actually genera @[code lang=java transcludeWith=:::datagen-translations:provider](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) ::: info NOTE -You will need a different provider for each langauge you want to generate (eg. one `ExampleEnglishLangProvider` and one `ExamplePirateLangProvider`). +You will need a different provider for each language you want to generate (eg. one `ExampleEnglishLangProvider` and one `ExamplePirateLangProvider`). ::: To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. -@[code lang=java transclude={26-26}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) +@[code lang=java transclude={27-27}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) ## Creating Translations {#creating-translations} diff --git a/develop/entities/damage-types.md b/develop/entities/damage-types.md index 466e298a6..90dd926de 100644 --- a/develop/entities/damage-types.md +++ b/develop/entities/damage-types.md @@ -55,11 +55,11 @@ You can override `onSteppedOn` to inflict this damage. We start by creating a `DamageSource` of our custom damage type. -@[code lang=java transclude={21-24}](@/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java) +@[code lang=java transclude={22-26}](@/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java) Then, we call `entity.damage()` with our `DamageSource` and an amount. -@[code lang=java transclude={25-25}](@/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java) +@[code lang=java transclude={27-27}](@/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java) The complete block implementation: @@ -72,7 +72,13 @@ Now whenever a living entity steps on our custom block, it'll take 5 damage (2.5 You can define a death message for the damage type in the format of `death.attack.` in our mod's `en_us.json` file. -@[code lang=json transclude={4-4}](@/reference/latest/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) +```json +{ + // ... + "death.attack.tater": "%1$s died from Tater damage!", + // ... +} +``` Upon death from our damage type, you'll see the following death message: diff --git a/develop/getting-started/creating-a-project.md b/develop/getting-started/creating-a-project.md index 8a15ce227..31d52b886 100644 --- a/develop/getting-started/creating-a-project.md +++ b/develop/getting-started/creating-a-project.md @@ -14,7 +14,7 @@ Fabric provides an easy way to create a new mod project using the Fabric Templat You can use the [Fabric Template Mod Generator](https://fabricmc.net/develop/template/) to generate a new project for your mod - you should fill in the required fields, such as the mod name, package name, and the Minecraft version that you want to develop for. -The package name should be lowercase, separated by dots, and unique to avoid conflicts with other programmers' packages. It is typically formatted as a reversed internet domain, such as `com.example.modid`. +The package name should be lowercase, separated by dots, and unique to avoid conflicts with other programmers' packages. It is typically formatted as a reversed internet domain, such as `com.example.mod-id`. ![Preview of the generator](/assets/develop/getting-started/template-generator.png) diff --git a/develop/getting-started/project-structure.md b/develop/getting-started/project-structure.md index cdedc0f83..8de4562cc 100644 --- a/develop/getting-started/project-structure.md +++ b/develop/getting-started/project-structure.md @@ -49,7 +49,7 @@ The `src/main/resources` folder is used to store the resources that your mod use It's also the location of `fabric.mod.json` and any mixin configuration files that your mod uses. -Assets are stored in a structure that mirrors the structure of resource packs - for example, a texture for a block would be stored in `assets/modid/textures/block/block.png`. +Assets are stored in a structure that mirrors the structure of resource packs - for example, a texture for a block would be stored in `assets/mod-id/textures/block/block.png`. ## `src/client/resources` {#src-client-resources} diff --git a/develop/getting-started/setting-up-a-development-environment.md b/develop/getting-started/setting-up-a-development-environment.md index 60f766410..6e3def24a 100644 --- a/develop/getting-started/setting-up-a-development-environment.md +++ b/develop/getting-started/setting-up-a-development-environment.md @@ -24,7 +24,7 @@ To start developing mods with Fabric, you will need to set up a development envi ## Installing JDK 21 {#installing-jdk-21} -To develop mods for Minecraft 1.21, you will need JDK 21. +To develop mods for Minecraft 1.21.4, you will need JDK 21. If you need help installing Java, you can refer to the various Java installation guides in the [player guides section](../../players/index). diff --git a/develop/items/custom-armor.md b/develop/items/custom-armor.md index 0b0c28885..cef1b7d20 100644 --- a/develop/items/custom-armor.md +++ b/develop/items/custom-armor.md @@ -11,81 +11,46 @@ Armor provides the player with increased defense against attacks from mobs and o ## Creating an Armor Materials Class {#creating-an-armor-materials-class} -Just like items and blocks, armor materials need to be registered. We will create a `ModArmorMaterials` class to store our custom armor materials for the sake of organization. +Technically, you don't need a dedicated class for your armor material, but it's good practice anyways with the number of static fields you will need. -You will need to add a static `initialize()` method to this class, and call it from your [mod's initializer](./getting-started/project-structure#entrypoints) so that the materials are registered. +For this example, we'll create an `GuiditeArmorMaterial` class to store our static fields. -```java -// Within the ModArmorMaterials class -public static void initialize() {}; -``` +### Base Durability {#base-durability} -::: warning -Make sure to call this method **before** you register your items, as the materials will need to be registered before the items can be created. -::: - -```java -@Override -public void onInitialize() { - ModArmorMaterials.initialize(); -} -``` - ---- - -Within this `ModArmorMaterials` class, you will need to create a static method which will register the armor material. This method should return a registry entry of the material, as this entry will be used by the ArmorItem constructor to create the armor items. - -@[code transcludeWith=:::1](@/reference/latest/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) - -## Armor Material Properties {#armor-material-properties} - -::: tip -If you're struggling to gauge a good value for any of these properties, consider looking at the vanilla armor materials in the `ArmorMaterials` class. -::: - -When creating an armor material, you will need to define the following properties: - -### Defense Points {#defense-points} - -::: warning -Ensure you assign a value to each type of armor piece you plan to create and register as an item. If you make an item for an armor piece without a set defense point value, the game will crash. -::: - -The `defensePoints` map is used to define the number of defense points that each armor piece will provide. The higher the number, the more protection the armor piece will provide. The map should contain an entry for each armor piece type. - -### Enchantability {#enchantability} +This constant will be used in the `Item.Settings#maxDamage(int damageValue)` method when creating our armor items, it is also required as a parameter in the `ArmorMaterial` constructor when we create our `ArmorMaterial` object later. -The `enchantability` property defines how easily the armor can be enchanted. The higher the number, the more enchantments the armor can receive. +@[code transcludeWith=:::base_durability](@/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java) -### Equip Sound {#equip-sound} +If you're struggling to determine a balanced base durability, you can refer to the vanilla armor material instances found in the `ArmorMaterials` interface. -The `equipSound` property is the sound that will play when the armor is equipped. This sound should be a registry entry of a `SoundEvent`. Consider taking a look at the [Custom Sound Events](../sounds/custom) page if you are considering creating custom sounds rather than relying on vanilla sounds within the `SoundEvents` class. +### Equipment Asset Registry Key {#equipment-asset-registry-key} -### Repair Ingredient(s) {#repair-ingredient} +Whilst we dont have to register our `ArmorMaterial` to any registries, the game will use this to find the relevant textures for our armor, it's generally good practice to store any registry keys as constants. -The `repairIngredientSupplier` property is a supplier of an `Ingredient` that is used to repair the armor. This ingredient can pretty much be anything, it's recommended to set it to be the same as the material's crafting ingredient used to actually craft the armor items. +@[code transcludeWith=:::material_key](@/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java) -### Toughness {#toughness} +We will pass this to the `ArmorMaterial` constructor later. -The `toughness` property defines how much damage the armor will absorb. The higher the number, the more damage the armor will absorb. +### `ArmorMaterial` Instance {#armormaterial-instance} -### Knockback Resistance {#knockback-resistance} +To create our material, we need to create a new instance of the `ArmorMaterial` record, the base durability and material registry key constants will be used here. -The `knockbackResistance` property defines how much knockback the player will reflect when hit. The higher the number, the less knockback the player will receive. +@[code transcludeWith=:::guidite_armor_material](@/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java) -### Dyeable {#dyeable} +The `ArmorMaterial` constructor accepts the following parameters, in this specific order: -The `dyeable` property is a boolean that defines whether the armor can be dyed. If set to `true`, the armor can be dyed using dyes in a crafting table. +| Parameter | Description | +| --------- | ----------- | +| `durability` | The base durability of all armor pieces, this is used when calculating the total durability of each individual armor piece that use this material. This should be the base durability constant you created earlier. | +| `defense` | A map of `EquipmentType` (an enum representing each armor slot) to an integer value, which indicates the defense value of the material when used in the corresponding armor slot. | +| `enchantmentValue` | The "enchantability" of armor items which use this material. | +| `equipSound` | A registry entry of a sound event that is played when you equip a piece of armor which uses this material. For more information on sounds, check out the [Custom Sounds](../sounds/custom) page. | +| `toughness` | A float value which represents the "toughness" attribute of the armor material - essentially how well the armor will absorb damage. | +| `knockbackResistance` | A float value which represents the amount of knockback resistance the armor material grants the wearer. | +| `repairIngredient` | An item tag that represents all items which can be used to repair the armor items of this material in an anvil. | +| `assetId` | An `EquipmentAsset` registry key, this should be the equipment asset registry key constant you created earlier. | -If you do choose to make your armor dyeable, your armor layer and item textures must be **designed to be dyed**, as the dye will overlay the texture, not replace it. Take a look at the vanilla leather armor for an example, the textures are grayscale and the dye is applied as an overlay, causing the armor to change color. - -## Registering the Armor Material {#registering-the-armor-material} - -Now that you've created a utility method which can be used to register armor materials, you can register your custom armor materials as a static field in the `ModArmorMaterials` class. - -For this example, we'll be creating Guidite armor, with the following properties: - -@[code transcludeWith=:::2](@/reference/latest/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) +If you're struggling to determine values for any of the parameters, you can consult the vanilla `ArmorMaterial` instances which can be found in the `ArmorMaterials` interface. ## Creating the Armor Items {#creating-the-armor-items} @@ -93,19 +58,9 @@ Now that you've registered the material, you can create the armor items in your Obviously, an armor set doesn't need every type to be satisfied, you can have a set with just boots, or leggings etc. - the vanilla turtle shell helmet is a good example of an armor set with missing slots. -### Durability {#durability} - -Unlike `ToolMaterial`, `ArmorMaterial` does not store any information about the durability of items. -For this reason the durability needs to be manually added to the armor items' `Item.Settings` when registering them. - -This is achieved using the `maxDamage` method in the `Item.Settings` class. -The different armor slots have different base durabilities which are commonly multiplied by a shared armor material multiplier but hard-coded values can also be used. - -For the Guidite armor we'll be using a shared armor multiplier stored alongside the armor material: - -@[code transcludeWith=:::3](@/reference/latest/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) +Unlike `ToolMaterial`, `ArmorMaterial` does not store any information about the durability of items. For this reason the base durability needs to be manually added to the armor items' `Item.Settings` when registering them. -We can then create the armor items using the durability constant: +This is achieved by passing the `BASE_DURABILITY` constant we created previously into the `maxDamage` method in the `Item.Settings` class. @[code transcludeWith=:::6](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) @@ -113,12 +68,9 @@ You will also need to **add the items to an item group** if you want them to be As with all items, you should create translation keys for them as well. -## Texturing and Modelling {#texturing-and-modelling} +## Textures and Models {#textures-and-models} -You will need to create two sets of textures: - -- Textures and models for the items themselves. -- The actual armor texture that is visible when an entity wears the armor. +You will need to create a set of textures for the items, and a set of textures for the actual armour when it's worn by a "humanoid" entity (players, zombies, skeletons, etc). ### Item Textures and Model {#item-textures-and-model} @@ -132,29 +84,41 @@ For example purposes, you may use the following textures and model JSON as a ref You will need model JSON files for all the items, not just the helmet, it's the same principle as other item models. ::: -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_helmet.json) As you can see, in-game the armor items should have suitable models: ![Armor item models](/assets/develop/items/armor_1.png) -## Armor Textures and Model {#armor-textures-and-model} +### Armor Textures {#armor-textures} -When an entity wears your armor, currently the missing texture will appear: +When an entity wears your armor, nothing will be shown. This is because you're missing textures and the equipment model definitions. ![Broken armor model on player](/assets/develop/items/armor_2.png) There are two layers for the armor texture, both must be present. -Since the armor material name in our case is `guidite`, the locations of the textures will be: +Previously, we created a `RegistryKey` constant called `GUIDITE_ARMOR_MATERIAL_KEY` which we passed into our `ArmorMaterial` constructor. It's recommended to name the texture similarly, so in our case, `guidite.png` + +- `assets//textures/entity/equipment/humanoid/guidite.png` - Contains upper body and boot textures. +- `assets//textures/entity/equipment/humanoid_leggings/guidite.png` - Contains legging textures. + +Guidite Armor Model Textures + +::: tip +If you're updating to 1.21.4 from an older version of the game, the `humanoid` folder is where your `layer0.png` armor texture goes, and the `humanoid_leggings` folder is where your `layer1.png` armor texture goes. +::: -- `assets//textures/models/armor/guidite_layer_1.png` -- `assets//textures/models/armor/guidite_layer_2.png` +Next, you'll need to create an associated equipment model definition. These go in the `/assets//equipment/` folder. -Armor Model Textures +The `RegistryKey` constant we created earlier will determine the name of the JSON file. In this case, it'll be `guidite.json`. -The first layer contains textures for the helmet and chestplate, whilst the second layer contains textures for leggings and boots. +Since we only plan to add "humanoid" (helmet, chestplate, leggings, boots etc.) armor pieces, our equipment model definition will look like this: -When these textures are present, you should be able to see your armor on entities that wear it: +@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/equipment/guidite.json) + +With the textures and equipment model definition present, you should be able to see your armor on entities that wear it: ![Working armor model on player](/assets/develop/items/armor_3.png) + + \ No newline at end of file diff --git a/develop/items/custom-enchantment-effects.md b/develop/items/custom-enchantment-effects.md index 733369706..93d7d5f23 100644 --- a/develop/items/custom-enchantment-effects.md +++ b/develop/items/custom-enchantment-effects.md @@ -45,7 +45,7 @@ Before proceeding, you should ensure your project is configured for data generat Lastly, we must tell our mod to add our `EnchantmentGenerator` to the list of data generation tasks. To do so, simply add the `EnchantmentGenerator` to this inside of the `onInitializeDataGenerator` method. -@[code transclude={22-22}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) +@[code transclude={24-24}](@/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) Now, when you run your mod's data generation task, enchantment JSONs will be generated inside the `generated` folder. An example can be seen below: diff --git a/develop/items/custom-item-interactions.md b/develop/items/custom-item-interactions.md index d5d5ad2c0..bdaac8864 100644 --- a/develop/items/custom-item-interactions.md +++ b/develop/items/custom-item-interactions.md @@ -56,7 +56,7 @@ A great example of these events being used can be found in the [Playing SoundEve ## The `use()` Event {#use-event} -Let's say you want to make an item that summons a lightning bolt infront of the player - you would need to create a custom class. +Let's say you want to make an item that summons a lightning bolt in front of the player - you would need to create a custom class. @[code transcludeWith=:::1](@/reference/latest/src/main/java/com/example/docs/item/custom/LightningStick.java) @@ -66,6 +66,6 @@ The `use` event is probably the most useful out of them all - you can use this e As usual, you should register your item, add a model and texture. -As you can see, the lightning bolt should spawn 10 blocks infront of you - the player. +As you can see, the lightning bolt should spawn 10 blocks in front of you - the player. diff --git a/develop/items/custom-tools.md b/develop/items/custom-tools.md index 22a2b06c6..31af2e9ca 100644 --- a/develop/items/custom-tools.md +++ b/develop/items/custom-tools.md @@ -11,75 +11,22 @@ Tools are essential for survival and progression, allowing players to gather res ## Creating a Tool Material {#creating-a-tool-material} -::: info -If you're creating multiple tool materials, consider using an `Enum` to store them. Vanilla does this in the `ToolMaterials` class, which stores all the tool materials that are used in the game. +You can create a tool material by instantiating a new `ToolMaterial` object and storing it in a field that can be used later to create the tool items that use the material. -This class can also be used to determine your tool material's properties in relation to vanilla tool materials. -::: +@[code transcludeWith=:::guidite_tool_material](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) -You can create a tool material by creating a new class that inherits it - in this example, I'll be creating "Guidite" tools: +The `ToolMaterial` constructor accepts the following parameters, in this specific order: -@[code transcludeWith=:::1](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) +| Parameter | Description | +| --------- | ----------- | +| `incorrectBlocksForDrops` | If a block is in the incorrectBlocksForDrops tag, it means that when you use a tool made from this `ToolMaterial` on that block, the block will not drop any items. | +| `durability` | The durability of all tools that are of this `ToolMaterial`. | +| `speed` | The mining speed of the tools that are of this `ToolMaterial`. | +| `attackDamageBonus` | The additional attack damage of the tools that are of this `ToolMaterial` will have. | +| `enchantmentValue` | The "Enchantability" of tools which are of this `ToolMaterial`. | +| `repairItems` | Any items within this tag can be used to repair tools of this `ToolMaterial` in an anvil. | -Once you have created your tool material and tweaked it to your likings, you can create an instance of it to be used in the tool item constructors. - -@[code transcludeWith=:::8](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) - -The tool material tells the game the following information: - -### Durability - `getDurability()` {#durability} - -How many times the tool can be used before breaking: - -@[code transcludeWith=:::2](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) - -### Mining Speed - `getMiningSpeedMultiplier()` {#mining-speed} - -If the tool is used to break blocks, how fast should it break the blocks? - -@[code transcludeWith=:::3](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) - -For reference purposes, the diamond tool material has a mining speed of `8.0F` whilst the stone tool material has a mining speed of `4.0F`. - -### Attack Damage - `getAttackDamage()` {#attack-damage} - -How many points of damage should the tool do when used as a weapon against another entity? - -@[code transcludeWith=:::4](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) - -### Inverse Tag - `getMiningLevel()` {#inverse-tag} - -The inverse tag shows what the tool _**cannot**_ mine. For instance, using the `BlockTags.INCORRECT_FOR_WOODEN_TOOL` tag stops the tool from mining certain blocks: - -```json -{ - "values": [ - "#minecraft:needs_diamond_tool", - "#minecraft:needs_iron_tool", - "#minecraft:needs_stone_tool" - ] -} -``` - -This means the tool can't mine blocks that need a diamond, iron, or stone tool. - -Let's use the iron tool tag. This stops Guidite tools from mining blocks that require a stronger tool than iron. - -@[code transcludeWith=:::5](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) - -You can use `TagKey.of(...)` to create a custom tag key if you want to use a custom tag. - -### Enchantability - `getEnchantability()` {#enchantability} - -How easy is it to get better and higher level enchantments with this item? For reference, Gold has an enchantability of 22 whilst Netherite has an enchantability of 15. - -@[code transcludeWith=:::6](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) - -### Repair Ingredient(s) - `getRepairIngredient()` {#repair-ingredient} - -What item or items are used to repair the tool? - -@[code transcludeWith=:::7](@/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) +If you're struggling to determine balanced values for any of the numerical parameters, you should consider looking at the vanilla tool material constants, such as `ToolMaterial.STONE` or `ToolMaterial.DIAMOND`. ## Creating Tool Items {#creating-tool-items} @@ -87,15 +34,17 @@ Using the same utility function as in the [Creating Your First Item](./first-ite @[code transcludeWith=:::7](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) +The two float values (`1f, 1f`) refer to the attack damage of the tool and the attack speed of the tool respectively. + Remember to add them to an item group if you want to access them from the creative inventory! @[code transcludeWith=:::8](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) -You will also have to add a texture, item translation and item model. However, for the item model, you'll want to use the `item/handheld` model as your parent. +You will also have to add a texture, item translation and item model. However, for the item model, you'll want to use the `item/handheld` model as your parent instead of the usual `item/generated`. For this example, I will be using the following model and texture for the "Guidite Sword" item: -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_sword.json) Texture diff --git a/develop/items/first-item.md b/develop/items/first-item.md index 84678c998..270c6a1d6 100644 --- a/develop/items/first-item.md +++ b/develop/items/first-item.md @@ -4,6 +4,7 @@ description: Learn how to register a simple item and how to texture, model and n authors: - IMB11 - dicedpixels + - RaphProductions --- # Creating Your First Item {#creating-your-first-item} @@ -98,7 +99,7 @@ You're going to create a simple `item/generated` model, which takes in an input Create the model JSON in the `assets//models/item` folder, with the same name as the item; `suspicious_substance.json` -@[code](@/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/suspicious_substance.json) ### Breaking Down the Model JSON {#breaking-down-the-model-json} @@ -107,7 +108,21 @@ Create the model JSON in the `assets//models/item` folder, with the Most items will use the `item/generated` model as their parent, as it's a simple model that just displays the texture. -There are alternatives, such as `item/handheld` which is used for items that are held in the player's hand, such as tools. +There are alternatives, such as `item/handheld` which is used for items that are "held" in the player's hand, such as tools. + +## Creating the Item Model Description {#creating-the-item-model-description} + +Minecraft doesn't automatically know where your item's model files can be found, we need to provide an item model description. + +Create the item description JSON in the `assets//items`, with the same filename as the identifier of the item; `suspicious_substance.json`. + +@[code](@/reference/latest/src/main/generated/assets/fabric-docs-reference/items/suspicious_substance.json) + +### Breaking Down the Item Model Description JSON {#breaking-down-the-item-model-description-json} + +- `model`: This is the property that contains the reference to our model. + - `type`: This is the type of our model. For most items, this should be `minecraft:model` + - `model`: This is the model's identifier. It should have this form: `:item/` Your item should now look like this in-game: @@ -121,7 +136,7 @@ For example, if you want to make your item compostable, you can use the `Compost @[code transcludeWith=:::_10](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) -Alternatively, if you want to make your item a fuel, you can use the `FuelRegistry` class: +Alternatively, if you want to make your item a fuel, you can use the `FuelRegistryEvents.BUILD` event: @[code transcludeWith=:::_11](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) diff --git a/develop/items/food.md b/develop/items/food.md index c0c3150c9..8bfa6e88d 100644 --- a/develop/items/food.md +++ b/develop/items/food.md @@ -25,18 +25,18 @@ new Item.Settings().food(new FoodComponent.Builder().build()) Right now, this just makes the item edible and nothing more. -The `FoodComponent.Builder` class has many methods that allow you to modify what happens when a player eats your item: +The `FoodComponent.Builder` class has some methods that allow you to modify what happens when a player eats your item: -| Method | Description | -| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `nutrition` | Sets the amount of hunger points your item will replenish. | -| `saturationModifier` | Sets the amount of saturation points your item will add. | -| `alwaysEdible` | Allows your item to be eaten regardless of hunger level. | -| `snack` | Declares your item as a snack. | -| `statusEffect` | Adds a status effect when you eat your item. Usually a status effect instance and chance is passed to this method, where chance is a decimal percentage (`1f = 100%`) | +| Method | Description | +|----------------------|------------------------------------------------------------| +| `nutrition` | Sets the amount of hunger points your item will replenish. | +| `saturationModifier` | Sets the amount of saturation points your item will add. | +| `alwaysEdible` | Allows your item to be eaten regardless of hunger level. | When you've modified the builder to your liking, you can call the `build()` method to get the `FoodComponent`. +If you want to add status effects to the player when they eat your food, you will need to use the `ConsumableComponent` alongside the `FoodComponent` class as seen in the following example: + @[code transcludeWith=:::5](@/reference/latest/src/main/java/com/example/docs/item/ModItems.java) Similar to the example in the [Creating Your First Item](./first-item) page, I'll be using the above component: @@ -46,7 +46,6 @@ Similar to the example in the [Creating Your First Item](./first-item) page, I'l This makes the item: - Always edible, it can be eaten regardless of hunger level. -- A "snack". - Always give Poison II for 6 seconds when eaten. - + diff --git a/develop/items/potions.md b/develop/items/potions.md index 0e9f98b71..caa2ad3fc 100644 --- a/develop/items/potions.md +++ b/develop/items/potions.md @@ -39,7 +39,7 @@ To create your own potion effect, please see the [Effects](../entities/effects) In our initializer, we will use the `FabricBrewingRecipeRegistryBuilder.BUILD` event to register our potion using the `BrewingRecipeRegistry.registerPotionRecipe` method. -@[code lang=java transclude={29-42}](@/reference/latest/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) +@[code lang=java transclude={29-40}](@/reference/latest/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) `registerPotionRecipe` takes 3 parameters: diff --git a/develop/rendering/basic-concepts.md b/develop/rendering/basic-concepts.md index cc1921c8a..4d70c843d 100644 --- a/develop/rendering/basic-concepts.md +++ b/develop/rendering/basic-concepts.md @@ -135,7 +135,7 @@ The `MatrixStack` class has the following methods: You can also multiply the top matrix on the stack using quaternions, which we will cover in the next section. -Taking from our example above, we can make our diamond scale up and down by using the `MatrixStack` and the `tickDelta` - which is the time that has passed since the last frame. +Taking from our example above, we can make our diamond scale up and down by using the `MatrixStack` and the `tickDelta` - which is the "progress" between the last game tick and the next game tick. We'll clarify this later in the [Rendering in the Hud](./hud#tick-delta) page. ::: warning You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. diff --git a/develop/rendering/draw-context.md b/develop/rendering/draw-context.md index 7ba1f9aab..44c4fc8db 100644 --- a/develop/rendering/draw-context.md +++ b/develop/rendering/draw-context.md @@ -65,6 +65,8 @@ There is no one "correct" way to draw textures onto a screen, as the `drawTextur Generally, it's recommended that you use the overload that specifies the `textureWidth` and `textureHeight` parameters. This is because the `DrawContext` class will assume these values if you don't provide them, which can sometimes be wrong. +You will also need to specify the render layer which your texture is drawn onto. For basic textures, this will usually always be `RenderLayer::getGuiTextured`. + @[code lang=java transcludeWith=:::5](@/reference/latest/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) ![Drawing whole texture example](/assets/develop/rendering/draw-context-whole-texture.png) diff --git a/develop/rendering/hud.md b/develop/rendering/hud.md index ec1dc4e35..acc8c9db9 100644 --- a/develop/rendering/hud.md +++ b/develop/rendering/hud.md @@ -7,24 +7,47 @@ authors: # Rendering in the Hud {#rendering-in-the-hud} -We already briefly touched on rendering things to the hud in the [Basic Rendering Concepts](./basic-concepts) page and [Using The Drawing Context](./draw-context), so on this page we'll stick to the `HudRenderCallback` event and the `deltaTick` parameter. +We already briefly touched on rendering things to the hud in the [Basic Rendering Concepts](./basic-concepts) page and [Using The Drawing Context](./draw-context), so on this page we'll stick to the `HudRenderCallback` event and the `tickDelta` parameter. ## HudRenderCallback {#hudrendercallback} The `HudRenderCallback` event - provided by Fabric API - is called every frame, and is used to render things to the HUD. -To register to this event, you can simply call `HudRenderCallback.EVENT.register` and pass in a lambda that takes a `DrawContext` and a `float` (deltaTick) as parameters. +To register to this event, you can simply call `HudRenderCallback.EVENT.register` and pass in a lambda that takes a `DrawContext` and a `RenderTickCounter` instance as parameters. The draw context can be used to access the various rendering utilities provided by the game, and access the raw matrix stack. You should check out the [Draw Context](./draw-context) page to learn more about the draw context. -### DeltaTick {#deltatick} +### Render Tick Counter {#render-tick-counter} -The `deltaTick` refers to the time since the last frame, in seconds. This can be used to make animations and other time-based effects. +The `RenderTickCounter` class allows you to retrieve the current `tickDelta` value. -For example, let's say you want to lerp a color over time. You can use the `deltaTickManager` to get the deltaTick, and store it over time to lerp the color: +`tickDelta` is the "progress" between the last game tick and the next game tick. + +For example, if we assume a 200 FPS scenario, the game runs a new tick roughly every 10 frames. Each frame, `tickDelta` represents how far we are between the last tick and the next. Over 10 frames, you might see: + +| Frame | tickDelta | +|-------|----------------------------------------------| +| 1 | `1.0` (new tick) | +| 2 | `0.11 (1÷9)` - The next tick is in 9 frames. | +| 3 | `0.22 (2÷9)` | +| 4 | `0.33 (3÷9)` | +| 5 | `0.44 (4÷9)` | +| 6 | `0.55 (5÷9)` | +| 7 | `0.66 (6÷9)` | +| 8 | `0.77 (7÷9)` | +| 9 | `0.88 (8÷9)` | +| 10 | `1.0 (9÷9)` (new tick) | + +Practically, you should only use `tickDelta` when your animations depend on Minecraft's ticks. For time-based animations, use `Util.getMeasuringTimeMs()`, which measures real-world time. + +You can retrieve `tickDelta` using the `renderTickCounter.getTickDelta(false);` function, where the boolean parameter is `ignoreFreeze`, which essentially just allows you to ignore whenever players use the `/tick freeze` command. + +In this example, we'll use `Util.getMeasuringTimeMs()` to linearly interpolate the color of a square that is being rendered to the HUD. @[code lang=java transcludeWith=:::1](@/reference/latest/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java) ![Lerping a color over time](/assets/develop/rendering/hud-rendering-deltatick.webp) + +Why don't you try use `tickDelta` and see what happens to the animation when you run the `/tick freeze` command? You should see the animation freeze in place as `tickDelta` becomes constant (assuming you have passed `false` as the parameter to `RenderTickCounter#getTickDelta`) diff --git a/develop/rendering/particles/creating-particles.md b/develop/rendering/particles/creating-particles.md index 3b08a98aa..0388cb2f5 100644 --- a/develop/rendering/particles/creating-particles.md +++ b/develop/rendering/particles/creating-particles.md @@ -13,7 +13,7 @@ Particles are a powerful tool. They can add ambience to a beautiful scene, or ad We'll be adding a new sparkle particle which will mimic the movement of an end rod particle. -We first need to register a `ParticleType` in your [mod's initializer](./getting-started/project-structure#entrypoints) class using your mod id. +We first need to register a `ParticleType` in your [mod's initializer](../../getting-started/project-structure#entrypoints) class using your mod id. @[code lang=java transcludeWith=#particle_register_main](@/reference/latest/src/main/java/com/example/docs/FabricDocsReference.java) diff --git a/develop/sounds/dynamic-sounds.md b/develop/sounds/dynamic-sounds.md index 330f462e0..652b292fa 100644 --- a/develop/sounds/dynamic-sounds.md +++ b/develop/sounds/dynamic-sounds.md @@ -164,7 +164,7 @@ In specific situations, a logical server side entity's properties can differ fro If you notice that your values don't line up, make sure that your values are synchronized either with entity's `TrackedData`, `BlockEntity` S2C packets or complete custom S2C network packets. -After you have finished creating your custom `SoundInstance` It's ready to be used anywhere as long as it's been executed on the client side using the sound manager. +After you have finished creating your custom `SoundInstance`, it's ready to be used anywhere as long as it's been executed on the client side using the sound manager. In the same way, you can also stop the custom `SoundInstance` manually, if necessary. @[code lang=java transcludeWith=:::2](@/reference/latest/src/client/java/com/example/docs/FabricDocsDynamicSound.java) @@ -173,7 +173,7 @@ The sound loop will be played now only for the client, which ran that SoundInsta This concludes the explanation of creating and using a simple custom `SoundInstance`. -## Advanced SoundInstances {#advanced-soundinstances} +## Advanced Sound Instances {#advanced-sound-instances} ::: warning The following content covers an advanced topic. @@ -223,9 +223,9 @@ If you choose to create a new, more modular, custom `AbstractDynamicSoundInstanc you may want to reference not only a single type of `Entity` but different ones, or even a `BlockEntity` too. In that case, making use of abstraction is the key. -Instead of referencing e.g. a custom `BlockEntity` directly, only keeping track of an Interface, which provides the data, solves that problem. +Instead of referencing e.g. a custom `BlockEntity` directly, only keeping track of an interface, which provides the data, solves that problem. -Going forward we will make use of a custom Interface called `DynamicSoundSource`. It is implemented in all classes which want to make use of that dynamic sound functionality, +Going forward we will make use of a custom interface called `DynamicSoundSource`. It is implemented in all classes which want to make use of that dynamic sound functionality, like your custom `BlockEntity`, Entities or even, using Mixins, on already existing classes, like `ZombieEntity`. It basically represents only the necessary data of the sound source. @[code lang=java transcludeWith=:::1](@/reference/latest/src/main/java/com/example/docs/sound/DynamicSoundSource.java) @@ -235,8 +235,8 @@ After creating this interface, make sure to implement it in the necessary classe ::: info This is a utility, which may be used on both the client and the logical server side. -So this Interface should be stored in the common packages instead of the client only packages, if you make use of the -"split sources" option +So this interface should be stored in the common packages instead of the client only packages, if you make use of the +"split sources" option. ::: ### `TransitionState` Enum {#transitionstate-enum} diff --git a/develop/text-and-translations.md b/develop/text-and-translations.md index 38f6038d5..732eaaebb 100644 --- a/develop/text-and-translations.md +++ b/develop/text-and-translations.md @@ -110,7 +110,7 @@ Furthermore, to deserialize a JSON text object into an actual `Text` class, agai You may be familiar with Minecraft's formatting standards: -You can apply these formattings using the `Formatting` enum on the `MutableText` class: +You can apply these formatting styles using the `Formatting` enum on the `MutableText` class: ```java MutableText result = Text.literal("Hello World!") diff --git a/package-lock.json b/package-lock.json index 7f6ccc497..e34ca95a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "name": "fabric-docs", "dependencies": { + "@vueuse/core": "^12.4.0", "markdown-it-mathjax3": "^4.3.2", "markdown-it-vuepress-code-snippet-enhanced": "github:IMB11/md-it-enhanced-snippets#dfb9fa2", "medium-zoom": "^1.1.0", @@ -24,7 +25,7 @@ "markdownlint-rule-search-replace": "^1.2.0", "markdownlint-rule-titlecase": "^0.1.0", "prompts": "^2.4.2", - "ts-node": "^10.9.2" + "tsx": "^4.19.2" }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.21.3" @@ -312,27 +313,30 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", + "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.26.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -342,30 +346,18 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", + "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@docsearch/css": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", @@ -681,6 +673,23 @@ "node": ">=12" } }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/openbsd-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", @@ -795,29 +804,11 @@ "node": ">=12" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -830,132 +821,182 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz", - "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", + "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz", - "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", + "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz", - "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", + "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz", - "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", + "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", + "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", + "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz", - "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", + "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz", - "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", + "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz", - "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", + "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz", - "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", + "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", "cpu": [ "arm64" ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", + "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz", - "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", + "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz", - "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", + "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", "cpu": [ "riscv64" ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz", - "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", + "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", "cpu": [ "s390x" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -974,48 +1015,52 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz", - "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", + "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz", - "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", + "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz", - "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", + "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz", - "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", + "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1075,34 +1120,11 @@ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.2.2.tgz", "integrity": "sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==" }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" }, "node_modules/@types/glob": { "version": "8.1.0", @@ -1212,12 +1234,13 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.6.tgz", - "integrity": "sha512-r+gNu6K4lrvaQLQGmf+1gc41p3FO2OUJyWmNqaIITaJU6YFiV5PtQSFZt8jfztYyARwqhoCayjprC7KMvT3nRA==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.6", + "@vue/shared": "3.5.13", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" @@ -1227,6 +1250,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -1235,37 +1259,40 @@ } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.6.tgz", - "integrity": "sha512-xRXqxDrIqK8v8sSScpistyYH0qYqxakpsIvqMD2e5sV/PXQ1mTwtXp4k42yHK06KXxKSmitop9e45Ui/3BrTEw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.6.tgz", - "integrity": "sha512-pjWJ8Kj9TDHlbF5LywjVso+BIxCY5wVOLhkEXRhuCHDxPFIeX1zaFefKs8RYoHvkSMqRWt93a0f2gNJVJixHwg==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.6", - "@vue/compiler-dom": "3.5.6", - "@vue/compiler-ssr": "3.5.6", - "@vue/shared": "3.5.6", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", - "postcss": "^8.4.47", + "postcss": "^8.4.48", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.6.tgz", - "integrity": "sha512-VpWbaZrEOCqnmqjE83xdwegtr5qO/2OPUC6veWgvNqTJ3bYysz6vY3VqMuOijubuUYPRpG3OOKIh9TD0Stxb9A==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/devtools-api": { @@ -1299,87 +1326,80 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.6.tgz", - "integrity": "sha512-shZ+KtBoHna5GyUxWfoFVBCVd7k56m6lGhk5e+J9AKjheHF6yob5eukssHRI+rzvHBiU1sWs/1ZhNbLExc5oYQ==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz", + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "license": "MIT", "dependencies": { - "@vue/shared": "3.5.6" + "@vue/shared": "3.5.13" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.6.tgz", - "integrity": "sha512-FpFULR6+c2lI+m1fIGONLDqPQO34jxV8g6A4wBOgne8eSRHP6PQL27+kWFIx5wNhhjkO7B4rgtsHAmWv7qKvbg==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz", + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.6.tgz", - "integrity": "sha512-SDPseWre45G38ENH2zXRAHL1dw/rr5qp91lS4lt/nHvMr0MhsbCbihGAWLXNB/6VfFOJe2O+RBRkXU+CJF7/sw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.6", - "@vue/runtime-core": "3.5.6", - "@vue/shared": "3.5.6", + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.6.tgz", - "integrity": "sha512-zivnxQnOnwEXVaT9CstJ64rZFXMS5ZkKxCjDQKiMSvUhXRzFLWZVbaBiNF4HGDqGNNsTgmjcCSmU6TB/0OOxLA==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz", + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" }, "peerDependencies": { - "vue": "3.5.6" + "vue": "3.5.13" } }, "node_modules/@vue/shared": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.6.tgz", - "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA==" + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "license": "MIT" }, "node_modules/@vueuse/core": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz", - "integrity": "sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.4.0.tgz", + "integrity": "sha512-XnjQYcJwCsyXyIafyA6SvyN/OBtfPnjvJmbxNxQjCcyWD198urwm5TYvIUUyAxEAN0K7HJggOgT15cOlWFyLeA==", + "license": "MIT", "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "11.1.0", - "@vueuse/shared": "11.1.0", - "vue-demi": ">=0.14.10" + "@vueuse/metadata": "12.4.0", + "@vueuse/shared": "12.4.0", + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "node_modules/@vueuse/core/node_modules/@vueuse/shared": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.4.0.tgz", + "integrity": "sha512-9yLgbHVIF12OSCojnjTIoZL1+UA10+O4E1aD6Hpfo/DKVm5o3SZIwz6CupqGy3+IcKI8d6Jnl26EQj/YucnW0Q==", + "license": "MIT", + "dependencies": { + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/@vueuse/integrations": { @@ -1447,6 +1467,30 @@ } } }, + "node_modules/@vueuse/integrations/node_modules/@vueuse/core": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz", + "integrity": "sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "11.1.0", + "@vueuse/shared": "11.1.0", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/integrations/node_modules/@vueuse/metadata": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz", + "integrity": "sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@vueuse/integrations/node_modules/vue-demi": { "version": "0.14.10", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", @@ -1473,9 +1517,10 @@ } }, "node_modules/@vueuse/metadata": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz", - "integrity": "sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.4.0.tgz", + "integrity": "sha512-AhPuHs/qtYrKHUlEoNO6zCXufu8OgbR8S/n2oMw1OQuBQJ3+HOLQ+EpvXs+feOlZMa0p8QVvDWNlmcJJY8rW2g==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } @@ -1527,18 +1572,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/algoliasearch": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", @@ -1628,12 +1661,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1794,17 +1821,12 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1843,7 +1865,8 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/d": { "version": "1.0.2", @@ -1877,15 +1900,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -2078,7 +2092,8 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" }, "node_modules/event-emitter": { "version": "0.3.5", @@ -2134,6 +2149,19 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", @@ -2350,19 +2378,14 @@ } }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/mark.js": { "version": "8.11.1", "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", @@ -2701,15 +2724,16 @@ "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -2813,14 +2837,15 @@ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "funding": [ { "type": "opencollective", @@ -2835,9 +2860,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -2889,17 +2915,28 @@ "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.2.tgz", "integrity": "sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw==" }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" }, "node_modules/rollup": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz", - "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", + "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -2909,25 +2946,41 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.3", - "@rollup/rollup-android-arm64": "4.21.3", - "@rollup/rollup-darwin-arm64": "4.21.3", - "@rollup/rollup-darwin-x64": "4.21.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.3", - "@rollup/rollup-linux-arm-musleabihf": "4.21.3", - "@rollup/rollup-linux-arm64-gnu": "4.21.3", - "@rollup/rollup-linux-arm64-musl": "4.21.3", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3", - "@rollup/rollup-linux-riscv64-gnu": "4.21.3", - "@rollup/rollup-linux-s390x-gnu": "4.21.3", - "@rollup/rollup-linux-x64-gnu": "4.21.3", - "@rollup/rollup-linux-x64-musl": "4.21.3", - "@rollup/rollup-win32-arm64-msvc": "4.21.3", - "@rollup/rollup-win32-ia32-msvc": "4.21.3", - "@rollup/rollup-win32-x64-msvc": "4.21.3", + "@rollup/rollup-android-arm-eabi": "4.30.1", + "@rollup/rollup-android-arm64": "4.30.1", + "@rollup/rollup-darwin-arm64": "4.30.1", + "@rollup/rollup-darwin-x64": "4.30.1", + "@rollup/rollup-freebsd-arm64": "4.30.1", + "@rollup/rollup-freebsd-x64": "4.30.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", + "@rollup/rollup-linux-arm-musleabihf": "4.30.1", + "@rollup/rollup-linux-arm64-gnu": "4.30.1", + "@rollup/rollup-linux-arm64-musl": "4.30.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", + "@rollup/rollup-linux-riscv64-gnu": "4.30.1", + "@rollup/rollup-linux-s390x-gnu": "4.30.1", + "@rollup/rollup-linux-x64-gnu": "4.30.1", + "@rollup/rollup-linux-x64-musl": "4.30.1", + "@rollup/rollup-win32-arm64-msvc": "4.30.1", + "@rollup/rollup-win32-ia32-msvc": "4.30.1", + "@rollup/rollup-win32-x64-msvc": "4.30.1", "fsevents": "~2.3.2" } }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", + "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/search-insights": { "version": "2.17.2", "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", @@ -3194,14 +3247,6 @@ "tslib": "^2.0.3" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -3216,64 +3261,472 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, + "node_modules/tsx": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", "dev": true, + "license": "MIT", "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" + "tsx": "dist/cli.mjs" }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" + "engines": { + "node": ">=18.0.0" }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } + "optionalDependencies": { + "fsevents": "~2.3.3" } }, - "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/type": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==" }, "node_modules/typescript": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", - "devOptional": true, + "optional": true, "peer": true, "bin": { "tsc": "bin/tsc", @@ -3378,12 +3831,6 @@ } } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/valid-data-url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", @@ -3752,16 +4199,105 @@ } } }, + "node_modules/vitepress/node_modules/@vueuse/core": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.3.0.tgz", + "integrity": "sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "11.3.0", + "@vueuse/shared": "11.3.0", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/vitepress/node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vitepress/node_modules/@vueuse/metadata": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.3.0.tgz", + "integrity": "sha512-pwDnDspTqtTo2HwfLw4Rp6yywuuBdYnPYDq+mO38ZYKGebCUQC/nVj/PXSiK9HX5otxLz8Fn7ECPbjiRz2CC3g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/vitepress/node_modules/@vueuse/shared": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.3.0.tgz", + "integrity": "sha512-P8gSSWQeucH5821ek2mn/ciCk+MS/zoRKqdQIM3bHq6p7GXDAJLmnRRKmF5F65sAVJIfzQlwR3aDzwCn10s8hA==", + "license": "MIT", + "dependencies": { + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/vitepress/node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/vue": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.6.tgz", - "integrity": "sha512-zv+20E2VIYbcJOzJPUWp03NOGFhMmpCKOfSxVTmCYyYFFko48H9tmuQFzYj7tu4qX1AeXlp9DmhIP89/sSxxhw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz", + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.6", - "@vue/compiler-sfc": "3.5.6", - "@vue/runtime-dom": "3.5.6", - "@vue/server-renderer": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" }, "peerDependencies": { "typescript": "*" @@ -3954,15 +4490,6 @@ "node": ">=0.1" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 33670fec1..b86609ff5 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "dev": "vitepress dev", "build": "vitepress build", "preview": "vitepress preview", - "bump": "ts-node ./.vitepress/update.ts" + "bump": "tsx ./.vitepress/update.ts" }, "devDependencies": { "@types/glob": "^8.1.0", @@ -15,12 +15,13 @@ "markdownlint-rule-search-replace": "^1.2.0", "markdownlint-rule-titlecase": "^0.1.0", "prompts": "^2.4.2", - "ts-node": "^10.9.2" + "tsx": "^4.19.2" }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.21.3" }, "dependencies": { + "@vueuse/core": "^12.4.0", "markdown-it-mathjax3": "^4.3.2", "markdown-it-vuepress-code-snippet-enhanced": "github:IMB11/md-it-enhanced-snippets#dfb9fa2", "medium-zoom": "^1.1.0", diff --git a/players/faq.md b/players/faq.md index 886be051e..96a2269b2 100644 --- a/players/faq.md +++ b/players/faq.md @@ -19,9 +19,9 @@ You should always check if mods are from a trustworthy source. Check out the [Fi The majority of authors publish their mods to [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) and [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods&gameVersionTypeId=4), however some may choose to upload them on their personal websites, or on other platforms, such as a GitHub repository. -## Where Can I Find Premade Fabric Modpacks? {#where-can-i-find-premade-fabric-modpacks} +## Where Can I Find Pre-Made Fabric Modpacks? {#where-can-i-find-pre-made-fabric-modpacks} -You can find premade Fabric modpacks on a variety of platforms, such as: +You can find pre-made Fabric modpacks on a variety of platforms, such as: - [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) - [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks&gameVersionTypeId=4) diff --git a/players/troubleshooting/crash-reports.md b/players/troubleshooting/crash-reports.md index 83ebd8ade..5b19bffca 100644 --- a/players/troubleshooting/crash-reports.md +++ b/players/troubleshooting/crash-reports.md @@ -86,10 +86,10 @@ Mixins are a way for mods to modify the game without having to modify the game's When a mixin crashes, it will usually mention the mixin in the stack trace, and the class that the mixin is modifying. -Method mixins will contain `modid$handlerName` in the stack trace, where `modid` is the mod's ID, and `handlerName` is the name of the mixin handler. +Method mixins will contain `mod-id$handlerName` in the stack trace, where `mod-id` is the mod's ID, and `handlerName` is the name of the mixin handler. ```:no-line-numbers -... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +... net.minecraft.class_2248.method_3821$$$mod-id$handlerName() ... // [!code focus] ``` You can use this information to find the mod that caused the crash, and report the crash to the mod author. diff --git a/public/assets/develop/items/armor_2.png b/public/assets/develop/items/armor_2.png index ed53fd5d3..ec5cb92d1 100644 Binary files a/public/assets/develop/items/armor_2.png and b/public/assets/develop/items/armor_2.png differ diff --git a/public/assets/develop/items/example_armor_layer_textures.zip b/public/assets/develop/items/example_armor_layer_textures.zip index ce94222ef..601ba55d7 100644 Binary files a/public/assets/develop/items/example_armor_layer_textures.zip and b/public/assets/develop/items/example_armor_layer_textures.zip differ diff --git a/reference/1.21/build.gradle b/reference/1.21/build.gradle new file mode 100644 index 000000000..94a88fcb6 --- /dev/null +++ b/reference/1.21/build.gradle @@ -0,0 +1,15 @@ +def minecraftVersion = "1.21" +def yarnVersion = "1.21+build.7" +def fabricApiVersion = "0.102.0+1.21" + +dependencies { + minecraft "com.mojang:minecraft:${minecraftVersion}" + mappings "net.fabricmc:yarn:${yarnVersion}:v2" + modImplementation "net.fabricmc.fabric-api:fabric-api:${fabricApiVersion}" +} + +// :::automatic-testing:2 +test { + useJUnitPlatform() +} +// :::automatic-testing:2 diff --git a/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java b/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java new file mode 100644 index 000000000..cc3e4e640 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java @@ -0,0 +1,17 @@ +package com.example.docs; + +import net.minecraft.client.render.block.entity.BlockEntityRendererFactories; + +import net.fabricmc.api.ClientModInitializer; + +import com.example.docs.block.entity.ModBlockEntities; +import com.example.docs.rendering.blockentity.CounterBlockEntityRenderer; + +// :::1 +public class FabricDocsBlockEntityRenderer implements ClientModInitializer { + @Override + public void onInitializeClient() { + BlockEntityRendererFactories.register(ModBlockEntities.COUNTER_BLOCK_ENTITY, CounterBlockEntityRenderer::new); + } +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java b/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java new file mode 100644 index 000000000..fa3b057e5 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java @@ -0,0 +1,35 @@ +package com.example.docs; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; + +import net.fabricmc.api.ClientModInitializer; + +import com.example.docs.network.ReceiveS2C; +import com.example.docs.sound.CustomSounds; +import com.example.docs.sound.instance.CustomSoundInstance; + +public class FabricDocsDynamicSound implements ClientModInitializer { + @Override + public void onInitializeClient() { + ReceiveS2C.initialize(); + } + + private void playSimpleSoundInstance() { + // :::1 + MinecraftClient client = MinecraftClient.getInstance(); + client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + // :::1 + // :::2 + CustomSoundInstance instance = new CustomSoundInstance(client.player, CustomSounds.ENGINE_LOOP, SoundCategory.NEUTRAL); + + // play the sound instance + client.getSoundManager().play(instance); + + // stop the sound instance + client.getSoundManager().stop(instance); + // :::2 + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java b/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java new file mode 100644 index 000000000..91de9418e --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java @@ -0,0 +1,18 @@ +package com.example.docs; + +import net.minecraft.client.particle.EndRodParticle; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; + +public class FabricDocsReferenceClient implements ClientModInitializer { + @Override + public void onInitializeClient() { + // This entrypoint is suitable for setting up client-specific logic, such as rendering. + + // #particle_register_client + // For this example, we will use the end rod particle behaviour. + ParticleFactoryRegistry.getInstance().register(FabricDocsReference.SPARKLE_PARTICLE, EndRodParticle.Factory::new); + // #particle_register_client + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java b/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java new file mode 100644 index 000000000..2c43875d1 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java @@ -0,0 +1,22 @@ +package com.example.docs.client.command; + +import net.minecraft.text.Text; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; + +// Class to contain all mod client command registrations. +public class FabricDocsReferenceClientCommands implements ClientModInitializer { + @Override + public void onInitializeClient() { + // :::1 + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("clienttater").executes(context -> { + context.getSource().sendFeedback(Text.literal("Called /clienttater with no arguments.")); + return 1; + })); + }); + // :::1 + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java b/reference/1.21/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java new file mode 100644 index 000000000..8232ec86b --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java @@ -0,0 +1,67 @@ +package com.example.docs.datagen; + +import java.util.concurrent.CompletableFuture; + +import net.minecraft.component.EnchantmentEffectComponentTypes; +import net.minecraft.component.type.AttributeModifierSlot; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentLevelBasedValue; +import net.minecraft.enchantment.effect.EnchantmentEffectTarget; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.ItemTags; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider; +import net.fabricmc.fabric.api.resource.conditions.v1.ResourceCondition; + +import com.example.docs.enchantment.ModEnchantmentEffects; +import com.example.docs.enchantment.effect.LightningEnchantmentEffect; + +//#entrypoint +public class EnchantmentGenerator extends FabricDynamicRegistryProvider { + public EnchantmentGenerator(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + System.out.println("REGISTERING ENCHANTS"); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup registries, Entries entries) { + // Our new enchantment, "Thundering." + register(entries, ModEnchantmentEffects.THUNDERING, Enchantment.builder( + Enchantment.definition( + registries.getWrapperOrThrow(RegistryKeys.ITEM).getOrThrow(ItemTags.WEAPON_ENCHANTABLE), + // this is the "weight" or probability of our enchantment showing up in the table + 10, + // the maximum level of the enchantment + 3, + // base cost for level 1 of the enchantment, and min levels required for something higher + Enchantment.leveledCost(1, 10), + // same fields as above but for max cost + Enchantment.leveledCost(1, 15), + // anvil cost + 5, + // valid slots + AttributeModifierSlot.HAND + ) + ) + .addEffect( + // enchantment occurs POST_ATTACK + EnchantmentEffectComponentTypes.POST_ATTACK, + EnchantmentEffectTarget.ATTACKER, + EnchantmentEffectTarget.VICTIM, + new LightningEnchantmentEffect(EnchantmentLevelBasedValue.linear(0.4f, 0.2f)) // scale the enchantment linearly. + ) + ); + } + + private void register(Entries entries, RegistryKey key, Enchantment.Builder builder, ResourceCondition... resourceConditions) { + entries.add(key, builder.build(key.getValue()), resourceConditions); + } + + @Override + public String getName() { + return "ReferenceDocEnchantmentGenerator"; + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java new file mode 100644 index 000000000..784d4fabd --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java @@ -0,0 +1,103 @@ +package com.example.docs.datagen; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementEntry; +import net.minecraft.advancement.AdvancementFrame; +import net.minecraft.advancement.criterion.ConsumeItemCriterion; +import net.minecraft.advancement.criterion.InventoryChangedCriterion; +import net.minecraft.item.Items; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricAdvancementProvider; + +import com.example.docs.FabricDocsReference; +import com.example.docs.advancement.ModCriteria; +import com.example.docs.advancement.ParameterizedUseToolCriterion; +import com.example.docs.advancement.UseToolCriterion; + +// :::datagen-advancements:provider-start +public class FabricDocsReferenceAdvancementProvider extends FabricAdvancementProvider { + protected FabricDocsReferenceAdvancementProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup); + } + + @Override + public void generateAdvancement(RegistryWrapper.WrapperLookup wrapperLookup, Consumer consumer) { + // :::datagen-advancements:provider-start + // :::datagen-advancements:simple-advancement + AdvancementEntry getDirt = Advancement.Builder.create() + .display( + Items.DIRT, // The display icon + Text.literal("Your First Dirt Block"), // The title + Text.literal("Now make a house from it"), // The description + Identifier.ofVanilla("textures/gui/advancements/backgrounds/adventure.png"), // Background image for the tab in the advancements page, if this is a root advancement (has no parent) + AdvancementFrame.TASK, // TASK, CHALLENGE, or GOAL + true, // Show the toast when completing it + true, // Announce it to chat + false // Hide it in the advancement tab until it's achieved + ) + // "got_dirt" is the name referenced by other advancements when they want to have "requirements." + .criterion("got_dirt", InventoryChangedCriterion.Conditions.items(Items.DIRT)) + // Give the advancement an id + .build(consumer, FabricDocsReference.MOD_ID + "/get_dirt"); + // :::datagen-advancements:simple-advancement + // :::datagen-advancements:second-advancement + AdvancementEntry appleAndBeef = Advancement.Builder.create() + .parent(getDirt) + .display( + Items.APPLE, + Text.literal("Apple and Beef"), + Text.literal("Ate an apple and beef"), + null, // Children don't need a background, the root advancement takes care of that + AdvancementFrame.CHALLENGE, + true, + true, + false + ) + .criterion("ate_apple", ConsumeItemCriterion.Conditions.item(Items.APPLE)) + .criterion("ate_cooked_beef", ConsumeItemCriterion.Conditions.item(Items.COOKED_BEEF)) + .build(consumer, FabricDocsReference.MOD_ID + "/apple_and_beef"); + // :::datagen-advancements:second-advancement + // :::datagen-advancements:custom-criteria-advancement + AdvancementEntry breakBlockWithTool = Advancement.Builder.create() + .parent(getDirt) + .display( + Items.DIAMOND_SHOVEL, + Text.literal("Not a Shovel"), + Text.literal("That's not a shovel (probably)"), + null, + AdvancementFrame.GOAL, + true, + true, + false + ) + .criterion("break_block_with_tool", ModCriteria.USE_TOOL.create(new UseToolCriterion.Conditions(Optional.empty()))) + .build(consumer, FabricDocsReference.MOD_ID + "/break_block_with_tool"); + // :::datagen-advancements:custom-criteria-advancement + // :::datagen-advancements:new-custom-criteria-advancement + AdvancementEntry breakBlockWithToolFiveTimes = Advancement.Builder.create() + .parent(breakBlockWithTool) + .display( + Items.GOLDEN_SHOVEL, + Text.literal("Not a Shovel Still"), + Text.literal("That's still not a shovel (probably)"), + null, + AdvancementFrame.GOAL, + true, + true, + false + ) + .criterion("break_block_with_tool_five_times", ModCriteria.PARAMETERIZED_USE_TOOL.create(new ParameterizedUseToolCriterion.Conditions(Optional.empty(), 5))) + .build(consumer, FabricDocsReference.MOD_ID + "/break_block_with_tool_five_times"); + // :::datagen-advancements:new-custom-criteria-advancement + // :::datagen-advancements:provider-start + } +} +// :::datagen-advancements:provider-start diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java new file mode 100644 index 000000000..094c92926 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java @@ -0,0 +1,42 @@ +package com.example.docs.datagen; + +import java.util.concurrent.CompletableFuture; + +import net.minecraft.item.Items; +import net.minecraft.loot.LootPool; +import net.minecraft.loot.LootTable; +import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.loot.provider.number.ConstantLootNumberProvider; +import net.minecraft.loot.provider.number.UniformLootNumberProvider; +import net.minecraft.registry.RegistryWrapper; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider; + +import com.example.docs.block.ModBlocks; + +// :::datagen-loot-tables:block-provider +public class FabricDocsReferenceBlockLootTableProvider extends FabricBlockLootTableProvider { + protected FabricDocsReferenceBlockLootTableProvider(FabricDataOutput dataOutput, CompletableFuture registryLookup) { + super(dataOutput, registryLookup); + } + + @Override + public void generate() { + // :::datagen-loot-tables:block-provider + // :::datagen-loot-tables:block-drops + // Make condensed dirt drop its block item. + // Also adds the condition that it survives the explosion that broke it, if applicable, + addDrop(ModBlocks.CONDENSED_DIRT); + // Make prismarine lamps drop themselves with silk touch only + addDropWithSilkTouch(ModBlocks.PRISMARINE_LAMP); + // Make condensed oak logs drop between 7 and 9 oak logs + addDrop(ModBlocks.CONDENSED_OAK_LOG, LootTable.builder().pool(addSurvivesExplosionCondition(Items.OAK_LOG, LootPool.builder() + .rolls(new UniformLootNumberProvider(new ConstantLootNumberProvider(7), new ConstantLootNumberProvider(9))) + .with(ItemEntry.builder(Items.OAK_LOG)))) + ); + // :::datagen-loot-tables:block-drops + // :::datagen-loot-tables:block-provider + } +} +// :::datagen-loot-tables:block-provider diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java new file mode 100644 index 000000000..e2452dd95 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java @@ -0,0 +1,43 @@ +package com.example.docs.datagen; + +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; + +import net.minecraft.item.Items; +import net.minecraft.loot.LootPool; +import net.minecraft.loot.LootTable; +import net.minecraft.loot.context.LootContextTypes; +import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.loot.function.SetCountLootFunction; +import net.minecraft.loot.provider.number.ConstantLootNumberProvider; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryWrapper; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; + +import com.example.docs.ModLootTables; + +// :::datagen-loot-tables:chest-provider +public class FabricDocsReferenceChestLootTableProvider extends SimpleFabricLootTableProvider { + public FabricDocsReferenceChestLootTableProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup, LootContextTypes.CHEST); + } + + @Override + public void accept(BiConsumer, LootTable.Builder> lootTableBiConsumer) { + // :::datagen-loot-tables:chest-provider + // :::datagen-loot-tables:chest-loot + lootTableBiConsumer.accept(ModLootTables.TEST_CHEST_LOOT, LootTable.builder() + .pool(LootPool.builder() // One pool + .rolls(ConstantLootNumberProvider.create(2.0f)) // That has two rolls + .with(ItemEntry.builder(Items.DIAMOND) // With an entry that has diamond(s) + .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1.0f)))) // One diamond + .with(ItemEntry.builder(Items.DIAMOND_SWORD) // With an entry that has a plain diamond sword + ) + )); + // :::datagen-loot-tables:chest-loot + // :::datagen-loot-tables:chest-provider + } +} +// :::datagen-loot-tables:chest-provider diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDamageTypesProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDamageTypesProvider.java new file mode 100644 index 000000000..2c1a7bff2 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDamageTypesProvider.java @@ -0,0 +1,59 @@ +package com.example.docs.datagen; + +import java.util.concurrent.CompletableFuture; + +import com.google.gson.JsonObject; + +import net.minecraft.data.DataOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.DataWriter; +import net.minecraft.entity.damage.DamageScaling; +import net.minecraft.entity.damage.DamageType; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; + +import com.example.docs.damage.FabricDocsReferenceDamageTypes; + +public class FabricDocsReferenceDamageTypesProvider { + public static final DamageType TATER_DAMAGE_TYPE = new DamageType("tater", DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, 0.1f); + + public static class TaterDamageTypeTagGenerator extends FabricTagProvider { + TaterDamageTypeTagGenerator(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, RegistryKeys.DAMAGE_TYPE, registriesFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup arg) { + getOrCreateTagBuilder(TagKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of("minecraft:bypasses_armor"))).add(FabricDocsReferenceDamageTypes.TATER_DAMAGE); + } + } + + public static class TaterDamageTypesGenerator implements DataProvider { + private final DataOutput.PathResolver path; + + TaterDamageTypesGenerator(FabricDataOutput fabricDataOutput) { + path = fabricDataOutput.getResolver(DataOutput.OutputType.DATA_PACK, "damage_type/"); + } + + @Override + public CompletableFuture run(DataWriter writer) { + JsonObject damageTypeObject = new JsonObject(); + + damageTypeObject.addProperty("exhaustion", TATER_DAMAGE_TYPE.exhaustion()); + damageTypeObject.addProperty("message_id", TATER_DAMAGE_TYPE.msgId()); + damageTypeObject.addProperty("scaling", TATER_DAMAGE_TYPE.scaling().asString()); + + return DataProvider.writeToPath(writer, damageTypeObject, path.resolveJson(Identifier.of("fabric-docs-reference", "tater"))); + } + + @Override + public String getName() { + return "Damage Type"; + } + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java new file mode 100644 index 000000000..ad940193f --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java @@ -0,0 +1,51 @@ +package com.example.docs.datagen; + +import static com.example.docs.datagen.FabricDocsReferenceDamageTypesProvider.TATER_DAMAGE_TYPE; + +import net.minecraft.registry.RegistryBuilder; +import net.minecraft.registry.RegistryKeys; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +import com.example.docs.damage.FabricDocsReferenceDamageTypes; + +// :::datagen-setup:generator +public class FabricDocsReferenceDataGenerator implements DataGeneratorEntrypoint { + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + // :::datagen-setup:generator + // :::datagen-setup:pack + FabricDataGenerator.Pack pack = fabricDataGenerator.createPack(); + // :::datagen-setup:pack + + pack.addProvider(EnchantmentGenerator::new); + + pack.addProvider(FabricDocsReferenceAdvancementProvider::new); + + pack.addProvider(FabricDocsReferenceEnglishLangProvider::new); + + pack.addProvider(FabricDocsReferenceItemTagProvider::new); + + pack.addProvider(FabricDocsReferenceRecipeProvider::new); + + pack.addProvider(FabricDocsReferenceBlockLootTableProvider::new); + pack.addProvider(FabricDocsReferenceChestLootTableProvider::new); + + pack.addProvider(FabricDocsReferenceDamageTypesProvider.TaterDamageTypesGenerator::new); + pack.addProvider(FabricDocsReferenceDamageTypesProvider.TaterDamageTypeTagGenerator::new); + + // :::datagen-setup:generator + } + + // :::datagen-setup:generator + @Override + public void buildRegistry(RegistryBuilder registryBuilder) { + registryBuilder.addRegistry(RegistryKeys.DAMAGE_TYPE, registerable -> { + registerable.register(FabricDocsReferenceDamageTypes.TATER_DAMAGE, TATER_DAMAGE_TYPE); + }); + } + + // :::datagen-setup:generator +} +// :::datagen-setup:generator diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java new file mode 100644 index 000000000..fdd422d2c --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java @@ -0,0 +1,54 @@ +package com.example.docs.datagen; + +import java.util.concurrent.CompletableFuture; + +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider; + +import com.example.docs.item.ModItems; + +// :::datagen-translations:provider +public class FabricDocsReferenceEnglishLangProvider extends FabricLanguageProvider { + protected FabricDocsReferenceEnglishLangProvider(FabricDataOutput dataOutput, CompletableFuture registryLookup) { + // Specifying en_us is optional, as it's the default language code + super(dataOutput, "en_us", registryLookup); + } + + @Override + public void generateTranslations(RegistryWrapper.WrapperLookup wrapperLookup, TranslationBuilder translationBuilder) { + // :::datagen-translations:provider + // :::datagen-translations:build + translationBuilder.add("text.fabric_docs_reference.greeting", "Hello there!"); + // :::datagen-translations:build + translationBuilder.add(ModItems.GUIDITE_HELMET, "Guidite Helmet"); + translationBuilder.add(ModItems.GUIDITE_CHESTPLATE, "Guidite Chestplate"); + translationBuilder.add(ModItems.GUIDITE_LEGGINGS, "Guidite Leggings"); + translationBuilder.add(ModItems.GUIDITE_BOOTS, "Guidite Boots"); + translationBuilder.add(ModItems.GUIDITE_SWORD, "Guidite Sword"); + translationBuilder.add(ModItems.SUSPICIOUS_SUBSTANCE, "Suspicious Substance"); + + translationBuilder.add(Util.createTranslationKey("effect", Identifier.of("fabric-docs-reference", "tater")), "Tater"); + + // You can alternatively use the translationBuilder.add(Path.of("../existing/language/file.json")); + // to add translations from an existing language file instead of manually defining them all. + translationBuilder.add("sound.fabric-docs-reference.metal_whistle", "Metal Whistle"); + translationBuilder.add("item.minecraft.potion.effect.tater", "Tater Potion"); + translationBuilder.add("death.attack.tater", "%1$s died from Tater damage!"); + translationBuilder.add("item.fabric-docs-reference.poisonous_apple", "Poisonous Apple"); + translationBuilder.add("item.fabric-docs-reference.lightning_stick", "Lightning Stick"); + translationBuilder.add("item.fabric-docs-reference.counter", "Counter"); + translationBuilder.add("item.fabric-docs-reference.counter.info", "Used %1$s times"); + translationBuilder.add("itemTooltip.fabric-docs-reference.lightning_stick", "This is an extremely powerful weapon that can summon lightning bolts."); + translationBuilder.add("itemGroup.fabric_docs_reference", "Fabric Docs Reference"); + translationBuilder.add("block.fabric-docs-reference.condensed_dirt", "Condensed Dirt"); + translationBuilder.add("block.fabric-docs-reference.condensed_oak_log", "Condensed Oak Log"); + translationBuilder.add("block.fabric-docs-reference.prismarine_lamp", "Prismarine Lamp"); + translationBuilder.add("enchantment.FabricDocsReference.thundering", "Thundering"); + // :::datagen-translations:provider + } +} +// :::datagen-translations:provider diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java new file mode 100644 index 000000000..dde90f0ae --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java @@ -0,0 +1,44 @@ +package com.example.docs.datagen; + +import java.util.concurrent.CompletableFuture; + +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.ItemTags; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; + +import com.example.docs.FabricDocsReference; + +// :::datagen-tags:provider +public class FabricDocsReferenceItemTagProvider extends FabricTagProvider { + // :::datagen-tags:provider + // :::datagen-tags:tag-key + public static final TagKey SMELLY_ITEMS = TagKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "smelly_items")); + // :::datagen-tags:tag-key + // :::datagen-tags:provider + public FabricDocsReferenceItemTagProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, RegistryKeys.ITEM, registriesFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { + // :::datagen-tags:provider + // :::datagen-tags:build + getOrCreateTagBuilder(SMELLY_ITEMS) + .add(Items.SLIME_BALL) + .add(Items.ROTTEN_FLESH) + .addOptionalTag(ItemTags.DIRT) + .add(Identifier.ofVanilla("oak_planks")) + .forceAddTag(ItemTags.BANNERS) + .setReplace(true); + // :::datagen-tags:build + // :::datagen-tags:provider + } +} +// :::datagen-tags:provider diff --git a/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java new file mode 100644 index 000000000..72ab5493e --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java @@ -0,0 +1,67 @@ +package com.example.docs.datagen; + +// :::datagen-recipes:provider +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.Items; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.ItemTags; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; + +public class FabricDocsReferenceRecipeProvider extends FabricRecipeProvider { + public FabricDocsReferenceRecipeProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + public void generate(RecipeExporter recipeExporter) { + // :::datagen-recipes:provider + // :::datagen-recipes:shapeless + ShapelessRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, Items.DIRT) // You can also specify an int to produce more than one + .input(Items.COARSE_DIRT) // You can also specify an int to require more than one, or a tag to accept multiple things + // Create an advancement that gives you the recipe + .criterion(FabricRecipeProvider.hasItem(Items.COARSE_DIRT), FabricRecipeProvider.conditionsFromItem(Items.COARSE_DIRT)) + .offerTo(recipeExporter); + // :::datagen-recipes:shapeless + // :::datagen-recipes:shaped + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.CRAFTING_TABLE, 4) + .pattern("ll") + .pattern("ll") + .input('l', ItemTags.LOGS) // 'l' means "any log" + .group("multi_bench") // Put it in a group called "multi_bench" - groups are shown in one slot in the recipe book + .criterion(FabricRecipeProvider.hasItem(Items.CRAFTING_TABLE), FabricRecipeProvider.conditionsFromItem(Items.CRAFTING_TABLE)) + .offerTo(recipeExporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.LOOM, 4) + .pattern("ww") + .pattern("ll") + .input('w', ItemTags.WOOL) // 'w' means "any wool" + .input('l', ItemTags.LOGS) + .group("multi_bench") + .criterion(FabricRecipeProvider.hasItem(Items.LOOM), FabricRecipeProvider.conditionsFromItem(Items.LOOM)) + .offerTo(recipeExporter); + FabricRecipeProvider.createDoorRecipe(Items.OAK_DOOR, Ingredient.ofItems(Items.OAK_BUTTON)) // Using a helper method! + .criterion(FabricRecipeProvider.hasItem(Items.OAK_BUTTON), FabricRecipeProvider.conditionsFromItem(Items.OAK_BUTTON)) + .offerTo(recipeExporter); + // :::datagen-recipes:shaped + // :::datagen-recipes:other + FabricRecipeProvider.offerSmelting(recipeExporter, + List.of(Items.BREAD, Items.COOKIE, Items.HAY_BLOCK), // Inputs + RecipeCategory.FOOD, // Category + Items.WHEAT, // Output + 0.1f, // Experience + 300, // Cooking time + "food_to_wheat" // group + ); + // :::datagen-recipes:other + // :::datagen-recipes:provider + } +} +// :::datagen-recipes:provider diff --git a/reference/1.21/src/client/java/com/example/docs/mixin/client/ExampleClientMixin.java b/reference/1.21/src/client/java/com/example/docs/mixin/client/ExampleClientMixin.java new file mode 100644 index 000000000..4fd21eee5 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/mixin/client/ExampleClientMixin.java @@ -0,0 +1,16 @@ +package com.example.docs.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.MinecraftClient; + +@Mixin(MinecraftClient.class) +public class ExampleClientMixin { + @Inject(at = @At("HEAD"), method = "run") + private void run(CallbackInfo info) { + // This code is injected into the start of MinecraftClient.run()V + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/mixin/client/TitleScreenMixin.java b/reference/1.21/src/client/java/com/example/docs/mixin/client/TitleScreenMixin.java new file mode 100644 index 000000000..f8cf56721 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/mixin/client/TitleScreenMixin.java @@ -0,0 +1,27 @@ +package com.example.docs.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; + +import com.example.docs.rendering.DrawContextExampleScreen; +import com.example.docs.rendering.screens.CustomScreen; + +@Mixin(TitleScreen.class) +public class TitleScreenMixin extends Screen { + protected TitleScreenMixin(Text title) { + super(title); + } + + @Inject(method = "init", at = @At("TAIL"), cancellable = false) + private void addTestWidgets(CallbackInfo ci) { + this.addDrawableChild(ButtonWidget.builder(Text.of("DrawContext Test"), (btn) -> this.client.setScreen(new DrawContextExampleScreen())).dimensions(5, 5, 60, 20).build()); + this.addDrawableChild(ButtonWidget.builder(Text.of("CustomScreen 1"), (btn) -> this.client.setScreen(new CustomScreen(Text.empty()))).dimensions(5, 5+30, 60, 20).build()); + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/network/ReceiveS2C.java b/reference/1.21/src/client/java/com/example/docs/network/ReceiveS2C.java new file mode 100644 index 000000000..7e43ea88b --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/network/ReceiveS2C.java @@ -0,0 +1,48 @@ +package com.example.docs.network; + +import net.minecraft.client.world.ClientWorld; +import net.minecraft.sound.SoundCategory; + +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; + +import com.example.docs.block.entity.custom.EngineBlockEntity; +import com.example.docs.networking.payload.EngineSoundInstancePacket; +import com.example.docs.sound.AbstractDynamicSoundInstance; +import com.example.docs.sound.CustomSounds; +import com.example.docs.sound.DynamicSoundManager; +import com.example.docs.sound.instance.EngineSoundInstance; + +public class ReceiveS2C { + static { + ClientPlayNetworking.registerGlobalReceiver(EngineSoundInstancePacket.IDENTIFIER, ReceiveS2C::handleS2CEngineSoundPacket); + } + + // :::1 + private static void handleS2CEngineSoundPacket(EngineSoundInstancePacket packet, ClientPlayNetworking.Context context) { + ClientWorld world = context.client().world; + if (world == null) return; + + DynamicSoundManager soundManager = DynamicSoundManager.getInstance(); + + if (world.getBlockEntity(packet.blockEntityPos()) instanceof EngineBlockEntity engineBlockEntity) { + if (packet.shouldStart()) { + soundManager.play(new EngineSoundInstance(engineBlockEntity, + CustomSounds.ENGINE_LOOP, SoundCategory.BLOCKS, + 60, 30, 1.2f, 0.8f, 1.4f, + soundManager) + ); + + return; + } + } + + if (!packet.shouldStart()) { + soundManager.getPlayingSoundInstance(CustomSounds.ENGINE_LOOP).ifPresent(AbstractDynamicSoundInstance::end); + } + } + + // :::1 + + public static void initialize() { + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java b/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java new file mode 100644 index 000000000..2f79aa2f7 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java @@ -0,0 +1,75 @@ +package com.example.docs.rendering; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public class DrawContextExampleScreen extends Screen { + public DrawContextExampleScreen() { + super(Text.empty()); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + + // :::1 + int rectangleX = 10; + int rectangleY = 10; + int rectangleWidth = 100; + int rectangleHeight = 50; + // x1, y1, x2, y2, color + context.fill(rectangleX, rectangleY, rectangleX + rectangleWidth, rectangleY + rectangleHeight, 0xFF0000FF); + // :::1 + + // :::2 + // x, y, width, height, color + context.drawBorder(rectangleX, rectangleY, rectangleWidth, rectangleHeight, 0xFFFF0000); + // :::2 + + // :::3 + // Let's split the rectangle in half using a green line. + // x, y1, y2, color + context.drawVerticalLine(rectangleX + rectangleWidth / 2, rectangleY, rectangleY + rectangleHeight, 0xFF00FF00); + // :::3 + + // :::4 + // Let's create a scissor region that covers a middle bar section of the screen. + int scissorRegionX = 200; + int scissorRegionY = 20; + int scissorRegionWidth = 100; + + // The height of the scissor region is the height of the screen minus the height of the top and bottom bars. + int scissorRegionHeight = this.height - 40; + + // x1, y1, x2, y2 + context.enableScissor(scissorRegionX, scissorRegionY, scissorRegionX + scissorRegionWidth, scissorRegionY + scissorRegionHeight); + + // Let's fill the entire screen with a color gradient, it should only be visible in the scissor region. + // x1, y1, x2, y2, color1, color2 + context.fillGradient(0, 0, this.width, this.height, 0xFFFF0000, 0xFF0000FF); + + // Disable the scissor region. + context.disableScissor(); + // :::4 + + // :::5 + Identifier texture = Identifier.of("minecraft", "textures/block/deepslate.png"); + // texture, x, y, u, v, width, height, textureWidth, textureHeight + context.drawTexture(texture, 90, 90, 0, 0, 16, 16, 16, 16); + // :::5 + + // :::6 + Identifier texture2 = Identifier.of("fabric-docs-reference", "textures/gui/test-uv-drawing.png"); + int u = 10, v = 13, regionWidth = 14, regionHeight = 14; + // texture, x, y, width, height, u, v, regionWidth, regionHeight, textureWidth, textureHeight + context.drawTexture(texture2, 90, 190, 14, 14, u, v, regionWidth, regionHeight, 256, 256); + // :::6 + + // :::7 + // TextRenderer, text (string, or Text object), x, y, color, shadow + context.drawText(client.textRenderer, "Hello, world!", 10, 200, 0xFFFFFFFF, false); + // :::7 + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java b/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java new file mode 100644 index 000000000..d226f49fe --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java @@ -0,0 +1,31 @@ +package com.example.docs.rendering; + +import net.minecraft.util.math.ColorHelper; +import net.minecraft.util.math.MathHelper; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; + +public class HudRenderingEntrypoint implements ClientModInitializer { + private float totalTickDelta = 0.0F; + @Override + public void onInitializeClient() { + // :::1 + HudRenderCallback.EVENT.register((context, tickDeltaManager) -> { + int color = 0xFFFF0000; // Red + int targetColor = 0xFF00FF00; // Green + + // Total tick delta is stored in a field, so we can use it later. + totalTickDelta += tickDeltaManager.getTickDelta(true); + + // "lerp" simply means "linear interpolation", which is a fancy way of saying "blend". + float lerpedAmount = MathHelper.abs(MathHelper.sin(totalTickDelta / 50F)); + int lerpedColor = ColorHelper.Argb.lerp(lerpedAmount, color, targetColor); + + // Draw a square with the lerped color. + // x1, x2, y1, y2, z, color + context.fill(0, 0, 100, 100, 0, lerpedColor); + }); + // :::1 + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java b/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java new file mode 100644 index 000000000..311ea2434 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java @@ -0,0 +1,93 @@ +package com.example.docs.rendering; + +import com.mojang.blaze3d.systems.RenderSystem; +import org.joml.Matrix4f; + +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.BufferRenderer; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormat; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RotationAxis; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; + +public class RenderingConceptsEntrypoint implements ClientModInitializer { + public float totalTickDelta = 0F; + + @Override + public void onInitializeClient() { + // "A Practical Example: Rendering a Triangle Strip" + // :::1 + HudRenderCallback.EVENT.register((drawContext, tickDeltaManager) -> { + // :::1 + if (true) { + return; + } + + // :::2 + MatrixStack matrices = drawContext.getMatrices(); + + // Store the total tick delta in a field, so we can use it later. + totalTickDelta += tickDeltaManager.getTickDelta(true); + + // Push a new matrix onto the stack. + matrices.push(); + // :::2 + // :::1 + // Get the transformation matrix from the matrix stack, alongside the tessellator instance and a new buffer builder. + Matrix4f transformationMatrix = drawContext.getMatrices().peek().getPositionMatrix(); + Tessellator tessellator = Tessellator.getInstance(); + + // :::1 + // :::2 + // Scale the matrix by 0.5 to make the triangle smaller and larger over time. + float scaleAmount = MathHelper.sin(totalTickDelta / 10F) / 2F + 1.5F; + + // Apply the scaling amount to the matrix. + // We don't need to scale the Z axis since it's on the HUD and 2D. + matrices.scale(scaleAmount, scaleAmount, 1F); + // :::2 + matrices.scale(1 / scaleAmount, 1 / scaleAmount, 1F); + matrices.translate(60f, 60f, 0f); + // :::3 + // Lerp between 0 and 360 degrees over time. + float rotationAmount = (float) (totalTickDelta / 50F % 360); + matrices.multiply(RotationAxis.POSITIVE_Z.rotation(rotationAmount)); + // Shift entire diamond so that it rotates in its center. + matrices.translate(-20f, -40f, 0f); + // :::3 + + // :::1 + // Begin a triangle strip buffer using the POSITION_COLOR vertex format. + BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR); + + // Write our vertices, Z doesn't really matter since it's on the HUD. + buffer.vertex(transformationMatrix, 20, 20, 5).color(0xFF414141); + buffer.vertex(transformationMatrix, 5, 40, 5).color(0xFF000000); + buffer.vertex(transformationMatrix, 35, 40, 5).color(0xFF000000); + buffer.vertex(transformationMatrix, 20, 60, 5).color(0xFF414141); + + // We'll get to this bit in the next section. + RenderSystem.setShader(GameRenderer::getPositionColorProgram); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + + // Draw the buffer onto the screen. + BufferRenderer.drawWithGlobalProgram(buffer.end()); + // :::1 + // :::2 + + // ... write to the buffer. + + // Pop our matrix from the stack. + matrices.pop(); + // :::2 + // :::1 + }); + // :::1 + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java b/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java new file mode 100644 index 000000000..84d725e79 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java @@ -0,0 +1,27 @@ +package com.example.docs.rendering; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.mojang.serialization.JsonOps; + +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TextCodecs; + +public class TextTests { + public void test() { + // :::1 + Gson gson = new Gson(); + MutableText mutable = Text.translatable("my_mod.text.bye"); + String json = gson.toJson(TextCodecs.CODEC.encodeStart(JsonOps.INSTANCE, mutable).getOrThrow()); + // :::1 + + // :::2 + String jsonString = "..."; + Text deserialized = TextCodecs.CODEC + .decode(JsonOps.INSTANCE, gson.fromJson(jsonString, JsonElement.class)) + .getOrThrow() + .getFirst(); + // :::2 + } +} diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java b/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java new file mode 100644 index 000000000..0c7c2de48 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java @@ -0,0 +1,60 @@ +package com.example.docs.rendering.blockentity; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.block.entity.BlockEntityRenderer; +import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.RotationAxis; + +import com.example.docs.block.entity.custom.CounterBlockEntity; + +// :::1 +public class CounterBlockEntityRenderer implements BlockEntityRenderer { + // :::1 + + private final TextRenderer textRenderer; + + // :::1 + public CounterBlockEntityRenderer(BlockEntityRendererFactory.Context context) { + // :::1 + textRenderer = context.getTextRenderer(); + // :::1 + } + + @Override + public void render(CounterBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) { + // :::1 + + // :::2 + matrices.push(); + matrices.translate(0.5, 1, 0.5); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); + matrices.scale(1/18f, 1/18f, 1/18f); + // :::2 + + // :::3 + String text = entity.getClicks() + ""; + float width = textRenderer.getWidth(text); + + // draw the text. params: + // text, x, y, color, shadow, matrix, vertexConsumers, layerType, backgroundColor, light + textRenderer.draw( + text, + -width/2, -4f, + 0xffffff, + false, + matrices.peek().getPositionMatrix(), + vertexConsumers, + TextRenderer.TextLayerType.SEE_THROUGH, + 0, + light + ); + // :::3 + + matrices.pop(); + + // :::1 + } +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java b/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java new file mode 100644 index 000000000..1cf609b28 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java @@ -0,0 +1,66 @@ +package com.example.docs.rendering.screens; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.toast.SystemToast; +import net.minecraft.text.Text; + +// :::1 +public class CustomScreen extends Screen { + // :::1 + // :::2 + public Screen parent; + public CustomScreen(Text title, Screen parent) { + super(title); + this.parent = parent; + } + + @Override + public void close() { + this.client.setScreen(this.parent); + } + + // :::2 + // :::1 + public CustomScreen(Text title) { + super(title); + } + + @Override + protected void init() { + ButtonWidget buttonWidget = ButtonWidget.builder(Text.of("Hello World"), (btn) -> { + // When the button is clicked, we can display a toast to the screen. + this.client.getToastManager().add( + SystemToast.create(this.client, SystemToast.Type.NARRATOR_TOGGLE, Text.of("Hello World!"), Text.of("This is a toast.")) + ); + }).dimensions(40, 40, 120, 20).build(); + // x, y, width, height + // It's recommended to use the fixed height of 20 to prevent rendering issues with the button + // textures. + + // Register the button widget. + this.addDrawableChild(buttonWidget); + + // :::1 + // :::3 + // Add a custom widget to the screen. + // x, y, width, height + CustomWidget customWidget = new CustomWidget(40, 80, 120, 20); + this.addDrawableChild(customWidget); + // :::3 + // :::1 + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + + // Minecraft doesn't have a "label" widget, so we'll have to draw our own text. + // We'll subtract the font height from the Y position to make the text appear above the button. + // Subtracting an extra 10 pixels will give the text some padding. + // textRenderer, text, x, y, color, hasShadow + context.drawText(this.textRenderer, "Special Button", 40, 40 - this.textRenderer.fontHeight - 10, 0xFFFFFFFF, true); + } +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java b/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java new file mode 100644 index 000000000..c5c24e275 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java @@ -0,0 +1,40 @@ +package com.example.docs.rendering.screens; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.text.Text; + +// :::1 +public class CustomWidget extends ClickableWidget { + public CustomWidget(int x, int y, int width, int height) { + super(x, y, width, height, Text.empty()); + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + // We'll just draw a simple rectangle for now. + // x1, y1, x2, y2, startColor, endColor + int startColor = 0xFF00FF00; // Green + int endColor = 0xFF0000FF; // Blue + + // :::1 + // :::2 + // This is in the "renderWidget" method, so we can check if the mouse is hovering over the widget. + if (isHovered()) { + startColor = 0xFFFF0000; // Red + endColor = 0xFF00FFFF; // Cyan + } + + // :::2 + // :::1 + context.fillGradient(getX(), getY(), getX() + this.width, getY() + this.height, startColor, endColor); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + // For brevity, we'll just skip this for now - if you want to add narration to your widget, you can do so here. + return; + } +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java b/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java new file mode 100644 index 000000000..76ecf2c63 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java @@ -0,0 +1,146 @@ +package com.example.docs.sound; + +import net.minecraft.client.sound.MovingSoundInstance; +import net.minecraft.client.sound.SoundInstance; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.MathHelper; + +import com.example.docs.sound.instance.SoundInstanceCallback; + +// :::1 +public abstract class AbstractDynamicSoundInstance extends MovingSoundInstance { + protected final DynamicSoundSource soundSource; // Entities, BlockEntities, ... + protected TransitionState transitionState; // current TransitionState of the SoundInstance + + protected final int startTransitionTicks, endTransitionTicks; // duration of starting and ending phases + + // possible volume range when adjusting sound values + protected final float maxVolume; // only max value since the minimum is always 0 + // possible pitch range when adjusting sound values + protected final float minPitch, maxPitch; + + protected int currentTick = 0, transitionTick = 0; // current tick values for the instance + + protected final SoundInstanceCallback callback; // callback for soundInstance states + + // ... + // :::1 + + // :::2 + // ... + + // set up default settings of the SoundInstance in this constructor + protected AbstractDynamicSoundInstance(DynamicSoundSource soundSource, SoundEvent soundEvent, SoundCategory soundCategory, + int startTransitionTicks, int endTransitionTicks, float maxVolume, float minPitch, float maxPitch, + SoundInstanceCallback callback) { + super(soundEvent, soundCategory, SoundInstance.createRandom()); + + // store important references to other objects + this.soundSource = soundSource; + this.callback = callback; + + // store the limits for the SoundInstance + this.maxVolume = maxVolume; + this.minPitch = minPitch; + this.maxPitch = maxPitch; + this.startTransitionTicks = startTransitionTicks; // starting phase duration + this.endTransitionTicks = endTransitionTicks; // ending phase duration + + // set start values + this.volume = 0.0f; + this.pitch = minPitch; + this.repeat = true; + this.transitionState = TransitionState.STARTING; + this.setPositionToEntity(); + } + + // ... + // :::2 + + // :::3 + @Override + public boolean shouldAlwaysPlay() { + // override to true, so that the SoundInstance can start + // or add your own condition to the SoundInstance, if necessary + return true; + } + + // :::3 + + // :::4 + @Override + public void tick() { + // handle states where sound might be actually stopped instantly + if (this.soundSource == null) { + this.callback.onFinished(this); + } + + // basic tick behaviour + this.currentTick++; + this.setPositionToEntity(); + + // SoundInstance phase switching + switch (this.transitionState) { + case STARTING -> { + this.transitionTick++; + + // go into next phase if starting phase finished its duration + if (this.transitionTick > this.startTransitionTicks) { + this.transitionTick = 0; // reset tick for future ending phase + this.transitionState = TransitionState.RUNNING; + } + } + case ENDING -> { + this.transitionTick++; + + // set SoundInstance as finished if ending phase finished its duration + if (this.transitionTick > this.endTransitionTicks) { + this.callback.onFinished(this); + } + } + } + + // apply volume and pitch modulation here, + // if you use a normal SoundInstance class + } + + // :::4 + + // :::5 + // increase or decrease volume and pitch based on the current phase of the sound + protected void modulateSoundForTransition() { + float normalizedTick = switch (transitionState) { + case STARTING -> (float) this.transitionTick / this.startTransitionTicks; + case ENDING -> 1.0f - ((float) this.transitionTick / this.endTransitionTicks); + default -> 1.0f; + }; + + this.volume = MathHelper.lerp(normalizedTick, 0.0f, this.maxVolume); + } + + // increase or decrease pitch based on the sound source's stress value + protected void modulateSoundForStress() { + this.pitch = MathHelper.lerp(this.soundSource.getNormalizedStress(), this.minPitch, this.maxPitch); + } + + // :::5 + + // :::6 + // moves the sound instance position to the sound source's position + protected void setPositionToEntity() { + this.x = soundSource.getPosition().getX(); + this.y = soundSource.getPosition().getY(); + this.z = soundSource.getPosition().getZ(); + } + + // Sets the SoundInstance into its ending phase. + // This is especially useful for external access to this SoundInstance + public void end() { + this.transitionState = TransitionState.ENDING; + } + + // :::6 + // :::1 +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java b/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java new file mode 100644 index 000000000..a8650d34b --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java @@ -0,0 +1,79 @@ +package com.example.docs.sound; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.sound.SoundEvent; + +import com.example.docs.sound.instance.SoundInstanceCallback; + +// :::1 +public class DynamicSoundManager implements SoundInstanceCallback { + // An instance of the client to use Minecraft's default SoundManager + private static final MinecraftClient client = MinecraftClient.getInstance(); + // static field to store the current instance for the Singleton Design Pattern + private static DynamicSoundManager instance; + // The list which keeps track of all currently playing dynamic SoundInstances + private final List activeSounds = new ArrayList<>(); + + private DynamicSoundManager() { + // private constructor to make sure that the normal + // instantiation of that object is not used externally + } + + // when accessing this class for the first time a new instance + // is created and stored. If this is called again only the already + // existing instance will be returned, instead of creating a new instance + public static DynamicSoundManager getInstance() { + if (instance == null) { + instance = new DynamicSoundManager(); + } + + return instance; + } + + // :::1 + + // :::2 + // Plays a sound instance, if it doesn't already exist in the list + public void play(T soundInstance) { + if (this.activeSounds.contains(soundInstance)) return; + + client.getSoundManager().play(soundInstance); + this.activeSounds.add(soundInstance); + } + + // Stops a sound immediately. in most cases it is preferred to use + // the sound's ending phase, which will clean it up after completion + public void stop(T soundInstance) { + client.getSoundManager().stop(soundInstance); + this.activeSounds.remove(soundInstance); + } + + // Finds a SoundInstance from a SoundEvent, if it exists and is currently playing + public Optional getPlayingSoundInstance(SoundEvent soundEvent) { + for (var activeSound : this.activeSounds) { + // SoundInstances use their SoundEvent's id by default + if (activeSound.getId().equals(soundEvent.getId())) { + return Optional.of(activeSound); + } + } + + return Optional.empty(); + } + + // :::2 + + // :::1 + + // This is where the callback signal of a finished custom SoundInstance will arrive. + // For now, we can just stop and remove the sound from the list, but you can add + // your own functionality too + @Override + public void onFinished(T soundInstance) { + this.stop(soundInstance); + } +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/sound/instance/CustomSoundInstance.java b/reference/1.21/src/client/java/com/example/docs/sound/instance/CustomSoundInstance.java new file mode 100644 index 000000000..ef5f4a904 --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/sound/instance/CustomSoundInstance.java @@ -0,0 +1,52 @@ +package com.example.docs.sound.instance; + +import net.minecraft.client.sound.MovingSoundInstance; +import net.minecraft.client.sound.SoundInstance; +import net.minecraft.entity.LivingEntity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; + +// :::1 +public class CustomSoundInstance extends MovingSoundInstance { + private final LivingEntity entity; + + public CustomSoundInstance(LivingEntity entity, SoundEvent soundEvent, SoundCategory soundCategory) { + super(soundEvent, soundCategory, SoundInstance.createRandom()); + // In this constructor we also add the sound source (LivingEntity) of + // the SoundInstance and store it in the current object + this.entity = entity; + // set up default values when the sound is about to start + this.volume = 1.0f; + this.pitch = 1.0f; + this.repeat = true; + this.setPositionToEntity(); + } + + @Override + public void tick() { + // stop sound instantly if sound source does not exist anymore + if (this.entity == null || this.entity.isRemoved() || this.entity.isDead()) { + this.setDone(); + return; + } + + // move sound position over to the new position for every tick + this.setPositionToEntity(); + } + + @Override + public boolean shouldAlwaysPlay() { + // override to true, so that the SoundInstance can start + // or add your own condition to the SoundInstance, if necessary + return true; + } + + // small utility method to move the sound instance position + // to the sound source's position + private void setPositionToEntity() { + this.x = this.entity.getX(); + this.y = this.entity.getY(); + this.z = this.entity.getZ(); + } +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/sound/instance/EngineSoundInstance.java b/reference/1.21/src/client/java/com/example/docs/sound/instance/EngineSoundInstance.java new file mode 100644 index 000000000..0b3d49b9e --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/sound/instance/EngineSoundInstance.java @@ -0,0 +1,40 @@ +package com.example.docs.sound.instance; + +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; + +import com.example.docs.block.entity.custom.EngineBlockEntity; +import com.example.docs.sound.AbstractDynamicSoundInstance; +import com.example.docs.sound.DynamicSoundSource; + +// :::1 +public class EngineSoundInstance extends AbstractDynamicSoundInstance { + // Here we just use the default constructor parameters. + // If you want to specifically set values here already, + // you can clean up the constructor parameters a bit + public EngineSoundInstance(DynamicSoundSource soundSource, SoundEvent soundEvent, SoundCategory soundCategory, + int startTransitionTicks, int endTransitionTicks, float maxVolume, float minPitch, float maxPitch, + SoundInstanceCallback callback) { + super(soundSource, soundEvent, soundCategory, startTransitionTicks, endTransitionTicks, maxVolume, minPitch, maxPitch, callback); + } + + @Override + public void tick() { + // check conditions which set this sound automatically into the ending phase + if (soundSource instanceof EngineBlockEntity blockEntity && blockEntity.isRemoved()) { + this.end(); + } + + // apply the default tick behaviour from the parent class + super.tick(); + + // modulate volume and pitch of the SoundInstance + this.modulateSoundForTransition(); + this.modulateSoundForStress(); + } + + // you can also add sound modulation methods here, + // which should be only accessible to this + // specific SoundInstance +} +// :::1 diff --git a/reference/1.21/src/client/java/com/example/docs/sound/instance/SoundInstanceCallback.java b/reference/1.21/src/client/java/com/example/docs/sound/instance/SoundInstanceCallback.java new file mode 100644 index 000000000..94f1f204f --- /dev/null +++ b/reference/1.21/src/client/java/com/example/docs/sound/instance/SoundInstanceCallback.java @@ -0,0 +1,11 @@ +package com.example.docs.sound.instance; + +import com.example.docs.sound.AbstractDynamicSoundInstance; + +// :::1 +public interface SoundInstanceCallback { + // deliver the custom SoundInstance, from which this signal originates, + // using the method parameters + void onFinished(T soundInstance); +} +// :::1 diff --git a/reference/1.21/src/client/resources/fabric-docs-reference.client.mixins.json b/reference/1.21/src/client/resources/fabric-docs-reference.client.mixins.json new file mode 100644 index 000000000..55df3d8c6 --- /dev/null +++ b/reference/1.21/src/client/resources/fabric-docs-reference.client.mixins.json @@ -0,0 +1,9 @@ +{ + "required": true, + "package": "com.example.docs.mixin.client", + "compatibilityLevel": "JAVA_17", + "client": ["ExampleClientMixin", "TitleScreenMixin"], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/reference/1.21/src/main/generated/assets/fabric-docs-reference/lang/en_us.json b/reference/1.21/src/main/generated/assets/fabric-docs-reference/lang/en_us.json new file mode 100644 index 000000000..c4f66182f --- /dev/null +++ b/reference/1.21/src/main/generated/assets/fabric-docs-reference/lang/en_us.json @@ -0,0 +1,23 @@ +{ + "block.fabric-docs-reference.condensed_dirt": "Condensed Dirt", + "block.fabric-docs-reference.condensed_oak_log": "Condensed Oak Log", + "block.fabric-docs-reference.prismarine_lamp": "Prismarine Lamp", + "death.attack.tater": "%1$s died from Tater damage!", + "effect.fabric-docs-reference.tater": "Tater", + "enchantment.FabricDocsReference.thundering": "Thundering", + "item.fabric-docs-reference.counter": "Counter", + "item.fabric-docs-reference.counter.info": "Used %1$s times", + "item.fabric-docs-reference.guidite_boots": "Guidite Boots", + "item.fabric-docs-reference.guidite_chestplate": "Guidite Chestplate", + "item.fabric-docs-reference.guidite_helmet": "Guidite Helmet", + "item.fabric-docs-reference.guidite_leggings": "Guidite Leggings", + "item.fabric-docs-reference.guidite_sword": "Guidite Sword", + "item.fabric-docs-reference.lightning_stick": "Lightning Stick", + "item.fabric-docs-reference.poisonous_apple": "Poisonous Apple", + "item.fabric-docs-reference.suspicious_substance": "Suspicious Substance", + "item.minecraft.potion.effect.tater": "Tater Potion", + "itemGroup.fabric_docs_reference": "Fabric Docs Reference", + "itemTooltip.fabric-docs-reference.lightning_stick": "This is an extremely powerful weapon that can summon lightning bolts.", + "sound.fabric-docs-reference.metal_whistle": "Metal Whistle", + "text.fabric_docs_reference.greeting": "Hello there!" +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/building_blocks/dirt.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/building_blocks/dirt.json new file mode 100644 index 000000000..d6517a249 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/building_blocks/dirt.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_coarse_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:coarse_dirt" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:dirt" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_coarse_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:dirt" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_bread.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_bread.json new file mode 100644 index 000000000..ad6e340f2 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_bread.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_bread": { + "conditions": { + "items": [ + { + "items": "minecraft:bread" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:wheat_from_smelting_bread" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_bread" + ] + ], + "rewards": { + "recipes": [ + "minecraft:wheat_from_smelting_bread" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_cookie.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_cookie.json new file mode 100644 index 000000000..73bcae382 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_cookie.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_cookie": { + "conditions": { + "items": [ + { + "items": "minecraft:cookie" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:wheat_from_smelting_cookie" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_cookie" + ] + ], + "rewards": { + "recipes": [ + "minecraft:wheat_from_smelting_cookie" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_hay_block.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_hay_block.json new file mode 100644 index 000000000..473ad7323 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/food/wheat_from_smelting_hay_block.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_hay_block": { + "conditions": { + "items": [ + { + "items": "minecraft:hay_block" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:wheat_from_smelting_hay_block" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_hay_block" + ] + ], + "rewards": { + "recipes": [ + "minecraft:wheat_from_smelting_hay_block" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/misc/crafting_table.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/misc/crafting_table.json new file mode 100644 index 000000000..79c3af5ac --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/misc/crafting_table.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_crafting_table": { + "conditions": { + "items": [ + { + "items": "minecraft:crafting_table" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:crafting_table" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_crafting_table" + ] + ], + "rewards": { + "recipes": [ + "minecraft:crafting_table" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/misc/loom.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/misc/loom.json new file mode 100644 index 000000000..13671b4bc --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/misc/loom.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_loom": { + "conditions": { + "items": [ + { + "items": "minecraft:loom" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:loom" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_loom" + ] + ], + "rewards": { + "recipes": [ + "minecraft:loom" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/redstone/oak_door.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/redstone/oak_door.json new file mode 100644 index 000000000..5731beee6 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/recipes/redstone/oak_door.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_oak_button": { + "conditions": { + "items": [ + { + "items": "minecraft:oak_button" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:oak_door" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_oak_button" + ] + ], + "rewards": { + "recipes": [ + "minecraft:oak_door" + ] + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json new file mode 100644 index 000000000..e02cf9daa --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "tater", + "scaling": "when_caused_by_living_non_player" +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/enchantment/thundering.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/enchantment/thundering.json new file mode 100644 index 000000000..0a5f997c0 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/enchantment/thundering.json @@ -0,0 +1,36 @@ +{ + "anvil_cost": 5, + "description": { + "translate": "enchantment.fabric-docs-reference.thundering" + }, + "effects": { + "minecraft:post_attack": [ + { + "affected": "victim", + "effect": { + "type": "fabric-docs-reference:lightning_effect", + "amount": { + "type": "minecraft:linear", + "base": 0.4, + "per_level_above_first": 0.2 + } + }, + "enchanted": "attacker" + } + ] + }, + "max_cost": { + "base": 1, + "per_level_above_first": 15 + }, + "max_level": 3, + "min_cost": { + "base": 1, + "per_level_above_first": 10 + }, + "slots": [ + "hand" + ], + "supported_items": "#minecraft:enchantable/weapon", + "weight": 10 +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/condensed_dirt.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/condensed_dirt.json new file mode 100644 index 000000000..7e05f1665 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/condensed_dirt.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "fabric-docs-reference:condensed_dirt" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/condensed_oak_log.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/condensed_oak_log.json new file mode 100644 index 000000000..f55dc20d2 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/condensed_oak_log.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:oak_log" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 9.0, + "min": 7.0 + } + } + ] +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/prismarine_lamp.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/prismarine_lamp.json new file mode 100644 index 000000000..173c5f518 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/blocks/prismarine_lamp.json @@ -0,0 +1,32 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "fabric-docs-reference:prismarine_lamp" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/chests/test_loot.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/chests/test_loot.json new file mode 100644 index 000000000..690717efc --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/loot_table/chests/test_loot.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:chest", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 1.0, + "function": "minecraft:set_count" + } + ], + "name": "minecraft:diamond" + }, + { + "type": "minecraft:item", + "name": "minecraft:diamond_sword" + } + ], + "rolls": 2.0 + } + ] +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json new file mode 100644 index 000000000..a7712f67d --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "multi_bench", + "key": { + "l": { + "tag": "minecraft:logs" + } + }, + "pattern": [ + "ll", + "ll" + ], + "result": { + "count": 4, + "id": "minecraft:crafting_table" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/dirt.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/dirt.json new file mode 100644 index 000000000..e864fc682 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/dirt.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "ingredients": [ + { + "item": "minecraft:coarse_dirt" + } + ], + "result": { + "count": 1, + "id": "minecraft:dirt" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/loom.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/loom.json new file mode 100644 index 000000000..013eac197 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/loom.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "multi_bench", + "key": { + "l": { + "tag": "minecraft:logs" + }, + "w": { + "tag": "minecraft:wool" + } + }, + "pattern": [ + "ww", + "ll" + ], + "result": { + "count": 4, + "id": "minecraft:loom" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json new file mode 100644 index 000000000..477fcc1d4 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": { + "item": "minecraft:oak_button" + } + }, + "pattern": [ + "##", + "##", + "##" + ], + "result": { + "count": 3, + "id": "minecraft:oak_door" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json new file mode 100644 index 000000000..17017b6aa --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:smelting", + "category": "misc", + "cookingtime": 300, + "experience": 0.1, + "group": "food_to_wheat", + "ingredient": { + "item": "minecraft:bread" + }, + "result": { + "id": "minecraft:wheat" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json new file mode 100644 index 000000000..e87077791 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:smelting", + "category": "misc", + "cookingtime": 300, + "experience": 0.1, + "group": "food_to_wheat", + "ingredient": { + "item": "minecraft:cookie" + }, + "result": { + "id": "minecraft:wheat" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json new file mode 100644 index 000000000..2936c5d63 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:smelting", + "category": "misc", + "cookingtime": 300, + "experience": 0.1, + "group": "food_to_wheat", + "ingredient": { + "item": "minecraft:hay_block" + }, + "result": { + "id": "minecraft:wheat" + } +} \ No newline at end of file diff --git a/reference/1.21/src/main/generated/data/fabric-docs-reference/tags/item/smelly_items.json b/reference/1.21/src/main/generated/data/fabric-docs-reference/tags/item/smelly_items.json new file mode 100644 index 000000000..706e1c9c5 --- /dev/null +++ b/reference/1.21/src/main/generated/data/fabric-docs-reference/tags/item/smelly_items.json @@ -0,0 +1,13 @@ +{ + "replace": true, + "values": [ + "minecraft:slime_ball", + "minecraft:rotten_flesh", + { + "id": "#minecraft:dirt", + "required": false + }, + "minecraft:oak_planks", + "#minecraft:banners" + ] +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/apple_and_beef.json b/reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/apple_and_beef.json similarity index 100% rename from reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/apple_and_beef.json rename to reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/apple_and_beef.json diff --git a/reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool.json b/reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool.json similarity index 100% rename from reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool.json rename to reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool.json diff --git a/reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool_five_times.json b/reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool_five_times.json similarity index 100% rename from reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool_five_times.json rename to reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/break_block_with_tool_five_times.json diff --git a/reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/get_dirt.json b/reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/get_dirt.json similarity index 100% rename from reference/latest/src/main/generated/data/minecraft/advancement/fabric-docs-reference/get_dirt.json rename to reference/1.21/src/main/generated/data/minecraft/advancement/fabric-docs-reference/get_dirt.json diff --git a/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json b/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json new file mode 100644 index 000000000..986cfd310 --- /dev/null +++ b/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json @@ -0,0 +1,5 @@ +{ + "values": [ + "fabric-docs-reference:tater" + ] +} \ No newline at end of file diff --git a/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java b/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java new file mode 100644 index 000000000..60d387be5 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java @@ -0,0 +1,44 @@ +package com.example.docs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.particle.SimpleParticleType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes; + +//#entrypoint +public class FabricDocsReference implements ModInitializer { + // This logger is used to write text to the console and the log file. + // It is considered best practice to use your mod id as the logger's name. + // That way, it's clear which mod wrote info, warnings, and errors. + public static final String MOD_ID = "fabric-docs-reference"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + //#entrypoint + //#particle_register_main + // This DefaultParticleType gets called when you want to use your particle in code. + public static final SimpleParticleType SPARKLE_PARTICLE = FabricParticleTypes.simple(); + + //#particle_register_main + //#entrypoint + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + LOGGER.info("Hello Fabric world!"); + //#entrypoint + + //#particle_register_main + // Register our custom particle type in the mod initializer. + Registry.register(Registries.PARTICLE_TYPE, Identifier.of(MOD_ID, "sparkle_particle"), SPARKLE_PARTICLE); + //#particle_register_main + //#entrypoint + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/ModLootTables.java b/reference/1.21/src/main/java/com/example/docs/ModLootTables.java new file mode 100644 index 000000000..473492444 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/ModLootTables.java @@ -0,0 +1,12 @@ +package com.example.docs; + +import net.minecraft.loot.LootTable; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; + +// :::datagen-loot-tables:mod-loot-tables +public class ModLootTables { + public static RegistryKey TEST_CHEST_LOOT = RegistryKey.of(RegistryKeys.LOOT_TABLE, Identifier.of(FabricDocsReference.MOD_ID, "chests/test_loot")); +} +// :::datagen-loot-tables:mod-loot-tables diff --git a/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java b/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java new file mode 100644 index 000000000..1254a224f --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java @@ -0,0 +1,19 @@ +package com.example.docs; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffectInstance; + +import com.example.docs.effect.FabricDocsReferenceEffects; + +/** + * A static-first class, used solely to provide version-aware + * references to internal methods. + */ +public class ReferenceMethods { + public static void addTaterEffect(LivingEntity entity) { + // :::1 + var instance = new StatusEffectInstance(FabricDocsReferenceEffects.TATER, 5 * 20, 0, false, true, true); + entity.addStatusEffect(instance); + // :::1 + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java b/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java new file mode 100644 index 000000000..82da5d7af --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java @@ -0,0 +1,44 @@ +package com.example.docs.advancement; + +import java.util.HashMap; + +import net.minecraft.item.Item; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; + +// :::datagen-advancements:entrypoint +public class FabricDocsReferenceDatagenAdvancement implements ModInitializer { + @Override + public void onInitialize() { + // :::datagen-advancements:entrypoint + // :::datagen-advancements:call-init + ModCriteria.init(); + // :::datagen-advancements:call-init + // :::datagen-advancements:entrypoint + HashMap tools = new HashMap<>(); + + PlayerBlockBreakEvents.AFTER.register(((world, player, blockPos, blockState, blockEntity) -> { + if (player instanceof ServerPlayerEntity serverPlayer) { // Only triggers on the server side + Item item = player.getMainHandStack().getItem(); + + Integer usedCount = tools.getOrDefault(item, 0); + usedCount++; + tools.put(item, usedCount); + // :::datagen-advancements:entrypoint + // :::datagen-advancements:trigger-criterion + ModCriteria.USE_TOOL.trigger(serverPlayer); + // :::datagen-advancements:trigger-criterion + // :::datagen-advancements:trigger-new-criterion + ModCriteria.PARAMETERIZED_USE_TOOL.trigger(serverPlayer, usedCount); + // :::datagen-advancements:trigger-new-criterion + // :::datagen-advancements:entrypoint + + serverPlayer.sendMessage(Text.of("You've used \"" + item + "\" as a tool " + usedCount + " times!")); + } + })); + } +} +// :::datagen-advancements:entrypoint diff --git a/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java b/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java new file mode 100644 index 000000000..d72648e65 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java @@ -0,0 +1,25 @@ +package com.example.docs.advancement; + +import net.minecraft.advancement.criterion.Criteria; + +import com.example.docs.FabricDocsReference; + +// :::datagen-advancements:mod-criteria +public class ModCriteria { + // :::datagen-advancements:mod-criteria-init + // :::datagen-advancements:mod-criteria + public static final UseToolCriterion USE_TOOL = Criteria.register(FabricDocsReference.MOD_ID + "/use_tool", new UseToolCriterion()); + // :::datagen-advancements:mod-criteria + // :::datagen-advancements:new-mod-criteria + public static final ParameterizedUseToolCriterion PARAMETERIZED_USE_TOOL = Criteria.register(FabricDocsReference.MOD_ID + "/parameterized_use_tool", new ParameterizedUseToolCriterion()); + + // :::datagen-advancements:mod-criteria + // :::datagen-advancements:mod-criteria-init + public static void init() { + } + + // :::datagen-advancements:new-mod-criteria + // :::datagen-advancements:mod-criteria +} + +// :::datagen-advancements:mod-criteria diff --git a/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java b/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java new file mode 100644 index 000000000..638933430 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java @@ -0,0 +1,50 @@ +package com.example.docs.advancement; + +import java.util.Optional; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.server.network.ServerPlayerEntity; + +/** + * {@link UseToolCriterion} but with a parameter. Separated because there was no way to show the process to parameterize + * in just one class. + */ +public class ParameterizedUseToolCriterion extends AbstractCriterion { + // :::datagen-advancements:new-trigger + public void trigger(ServerPlayerEntity player, int totalTimes) { + trigger(player, conditions -> conditions.requirementsMet(totalTimes)); + } + + // :::datagen-advancements:new-trigger + + @Override + public Codec getConditionsCodec() { + return Conditions.CODEC; + } + + // :::datagen-advancements:new-parameter + public record Conditions(Optional playerPredicate, int requiredTimes) implements AbstractCriterion.Conditions { + // :::datagen-advancements:new-parameter + // :::datagen-advancements:new-codec + public static Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + LootContextPredicate.CODEC.optionalFieldOf("player").forGetter(Conditions::player), + Codec.INT.fieldOf("requiredTimes").forGetter(Conditions::requiredTimes) + ).apply(instance, Conditions::new)); + // :::datagen-advancements:new-parameter + @Override + public Optional player() { + return playerPredicate; + } + + // :::datagen-advancements:new-requirements-met + public boolean requirementsMet(int totalTimes) { + return totalTimes > requiredTimes; // AbstractCriterion#trigger helpfully checks the playerPredicate for us. + } + + // :::datagen-advancements:new-requirements-met + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java b/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java new file mode 100644 index 000000000..e1b0c56a3 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java @@ -0,0 +1,46 @@ +package com.example.docs.advancement; + +import java.util.Optional; + +import com.mojang.serialization.Codec; + +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.server.network.ServerPlayerEntity; + +// :::datagen-advancements:criterion-base +public class UseToolCriterion extends AbstractCriterion { + // :::datagen-advancements:criterion-base + // :::datagen-advancements:criterion-trigger + public void trigger(ServerPlayerEntity player) { + trigger(player, Conditions::requirementsMet); + } + + // :::datagen-advancements:criterion-trigger + // :::datagen-advancements:criterion-base + + @Override + public Codec getConditionsCodec() { + return Conditions.CODEC; + } + + public record Conditions(Optional playerPredicate) implements AbstractCriterion.Conditions { + public static Codec CODEC = LootContextPredicate.CODEC.optionalFieldOf("player") + .xmap(Conditions::new, Conditions::player).codec(); + + @Override + public Optional player() { + return playerPredicate; + } + + // :::datagen-advancements:criterion-base + // :::datagen-advancements:conditions-test + public boolean requirementsMet() { + return true; // AbstractCriterion#trigger helpfully checks the playerPredicate for us. + } + + // :::datagen-advancements:conditions-test + // :::datagen-advancements:criterion-base + } +} +// :::datagen-advancements:criterion-base diff --git a/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java b/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java new file mode 100644 index 000000000..9cec4e4ff --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java @@ -0,0 +1,12 @@ +package com.example.docs.block; + +import net.fabricmc.api.ModInitializer; + +// :::1 +public class FabricDocsReferenceBlocks implements ModInitializer { + @Override + public void onInitialize() { + ModBlocks.initialize(); + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java b/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java new file mode 100644 index 000000000..de1c61733 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java @@ -0,0 +1,91 @@ +package com.example.docs.block; + +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.block.PillarBlock; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; + +import com.example.docs.FabricDocsReference; +import com.example.docs.block.custom.CounterBlock; +import com.example.docs.block.custom.EngineBlock; +import com.example.docs.block.custom.PrismarineLampBlock; +import com.example.docs.item.ModItems; + +// :::1 +public class ModBlocks { + // :::1 + + // :::2 + public static final Block CONDENSED_DIRT = register( + new Block(AbstractBlock.Settings.create().sounds(BlockSoundGroup.GRASS)), + "condensed_dirt", + true + ); + // :::2 + // :::3 + public static final Block CONDENSED_OAK_LOG = register( + new PillarBlock( + AbstractBlock.Settings.create() + .sounds(BlockSoundGroup.WOOD) + ), "condensed_oak_log", true + ); + // :::3 + // :::4 + public static final Block PRISMARINE_LAMP = register( + new PrismarineLampBlock( + AbstractBlock.Settings.create() + .sounds(BlockSoundGroup.LANTERN) + .luminance(PrismarineLampBlock::getLuminance) + ), "prismarine_lamp", true + ); + // :::4 + public static final Block ENGINE_BLOCK = register( + new EngineBlock(AbstractBlock.Settings.create()), "engine", true + ); + + // :::5 + public static final Block COUNTER_BLOCK = register( + new CounterBlock(AbstractBlock.Settings.create()), "counter_block", true + ); + // :::5 + + // :::1 + public static Block register(Block block, String name, boolean shouldRegisterItem) { + // Register the block and its item. + Identifier id = Identifier.of(FabricDocsReference.MOD_ID, name); + + // Sometimes, you may not want to register an item for the block. + // Eg: if it's a technical block like `minecraft:air` or `minecraft:end_gateway` + if (shouldRegisterItem) { + BlockItem blockItem = new BlockItem(block, new Item.Settings()); + Registry.register(Registries.ITEM, id, blockItem); + } + + return Registry.register(Registries.BLOCK, id, block); + } + + // :::1 + public static void initialize() { + // :::3 + ItemGroupEvents.modifyEntriesEvent(ModItems.CUSTOM_ITEM_GROUP_KEY).register((itemGroup) -> { + itemGroup.add(ModBlocks.CONDENSED_DIRT.asItem()); + }); + // :::3 + + ItemGroupEvents.modifyEntriesEvent(ModItems.CUSTOM_ITEM_GROUP_KEY).register((itemGroup) -> { + itemGroup.add(ModBlocks.CONDENSED_OAK_LOG.asItem()); + itemGroup.add(ModBlocks.PRISMARINE_LAMP.asItem()); + itemGroup.add(ModBlocks.COUNTER_BLOCK.asItem()); + }); + } + + // :::1 +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java b/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java new file mode 100644 index 000000000..440d35a37 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java @@ -0,0 +1,72 @@ +package com.example.docs.block.custom; + +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.BlockWithEntity; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.example.docs.block.entity.ModBlockEntities; +import com.example.docs.block.entity.custom.CounterBlockEntity; + +// :::1 +public class CounterBlock extends BlockWithEntity { + public CounterBlock(Settings settings) { + super(settings); + } + + @Override + protected MapCodec getCodec() { + return createCodec(CounterBlock::new); + } + + @Override + protected BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + @Nullable + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new CounterBlockEntity(pos, state); + } + + // :::1 + + // :::2 + @Override + protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof CounterBlockEntity counterBlockEntity)) { + return super.onUse(state, world, pos, player, hit); + } + + counterBlockEntity.incrementClicks(); + player.sendMessage(Text.literal("You've clicked the block for the " + counterBlockEntity.getClicks() + "th time."), true); + + return ActionResult.SUCCESS; + } + + // :::2 + + // :::3 + @Nullable + @Override + public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + return validateTicker(type, ModBlockEntities.COUNTER_BLOCK_ENTITY, CounterBlockEntity::tick); + } + + // :::3 + + // :::1 +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/block/custom/EngineBlock.java b/reference/1.21/src/main/java/com/example/docs/block/custom/EngineBlock.java new file mode 100644 index 000000000..832779e18 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/custom/EngineBlock.java @@ -0,0 +1,86 @@ +package com.example.docs.block.custom; + +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.BlockWithEntity; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.registry.tag.ItemTags; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.ActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.example.docs.block.entity.ModBlockEntities; +import com.example.docs.block.entity.custom.EngineBlockEntity; + +public class EngineBlock extends BlockWithEntity { + public static final MapCodec CODEC = createCodec(EngineBlock::new); + + public EngineBlock(Settings settings) { + super(settings); + } + + @Override + protected MapCodec getCodec() { + return CODEC; + } + + @Nullable + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new EngineBlockEntity(pos, state); + } + + @Nullable + @Override + public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + return validateTicker(type, ModBlockEntities.ENGINE_BLOCK_ENTITY, EngineBlockEntity::tick); + } + + @Override + protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof EngineBlockEntity engineBlockEntity)) { + return super.onUse(state, world, pos, player, hit); + } + + if (player.getMainHandStack().isIn(ItemTags.COALS)) { + if (engineBlockEntity.setFuelIfPossible(engineBlockEntity.getFuel() + 40)) { + player.getMainHandStack().decrementUnlessCreative(1, player); + playSound(world, SoundEvents.ITEM_AXE_STRIP, pos); + return ActionResult.SUCCESS; + } + + return ActionResult.PASS; + } else { + if (engineBlockEntity.isRunning()) { + engineBlockEntity.setNormalizedStress(engineBlockEntity.getNormalizedStress() + 0.2f); + return ActionResult.SUCCESS; + } else if (engineBlockEntity.getFuel() > 0) { + playSound(world, SoundEvents.BLOCK_LEVER_CLICK, pos); + engineBlockEntity.turnOn(); + return ActionResult.SUCCESS; + } + } + + return ActionResult.PASS; + } + + @Override + protected BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + private static void playSound(World world, SoundEvent soundEvent, BlockPos pos) { + if (world.isClient()) return; + world.playSound(null, pos, soundEvent, SoundCategory.BLOCKS, 0.8f, 1f); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java b/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java new file mode 100644 index 000000000..7bd4cff2c --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java @@ -0,0 +1,69 @@ +package com.example.docs.block.custom; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.util.ActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +// :::1 +public class PrismarineLampBlock extends Block { + public static final BooleanProperty ACTIVATED = BooleanProperty.of("activated"); + + // :::1 + // :::3 + public PrismarineLampBlock(Settings settings) { + super(settings); + + // Set the default state of the block to be deactivated. + setDefaultState(getDefaultState().with(ACTIVATED, false)); + } + + // :::3 + // :::2 + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(ACTIVATED); + } + + // :::2 + // :::4 + @Override + protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { + if (!player.getAbilities().allowModifyWorld) { + // Skip if the player isn't allowed to modify the world. + return ActionResult.PASS; + } else { + // Get the current value of the "activated" property + boolean activated = state.get(ACTIVATED); + + // Flip the value of activated and save the new blockstate. + world.setBlockState(pos, state.with(ACTIVATED, !activated)); + + // Play a click sound to emphasise the interaction. + world.playSound(player, pos, SoundEvents.BLOCK_COMPARATOR_CLICK, SoundCategory.BLOCKS, 1.0F, 1.0F); + + return ActionResult.SUCCESS; + } + } + + // :::4 + // :::5 + public static int getLuminance(BlockState currentBlockState) { + // Get the value of the "activated" property. + boolean activated = currentBlockState.get(PrismarineLampBlock.ACTIVATED); + + // Return a light level if activated = true + return activated ? 15 : 0; + } + + // :::5 + // :::1 +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/block/entity/FabricDocsReferenceBlockEntities.java b/reference/1.21/src/main/java/com/example/docs/block/entity/FabricDocsReferenceBlockEntities.java new file mode 100644 index 000000000..53f62813d --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/entity/FabricDocsReferenceBlockEntities.java @@ -0,0 +1,10 @@ +package com.example.docs.block.entity; + +import net.fabricmc.api.ModInitializer; + +public class FabricDocsReferenceBlockEntities implements ModInitializer { + @Override + public void onInitialize() { + ModBlockEntities.initialize(); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java b/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java new file mode 100644 index 000000000..8d38b4289 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java @@ -0,0 +1,34 @@ +package com.example.docs.block.entity; + +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import com.example.docs.FabricDocsReference; +import com.example.docs.block.ModBlocks; +import com.example.docs.block.entity.custom.CounterBlockEntity; +import com.example.docs.block.entity.custom.EngineBlockEntity; + +public class ModBlockEntities { + public static final BlockEntityType ENGINE_BLOCK_ENTITY = + register("engine", EngineBlockEntity::new, ModBlocks.ENGINE_BLOCK); + + // :::1 + public static final BlockEntityType COUNTER_BLOCK_ENTITY = + register("counter", CounterBlockEntity::new, ModBlocks.COUNTER_BLOCK); + + private static BlockEntityType register(String name, + BlockEntityType.BlockEntityFactory entityFactory, + Block... blocks) { + Identifier id = Identifier.of(FabricDocsReference.MOD_ID, name); + return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, BlockEntityType.Builder.create(entityFactory, blocks).build()); + } + + // :::1 + + public static void initialize() { + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java b/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java new file mode 100644 index 000000000..856d0b185 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java @@ -0,0 +1,78 @@ +package com.example.docs.block.entity.custom; + +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.example.docs.block.entity.ModBlockEntities; + +// :::1 +public class CounterBlockEntity extends BlockEntity { + // :::1 + + // :::2 + private int clicks = 0; + // :::2 + + private int ticksSinceLast = 0; + + // :::1 + public CounterBlockEntity(BlockPos pos, BlockState state) { + super(ModBlockEntities.COUNTER_BLOCK_ENTITY, pos, state); + } + + // :::1 + + // :::2 + public int getClicks() { + return clicks; + } + + public void incrementClicks() { + // :::2 + + // :::6 + if (ticksSinceLast < 10) return; + ticksSinceLast = 0; + // :::6 + + // :::2 + clicks++; + markDirty(); + } + + // :::2 + + // :::3 + @Override + protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + nbt.putInt("clicks", clicks); + + super.writeNbt(nbt, registryLookup); + } + + // :::3 + + // :::4 + @Override + protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + super.readNbt(nbt, registryLookup); + + clicks = nbt.getInt("clicks"); + } + + // :::4 + + // :::5 + public static void tick(World world, BlockPos blockPos, BlockState blockState, CounterBlockEntity entity) { + entity.ticksSinceLast++; + } + + // :::5 + + // :::1 +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/block/entity/custom/EngineBlockEntity.java b/reference/1.21/src/main/java/com/example/docs/block/entity/custom/EngineBlockEntity.java new file mode 100644 index 000000000..b1ce936c4 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/block/entity/custom/EngineBlockEntity.java @@ -0,0 +1,133 @@ +package com.example.docs.block.entity.custom; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.listener.ClientPlayPacketListener; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; + +import com.example.docs.block.entity.ModBlockEntities; +import com.example.docs.networking.payload.EngineSoundInstancePacket; +import com.example.docs.sound.DynamicSoundSource; + +public class EngineBlockEntity extends BlockEntity implements DynamicSoundSource { + public static final int MAX_FUEL = 200; + private int tick = -1; // starts turned off + private int fuel = 0; + private float normalizedStress = 0; + + public EngineBlockEntity(BlockPos pos, BlockState state) { + super(ModBlockEntities.ENGINE_BLOCK_ENTITY, pos, state); + } + + public void setTick(int tick) { + this.tick = tick; + } + + @Override + public int getTick() { + return this.tick; + } + + public static void tick(World world, BlockPos pos, BlockState state, EngineBlockEntity engineBlockEntity) { + if (engineBlockEntity.getTick() < 0) return; + + engineBlockEntity.setTick(engineBlockEntity.getTick() + 1); + engineBlockEntity.setFuelIfPossible(engineBlockEntity.getFuel() - 1); + engineBlockEntity.setNormalizedStress(engineBlockEntity.getNormalizedStress() - 0.02f); + + if (!world.isClient() && engineBlockEntity.getFuel() > 0) { + PlayerLookup.tracking(engineBlockEntity).forEach(player -> { + String engineState = "Engine Fuel: %s | Stress: %s".formatted( + engineBlockEntity.getFuel(), + String.format("%.02f", engineBlockEntity.getNormalizedStress()) + ); + player.sendMessage(Text.literal(engineState), true); + }); + } + + if (engineBlockEntity.getFuel() <= 0) { + engineBlockEntity.turnOff(); + engineBlockEntity.setFuelIfPossible(0); + } + } + + @Override + public float getNormalizedStress() { + return MathHelper.clamp(normalizedStress, 0, 1); + } + + public void setNormalizedStress(float normalizedStress) { + this.normalizedStress = Math.clamp(normalizedStress, 0, 1); + } + + public int getFuel() { + return MathHelper.clamp(this.fuel, 0, MAX_FUEL); + } + + public boolean setFuelIfPossible(int fuel) { + boolean consumeItem = this.getFuel() != MAX_FUEL; + this.fuel = MathHelper.clamp(fuel, 0, MAX_FUEL); + return consumeItem; + } + + @Override + public Vec3d getPosition() { + return this.getPos().toCenterPos(); + } + + public void turnOn() { + if (this.getFuel() > 0) { + this.setTick(0); + this.setNormalizedStress(0); + this.sendPacketToTrackingClients(new EngineSoundInstancePacket(true, this.getPos())); + this.syncToChunk(); + } + } + + public void turnOff() { + this.tick = -1; + this.sendPacketToTrackingClients(new EngineSoundInstancePacket(false, this.getPos())); + this.syncToChunk(); + } + + public boolean isRunning() { + return this.getTick() > -1; + } + + public void sendPacketToTrackingClients(CustomPayload payload) { + if (payload == null || !(this.getWorld() instanceof ServerWorld)) return; + PlayerLookup.tracking(this).forEach(player -> ServerPlayNetworking.send(player, payload)); + } + + // S2C BlockEntity sync boilerplate + public void syncToChunk() { + if (!(getWorld() instanceof ServerWorld serverWorld)) return; + serverWorld.getChunkManager().markForUpdate(this.getPos()); + } + + @Nullable + @Override + public Packet toUpdatePacket() { + return BlockEntityUpdateS2CPacket.create(this); + } + + @Override + public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) { + return createNbt(registryLookup); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/codec/Bean.java b/reference/1.21/src/main/java/com/example/docs/codec/Bean.java new file mode 100644 index 000000000..8517df2db --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/codec/Bean.java @@ -0,0 +1,17 @@ +package com.example.docs.codec; + +import com.mojang.serialization.Codec; + +// ::: +// The abstract type we want to create a codec for +public interface Bean { + // Now we can create a codec for bean types based on the previously created registry. + Codec BEAN_CODEC = BeanType.REGISTRY.getCodec() + // And based on that, here's our registry dispatch codec for beans! + // The first argument is the field name for the bean type. + // When left out, it will default to "type". + .dispatch("type", Bean::getType, BeanType::codec); + + BeanType getType(); +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java b/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java new file mode 100644 index 000000000..da1e8ce25 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java @@ -0,0 +1,19 @@ +package com.example.docs.codec; + +import com.mojang.serialization.Lifecycle; +import com.mojang.serialization.MapCodec; + +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.SimpleRegistry; +import net.minecraft.util.Identifier; + +// ::: +// A record to keep information relating to a specific +// subclass of Bean, in this case only holding a Codec. +public record BeanType(MapCodec codec) { + // Create a registry to map identifiers to bean types + public static final Registry> REGISTRY = new SimpleRegistry<>( + RegistryKey.ofRegistry(Identifier.of("example", "bean_types")), Lifecycle.stable()); +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java b/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java new file mode 100644 index 000000000..62af651cb --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java @@ -0,0 +1,22 @@ +package com.example.docs.codec; + +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +// ::: +// An empty class to hold static references to all BeanTypes +public class BeanTypes { + // Make sure to register the bean types and leave them accessible to + // the getType method in their respective subclasses. + public static final BeanType STRINGY_BEAN = register("stringy_bean", new BeanType<>(StringyBean.CODEC)); + public static final BeanType COUNTING_BEAN = register("counting_bean", new BeanType<>(CountingBean.CODEC)); + + //::: + public static void register() { } + + //::: + public static BeanType register(String id, BeanType beanType) { + return Registry.register(BeanType.REGISTRY, Identifier.of("example", id), beanType); + } +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java b/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java new file mode 100644 index 000000000..785b9e2ad --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java @@ -0,0 +1,32 @@ +package com.example.docs.codec; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +// ::: +// Another implementation +public class CountingBean implements Bean { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.INT.fieldOf("counting_number").forGetter(CountingBean::getCountingNumber) + ).apply(instance, CountingBean::new)); + + private int countingNumber; + // ::: + + public CountingBean(int countingNumber) { + this.countingNumber = countingNumber; + } + + public int getCountingNumber() { + return countingNumber; + } + + // ::: + + @Override + public BeanType getType() { + return BeanTypes.COUNTING_BEAN; + } +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java b/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java new file mode 100644 index 000000000..e96ce5a9b --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java @@ -0,0 +1,34 @@ +package com.example.docs.codec; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +// ::: +// An implementing class of Bean, with its own codec. +public class StringyBean implements Bean { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.STRING.fieldOf("stringy_string").forGetter(StringyBean::getStringyString) + ).apply(instance, StringyBean::new)); + + private String stringyString; + // ::: + + public StringyBean(String stringyString) { + this.stringyString = stringyString; + } + + public String getStringyString() { + return stringyString; + } + + // ::: + + // It is important to be able to retrieve the + // BeanType of a Bean from it's instance. + @Override + public BeanType getType() { + return BeanTypes.STRINGY_BEAN; + } +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java b/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java new file mode 100644 index 000000000..bcf1b69a9 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java @@ -0,0 +1,40 @@ +package com.example.docs.command; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import net.minecraft.util.math.BlockPos; + +// :::1 +public class BlockPosArgumentType implements ArgumentType { + /** + * Parse the BlockPos from the reader in the {x, y, z} format. + */ + @Override + public BlockPos parse(StringReader reader) throws CommandSyntaxException { + try { + // This requires the argument to be surrounded by quotation marks. + // eg: "{1, 2, 3}" + String string = reader.readString(); + + // Remove the { and } from the string using regex. + string = string.replace("{", "").replace("}", ""); + + // Split the string into the x, y, and z values. + String[] split = string.split(","); + + // Parse the x, y, and z values from the split string. + int x = Integer.parseInt(split[0].trim()); + int y = Integer.parseInt(split[1].trim()); + int z = Integer.parseInt(split[2].trim()); + + // Return the BlockPos. + return new BlockPos(x, y, z); + } catch (Exception e) { + // Throw an exception if anything fails inside the try block. + throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException().create("Invalid BlockPos format. Expected {x, y, z}"); + } + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java b/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java new file mode 100644 index 000000000..4a168836b --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java @@ -0,0 +1,238 @@ +package com.example.docs.command; + +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import net.minecraft.command.argument.RegistryEntryReferenceArgumentType; +import net.minecraft.command.argument.serialize.ConstantArgumentSerializer; +import net.minecraft.command.suggestion.SuggestionProviders; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.command.v2.ArgumentTypeRegistry; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; + +// Class to contain all mod command registrations. +public class FabricDocsReferenceCommands implements ModInitializer { + // :::execute_dedicated_command + private static int executeDedicatedCommand(CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /dedicated_command."), false); + return 1; + } + + // :::execute_dedicated_command + // :::execute_required_command + private static int executeRequiredCommand(CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /required_command."), false); + return 1; + } + + // :::execute_required_command + // :::execute_sub_command_one + private static int executeSubCommandOne(CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /command sub_command_one."), false); + return 1; + } + + // :::execute_sub_command_one + // :::execute_command_sub_command_two + private static int executeCommandTwo(CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /command_two."), false); + return 1; + } + + private static int executeSubCommandTwo(CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /sub_command_two."), false); + return 1; + } + + // :::execute_command_sub_command_two + // :::execute_redirected_by + private static int executeRedirectedBy(CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /redirected_by."), false); + return 1; + } + + // :::execute_redirected_by + // :::execute_command_with_arg + private static int executeCommandWithArg(CommandContext context) { + int value = IntegerArgumentType.getInteger(context, "value"); + context.getSource().sendFeedback(() -> Text.literal("Called /command_with_arg with value = %s".formatted(value)), false); + return 1; + } + + // :::execute_command_with_arg + // :::execute_command_with_two_args + private static int executeWithOneArg(CommandContext context) { + int value1 = IntegerArgumentType.getInteger(context, "value_one"); + context.getSource().sendFeedback(() -> Text.literal("Called /command_with_two_args with value one = %s".formatted(value1)), false); + return 1; + } + + private static int executeWithTwoArgs(CommandContext context) { + int value1 = IntegerArgumentType.getInteger(context, "value_one"); + int value2 = IntegerArgumentType.getInteger(context, "value_two"); + context.getSource().sendFeedback(() -> Text.literal("Called /argtater2 with value one = %s and value two = %s".formatted(value1, value2)), + false); + return 1; + } + + // :::execute_command_with_two_args + // :::execute_common + private static int executeCommon(int value1, int value2, CommandContext context) { + context.getSource().sendFeedback(() -> Text.literal("Called /command_with_common_exec with value 1 = %s and value 2 = %s".formatted(value1, value2)), false); + return 1; + } + + // :::execute_common + // :::execute_custom_arg_command + private static int executeCustomArgCommand(CommandContext context) { + BlockPos arg = context.getArgument("block_pos", BlockPos.class); + context.getSource().sendFeedback(() -> Text.literal("Called /command_with_custom_arg with block pos = %s".formatted(arg)), false); + return 1; + } + + // :::execute_custom_arg_command + // :::execute_command_with_suggestions + private static int executeCommandWithSuggestions(CommandContext context) throws CommandSyntaxException { + var entityType = RegistryEntryReferenceArgumentType.getSummonableEntityType(context, "entity"); + context.getSource().sendFeedback(() -> Text.literal("Called /command_with_suggestions with entity = %s".formatted(entityType.value().getUntranslatedName())), false); + return 1; + } + + // :::execute_command_with_suggestions + // :::execute_command_with_custom_suggestions + private static int executeCommandWithCustomSuggestions(CommandContext context) { + String name = StringArgumentType.getString(context, "player_name"); + context.getSource().sendFeedback(() -> Text.literal("Called /command_with_custom_suggestions with value = %s".formatted(name)), false); + return 1; + } + + // :::execute_command_with_custom_suggestions + + @Override + public void onInitialize() { + // :::register_custom_arg + ArgumentTypeRegistry.registerArgumentType( + Identifier.of("fabric-docs", "block_pos"), + BlockPosArgumentType.class, + ConstantArgumentSerializer.of(BlockPosArgumentType::new) + ); + // :::register_custom_arg + + // :::test_command + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("test_command").executes(context -> { + context.getSource().sendFeedback(() -> Text.literal("Called /test_command."), false); + return 1; + })); + }); + // :::test_command + + // :::dedicated_command + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + if (environment.dedicated) { + dispatcher.register(CommandManager.literal("dedicated_command") + .executes(FabricDocsReferenceCommands::executeDedicatedCommand)); + } + }); + // :::dedicated_command + + // :::required_command + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("required_command") + .requires(source -> source.hasPermissionLevel(1)) + .executes(FabricDocsReferenceCommands::executeRequiredCommand)); + }); + // :::required_command + + // :::sub_command_one + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_one") + .then(CommandManager.literal("sub_command_one").executes(FabricDocsReferenceCommands::executeSubCommandOne))); + }); + // :::sub_command_one + + // :::sub_command_two + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_two") + .executes(FabricDocsReferenceCommands::executeCommandTwo) + .then(CommandManager.literal("sub_command_two").executes(FabricDocsReferenceCommands::executeSubCommandTwo))); + }); + // :::sub_command_two + + // :::redirect_command + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + var redirectedBy = dispatcher.register(CommandManager.literal("redirected_by").executes(FabricDocsReferenceCommands::executeRedirectedBy)); + dispatcher.register(CommandManager.literal("to_redirect").executes(FabricDocsReferenceCommands::executeRedirectedBy).redirect(redirectedBy)); + }); + // :::redirect_command + + // :::command_with_arg + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_with_arg") + .then(CommandManager.argument("value", IntegerArgumentType.integer()) + .executes(FabricDocsReferenceCommands::executeCommandWithArg))); + }); + // :::command_with_arg + + // :::command_with_two_args + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_with_two_args") + .then(CommandManager.argument("value_one", IntegerArgumentType.integer()) + .executes(FabricDocsReferenceCommands::executeWithOneArg) + .then(CommandManager.argument("value_two", IntegerArgumentType.integer()) + .executes(FabricDocsReferenceCommands::executeWithTwoArgs)))); + }); + // :::command_with_two_args + + // :::command_with_common_exec + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_with_common_exec") + .then(CommandManager.argument("value_one", IntegerArgumentType.integer()) + .executes(context -> executeCommon(IntegerArgumentType.getInteger(context, "value_one"), 0, context)) + .then(CommandManager.argument("value_two", IntegerArgumentType.integer()) + .executes(context -> executeCommon( + IntegerArgumentType.getInteger(context, "value_one"), + IntegerArgumentType.getInteger(context, "value_two"), + context))))); + }); + // :::command_with_common_exec + + // :::custom_arg_command + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_with_custom_arg").then( + CommandManager.argument("block_pos", new BlockPosArgumentType()) + .executes(FabricDocsReferenceCommands::executeCustomArgCommand) + )); + }); + // :::custom_arg_command + + // :::command_with_suggestions + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_with_suggestions").then( + CommandManager.argument("entity", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryKeys.ENTITY_TYPE)) + .suggests(SuggestionProviders.SUMMONABLE_ENTITIES) + .executes(FabricDocsReferenceCommands::executeCommandWithSuggestions) + )); + }); + // :::command_with_suggestions + + // :::command_with_custom_suggestions + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("command_with_custom_suggestions").then( + CommandManager.argument("player_name", StringArgumentType.string()) + .suggests(new PlayerSuggestionProvider()) + .executes(FabricDocsReferenceCommands::executeCommandWithCustomSuggestions) + )); + }); + // :::command_with_custom_suggestions + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java b/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java new file mode 100644 index 000000000..202871674 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java @@ -0,0 +1,32 @@ +package com.example.docs.command; + +import java.util.Collection; +import java.util.concurrent.CompletableFuture; + +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; + +import net.minecraft.server.command.ServerCommandSource; + +// :::1 +public class PlayerSuggestionProvider implements SuggestionProvider { + @Override + public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { + ServerCommandSource source = context.getSource(); + + // Thankfully, the ServerCommandSource has a method to get a list of player names. + Collection playerNames = source.getPlayerNames(); + + // Add all player names to the builder. + for (String playerName : playerNames) { + builder.suggest(playerName); + } + + // Lock the suggestions after we've modified them. + return builder.buildFuture(); + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/component/FabricDocsReferenceComponents.java b/reference/1.21/src/main/java/com/example/docs/component/FabricDocsReferenceComponents.java new file mode 100644 index 000000000..8d7710b04 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/component/FabricDocsReferenceComponents.java @@ -0,0 +1,10 @@ +package com.example.docs.component; + +import net.fabricmc.api.ModInitializer; + +public class FabricDocsReferenceComponents implements ModInitializer { + @Override + public void onInitialize() { + ModComponents.initialize(); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java b/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java new file mode 100644 index 000000000..74533629f --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java @@ -0,0 +1,39 @@ +package com.example.docs.component; + +import com.mojang.serialization.Codec; + +import net.minecraft.component.ComponentType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import com.example.docs.FabricDocsReference; + +//::1 +public class ModComponents { + //::1 + + //::2 + public static final ComponentType CLICK_COUNT_COMPONENT = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "click_count"), + ComponentType.builder().codec(Codec.INT).build() + ); + //::2 + + //::3 + public static final ComponentType MY_CUSTOM_COMPONENT = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "custom"), + ComponentType.builder().codec(MyCustomComponent.CODEC).build() + ); + //::3 + + //::1 + protected static void initialize() { + FabricDocsReference.LOGGER.info("Registering {} components", FabricDocsReference.MOD_ID); + // Technically this method can stay empty, but some developers like to notify + // the console, that certain parts of the mod have been successfully initialized + } +} +//::1 diff --git a/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java b/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java new file mode 100644 index 000000000..69fad856a --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java @@ -0,0 +1,19 @@ +package com.example.docs.component; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +//::1 +public record MyCustomComponent(float temperature, boolean burnt) { + //::1 + //::2 + public static final Codec CODEC = RecordCodecBuilder.create(builder -> { + return builder.group( + Codec.FLOAT.fieldOf("temperature").forGetter(MyCustomComponent::temperature), + Codec.BOOL.optionalFieldOf("burnt", false).forGetter(MyCustomComponent::burnt) + ).apply(builder, MyCustomComponent::new); + }); + //::2 + //::1 +} +//::1 diff --git a/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java b/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java new file mode 100644 index 000000000..b8c8d714b --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java @@ -0,0 +1,27 @@ +package com.example.docs.damage; + +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.entity.damage.DamageType; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ModInitializer; + +public class FabricDocsReferenceDamageTypes implements ModInitializer { + public static final Block TATER_BLOCK = new TaterBlock(AbstractBlock.Settings.create()); + // :::1 + public static final RegistryKey TATER_DAMAGE = RegistryKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of("fabric-docs-reference", "tater")); + // :::1 + + @Override + public void onInitialize() { + Registry.register(Registries.BLOCK, Identifier.of("fabric-docs-reference", "tater"), TATER_BLOCK); + Registry.register(Registries.ITEM, Identifier.of("fabric-docs-reference", "tater"), new BlockItem(TATER_BLOCK, new Item.Settings())); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java b/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java new file mode 100644 index 000000000..87e217764 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java @@ -0,0 +1,29 @@ +package com.example.docs.damage; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +// :::1 +public class TaterBlock extends Block { + public TaterBlock(Settings settings) { + super(settings); + } + + @Override + public void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity) { + if (entity instanceof LivingEntity) { + DamageSource damageSource = new DamageSource( + world.getRegistryManager() + .get(RegistryKeys.DAMAGE_TYPE) + .entryOf(FabricDocsReferenceDamageTypes.TATER_DAMAGE)); + entity.damage(damageSource, 5.0f); + } + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java b/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java new file mode 100644 index 000000000..61b9d319d --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java @@ -0,0 +1,24 @@ +package com.example.docs.effect; + +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ModInitializer; + +// :::1 +public class FabricDocsReferenceEffects implements ModInitializer { + public static final RegistryEntry TATER; + + static { + TATER = Registry.registerReference(Registries.STATUS_EFFECT, Identifier.of("fabric-docs-reference", "tater"), new TaterEffect()); + } + + @Override + public void onInitialize() { + // ... + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java b/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java new file mode 100644 index 000000000..eb0a705b5 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java @@ -0,0 +1,33 @@ +package com.example.docs.effect; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.entity.effect.StatusEffectCategory; +import net.minecraft.entity.player.PlayerEntity; + +// :::1 +public class TaterEffect extends StatusEffect { + protected TaterEffect() { + // category: StatusEffectCategory - describes if the effect is helpful (BENEFICIAL), harmful (HARMFUL) or useless (NEUTRAL) + // color: int - Color is the color assigned to the effect (in RGB) + super(StatusEffectCategory.BENEFICIAL, 0xe9b8b3); + } + + // Called every tick to check if the effect can be applied or not + @Override + public boolean canApplyUpdateEffect(int duration, int amplifier) { + // In our case, we just make it return true so that it applies the effect every tick + return true; + } + + // Called when the effect is applied. + @Override + public boolean applyUpdateEffect(LivingEntity entity, int amplifier) { + if (entity instanceof PlayerEntity) { + ((PlayerEntity) entity).addExperience(1 << amplifier); // Higher amplifier gives you experience faster + } + + return super.applyUpdateEffect(entity, amplifier); + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/enchantment/FabricDocsReferenceEnchantments.java b/reference/1.21/src/main/java/com/example/docs/enchantment/FabricDocsReferenceEnchantments.java new file mode 100644 index 000000000..58eae994b --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/enchantment/FabricDocsReferenceEnchantments.java @@ -0,0 +1,10 @@ +package com.example.docs.enchantment; + +import net.fabricmc.api.ModInitializer; + +public class FabricDocsReferenceEnchantments implements ModInitializer { + @Override + public void onInitialize() { + ModEnchantmentEffects.registerModEnchantmentEffects(); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/enchantment/ModEnchantmentEffects.java b/reference/1.21/src/main/java/com/example/docs/enchantment/ModEnchantmentEffects.java new file mode 100644 index 000000000..ecaa80563 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/enchantment/ModEnchantmentEffects.java @@ -0,0 +1,33 @@ +package com.example.docs.enchantment; + +import com.mojang.serialization.MapCodec; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.effect.EnchantmentEntityEffect; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; + +import com.example.docs.FabricDocsReference; +import com.example.docs.enchantment.effect.LightningEnchantmentEffect; + +//#entrypoint +public class ModEnchantmentEffects { + public static final RegistryKey THUNDERING = of("thundering"); + public static MapCodec LIGHTNING_EFFECT = register("lightning_effect", LightningEnchantmentEffect.CODEC); + + private static RegistryKey of(String path) { + Identifier id = Identifier.of(FabricDocsReference.MOD_ID, path); + return RegistryKey.of(RegistryKeys.ENCHANTMENT, id); + } + + private static MapCodec register(String id, MapCodec codec) { + return Registry.register(Registries.ENCHANTMENT_ENTITY_EFFECT_TYPE, Identifier.of(FabricDocsReference.MOD_ID, id), codec); + } + + public static void registerModEnchantmentEffects() { + FabricDocsReference.LOGGER.info("Registering EnchantmentEffects for" + FabricDocsReference.MOD_ID); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/enchantment/effect/LightningEnchantmentEffect.java b/reference/1.21/src/main/java/com/example/docs/enchantment/effect/LightningEnchantmentEffect.java new file mode 100644 index 000000000..a2b020223 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/enchantment/effect/LightningEnchantmentEffect.java @@ -0,0 +1,44 @@ +package com.example.docs.enchantment.effect; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.enchantment.EnchantmentEffectContext; +import net.minecraft.enchantment.EnchantmentLevelBasedValue; +import net.minecraft.enchantment.effect.EnchantmentEntityEffect; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.SpawnReason; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +//#entrypoint +public record LightningEnchantmentEffect(EnchantmentLevelBasedValue amount) implements EnchantmentEntityEffect { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + EnchantmentLevelBasedValue.CODEC.fieldOf("amount").forGetter(LightningEnchantmentEffect::amount) + ).apply(instance, LightningEnchantmentEffect::new) + ); + + @Override + public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) { + if (target instanceof LivingEntity victim) { + if (context.owner() != null && context.owner() instanceof PlayerEntity player) { + float numStrikes = this.amount.getValue(level); + + for (float i = 0; i < numStrikes; i++) { + BlockPos position = victim.getBlockPos(); + EntityType.LIGHTNING_BOLT.spawn(world, position, SpawnReason.TRIGGERED); + } + } + } + } + + @Override + public MapCodec getCodec() { + return CODEC; + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java b/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java new file mode 100644 index 000000000..150d6b616 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java @@ -0,0 +1,62 @@ +package com.example.docs.event; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.loot.LootPool; +import net.minecraft.loot.LootTable; +import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.util.ActionResult; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.player.AttackBlockCallback; +import net.fabricmc.fabric.api.loot.v3.LootTableEvents; + +// Class to contain all mod events. +public class FabricDocsReferenceEvents implements ModInitializer { + private static final RegistryKey COAL_ORE_LOOT_TABLE_ID = Blocks.COAL_ORE.getLootTableKey(); + + @Override + public void onInitialize() { + // :::1 + AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> { + BlockState state = world.getBlockState(pos); + + // Manual spectator check is necessary because AttackBlockCallbacks fire before the spectator check + if (!player.isSpectator() && player.getMainHandStack().isEmpty() && state.isToolRequired()) { + player.damage(world.getDamageSources().generic(), 1.0F); + } + + return ActionResult.PASS; + }); + // :::1 + + // :::2 + LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> { + // Let's only modify built-in loot tables and leave data pack loot tables untouched by checking the source. + // We also check that the loot table ID is equal to the ID we want. + if (source.isBuiltin() && COAL_ORE_LOOT_TABLE_ID.equals(key)) { + // We make the pool and add an item + LootPool.Builder poolBuilder = LootPool.builder().with(ItemEntry.builder(Items.EGG)); + tableBuilder.pool(poolBuilder); + } + }); + // :::2 + + // :::3 + SheepShearCallback.EVENT.register((player, sheep) -> { + sheep.setSheared(true); + + // Create diamond item entity at sheep's position. + ItemStack stack = new ItemStack(Items.DIAMOND); + ItemEntity itemEntity = new ItemEntity(player.getWorld(), sheep.getX(), sheep.getY(), sheep.getZ(), stack); + player.getWorld().spawnEntity(itemEntity); + + return ActionResult.FAIL; + }); + // :::3 + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java b/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java new file mode 100644 index 000000000..ea598bf31 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java @@ -0,0 +1,35 @@ +package com.example.docs.event; + +import net.minecraft.entity.passive.SheepEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.ActionResult; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +/** + * Callback for shearing a sheep. + * Called before the sheep is sheared, items are dropped, and items are damaged. + * Upon return: + * - SUCCESS cancels further processing and continues with normal shearing behavior. + * - PASS falls back to further processing and defaults to SUCCESS if no other listeners are available + * - FAIL cancels further processing and does not shear the sheep. + */ + +// ::: +public interface SheepShearCallback { + Event EVENT = EventFactory.createArrayBacked(SheepShearCallback.class, + (listeners) -> (player, sheep) -> { + for (SheepShearCallback listener : listeners) { + ActionResult result = listener.interact(player, sheep); + + if (result != ActionResult.PASS) { + return result; + } + } + + return ActionResult.PASS; + }); + + ActionResult interact(PlayerEntity player, SheepEntity sheep); +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java b/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java new file mode 100644 index 000000000..fc7222cb0 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java @@ -0,0 +1,19 @@ +package com.example.docs.item; + +import net.fabricmc.api.ModInitializer; + +import com.example.docs.item.armor.ModArmorMaterials; + +// :::1 +public class FabricDocsReferenceItems implements ModInitializer { + @Override + public void onInitialize() { + // :::1 + // :::2 + ModArmorMaterials.initialize(); + // :::2 + // :::1 + ModItems.initialize(); + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/item/ModItems.java b/reference/1.21/src/main/java/com/example/docs/item/ModItems.java new file mode 100644 index 000000000..928f1578e --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/item/ModItems.java @@ -0,0 +1,151 @@ +package com.example.docs.item; + +import net.minecraft.component.type.FoodComponent; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemGroups; +import net.minecraft.item.ItemStack; +import net.minecraft.item.SwordItem; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; +import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.fabricmc.fabric.api.registry.CompostingChanceRegistry; +import net.fabricmc.fabric.api.registry.FuelRegistry; + +import com.example.docs.FabricDocsReference; +import com.example.docs.component.ModComponents; +import com.example.docs.item.armor.ModArmorMaterials; +import com.example.docs.item.custom.CounterItem; +import com.example.docs.item.custom.LightningStick; +import com.example.docs.item.tool.GuiditeMaterial; + +// :::1 +public class ModItems { + // :::1 + + // :::6 + public static final Item GUIDITE_HELMET = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.HELMET, new Item.Settings().maxDamage(ArmorItem.Type.HELMET.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_helmet"); + public static final Item GUIDITE_CHESTPLATE = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.CHESTPLATE, new Item.Settings().maxDamage(ArmorItem.Type.CHESTPLATE.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_chestplate"); + public static final Item GUIDITE_LEGGINGS = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.LEGGINGS, new Item.Settings().maxDamage(ArmorItem.Type.LEGGINGS.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_leggings"); + public static final Item GUIDITE_BOOTS = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.BOOTS, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_boots"); + // :::6 + public static final Item LIGHTNING_STICK = register(new LightningStick(new Item.Settings()), "lightning_stick"); + // :::7 + public static final Item GUIDITE_SWORD = register(new SwordItem(GuiditeMaterial.INSTANCE, new Item.Settings()), "guidite_sword"); + // :::7 + // :::_13 + public static final Item COUNTER = register(new CounterItem( + // Initialize the click count component with a default value of 0 + new Item.Settings().component(ModComponents.CLICK_COUNT_COMPONENT, 0) + ), "counter"); + // :::_13 + // :::9 + public static final RegistryKey CUSTOM_ITEM_GROUP_KEY = RegistryKey.of(Registries.ITEM_GROUP.getKey(), Identifier.of(FabricDocsReference.MOD_ID, "item_group")); + public static final ItemGroup CUSTOM_ITEM_GROUP = FabricItemGroup.builder() + .icon(() -> new ItemStack(ModItems.GUIDITE_SWORD)) + .displayName(Text.translatable("itemGroup.fabric_docs_reference")) + .build(); + // :::9 + // :::5 + public static final FoodComponent POISON_FOOD_COMPONENT = new FoodComponent.Builder() + .alwaysEdible() + .snack() + // The duration is in ticks, 20 ticks = 1 second + .statusEffect(new StatusEffectInstance(StatusEffects.POISON, 6 * 20, 1), 1.0f) + .build(); + // :::5 + + // :::poisonous_apple + public static final Item POISONOUS_APPLE = register( + new Item(new Item.Settings().food(POISON_FOOD_COMPONENT)), + "poisonous_apple" + ); + // :::poisonous_apple + + // :::2 + public static final Item SUSPICIOUS_SUBSTANCE = register( + new Item(new Item.Settings()), + "suspicious_substance" + ); + // :::2 + + // :::1 + public static Item register(Item item, String id) { + // Create the identifier for the item. + Identifier itemID = Identifier.of(FabricDocsReference.MOD_ID, id); + + // Register the item. + Item registeredItem = Registry.register(Registries.ITEM, itemID, item); + + // Return the registered item! + return registeredItem; + } + + // :::1 + + // :::3 + public static void initialize() { + // :::3 + // :::4 + // Get the event for modifying entries in the ingredients group. + // And register an event handler that adds our suspicious item to the ingredients group. + ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS) + .register((itemGroup) -> itemGroup.add(ModItems.SUSPICIOUS_SUBSTANCE)); + // :::4 + + ItemGroupEvents.modifyEntriesEvent(ItemGroups.TOOLS) + .register((itemGroup) -> { + itemGroup.add(ModItems.GUIDITE_HELMET); + itemGroup.add(ModItems.GUIDITE_BOOTS); + itemGroup.add(ModItems.GUIDITE_LEGGINGS); + itemGroup.add(ModItems.GUIDITE_CHESTPLATE); + }); + + // :::8 + ItemGroupEvents.modifyEntriesEvent(ItemGroups.TOOLS) + .register((itemGroup) -> itemGroup.add(ModItems.GUIDITE_SWORD)); + // :::8 + + // :::_12 + // Register the group. + Registry.register(Registries.ITEM_GROUP, CUSTOM_ITEM_GROUP_KEY, CUSTOM_ITEM_GROUP); + + // Register items to the custom item group. + ItemGroupEvents.modifyEntriesEvent(CUSTOM_ITEM_GROUP_KEY).register(itemGroup -> { + itemGroup.add(ModItems.SUSPICIOUS_SUBSTANCE); + itemGroup.add(ModItems.POISONOUS_APPLE); + itemGroup.add(ModItems.GUIDITE_SWORD); + itemGroup.add(ModItems.GUIDITE_HELMET); + itemGroup.add(ModItems.GUIDITE_BOOTS); + itemGroup.add(ModItems.GUIDITE_LEGGINGS); + itemGroup.add(ModItems.GUIDITE_CHESTPLATE); + itemGroup.add(ModItems.LIGHTNING_STICK); + // ... + }); + // :::_12 + + // :::_10 + // Add the suspicious substance to the composting registry with a 30% chance of increasing the composter's level. + CompostingChanceRegistry.INSTANCE.add(ModItems.SUSPICIOUS_SUBSTANCE, 0.3f); + // :::_10 + + // :::_11 + // Add the suspicious substance to the registry of fuels, with a burn time of 30 seconds. + // Remember, Minecraft deals with logical based-time using ticks. + // 20 ticks = 1 second. + FuelRegistry.INSTANCE.add(ModItems.SUSPICIOUS_SUBSTANCE, 30 * 20); + // :::_11 + // :::3 + } + + // :::3 +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java b/reference/1.21/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java new file mode 100644 index 000000000..eb0ed42df --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java @@ -0,0 +1,97 @@ +//package com.example.docs.item.armor; +// +//import net.minecraft.item.ArmorItem; +//import net.minecraft.item.ArmorMaterial; +//import net.minecraft.recipe.Ingredient; +//import net.minecraft.sound.SoundEvent; +//import net.minecraft.sound.SoundEvents; +// +//import com.example.docs.item.ModItems; +// +//// :::1 +//public class GuiditeArmorMaterial implements ArmorMaterial { +// // ... +// //:::1 +// // :::_10 +// public static final GuiditeArmorMaterial INSTANCE = new GuiditeArmorMaterial(); +// +// // :::_10 +// // :::2 +// @Override +// public int getDurability(ArmorItem.Type type) { +// // Replace this multiplier by a constant value for the durability of the armor. +// // For reference, diamond uses 33 for all armor pieces, whilst leather uses 5. +// int DURABILITY_MULTIPLIER = 12; +// return switch (type) { +// case BOOTS -> 13 * DURABILITY_MULTIPLIER; +// case LEGGINGS -> 15 * DURABILITY_MULTIPLIER; +// case CHESTPLATE -> 16 * DURABILITY_MULTIPLIER; +// case HELMET -> 11 * DURABILITY_MULTIPLIER; +// default -> 0; +// }; +// } +// +// // :::2 +// // :::3 +// @Override +// public int getProtection(ArmorItem.Type type) { +// // Protection values for all the slots. +// // For reference, diamond uses 3 for boots, 6 for leggings, 8 for chestplate, and 3 for helmet, +// // whilst leather uses 1, 2, 3 and 1 respectively. +// return switch (type) { +// case BOOTS, HELMET -> 3; +// case LEGGINGS -> 6; +// case CHESTPLATE -> 8; +// default -> 0; +// }; +// } +// +// // :::3 +// // :::4 +// @Override +// public int getEnchantability() { +// return 5; +// } +// +// // :::4 +// // :::5 +// @Override +// public SoundEvent getEquipSound() { +// // Example for Iron Armor +// return SoundEvents.ITEM_ARMOR_EQUIP_IRON; +// } +// +// // :::5 +// // :::6 +// @Override +// public Ingredient getRepairIngredient() { +// return Ingredient.ofItems(ModItems.SUSPICIOUS_SUBSTANCE); +// } +// +// // :::6 +// // :::7 +// @Override +// public String getName() { +// return "guidite"; +// } +// +// // :::7 +// // :::8 +// @Override +// public float getToughness() { +// return 2.0F; +// } +// +// // :::8 +// // :::9 +// @Override +// public float getKnockbackResistance() { +// // We don't want knockback resistance for guidite armor, but if you do, +// // change this value to 0.XF, where X is the level of knockback resistance you want. +// return 0; +// } +// +// // :::9 +// // :::1 +//} +//// :::1 diff --git a/reference/latest/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java b/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java similarity index 100% rename from reference/latest/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java rename to reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java diff --git a/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java b/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java new file mode 100644 index 000000000..4bf333922 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java @@ -0,0 +1,58 @@ +package com.example.docs.item.custom; + +import java.util.List; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; + +import com.example.docs.component.ModComponents; + +//::1 +public class CounterItem extends Item { + public CounterItem(Settings settings) { + super(settings); + } + + //::1 + + @Override + //::2 + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + ItemStack stack = user.getStackInHand(hand); + + // Don't do anything on the client + if (world.isClient()) { + return TypedActionResult.success(stack); + } + + // Read the current count and increase it by one + int count = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); + stack.set(ModComponents.CLICK_COUNT_COMPONENT, ++count); + + // Return the original stack + return TypedActionResult.success(stack); + } + + //::2 + + @Override + //::3 + public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + if (stack.contains(ModComponents.CLICK_COUNT_COMPONENT)) { + int count = stack.get(ModComponents.CLICK_COUNT_COMPONENT); + tooltip.add(Text.translatable("item.fabric-docs-reference.counter.info", count).formatted(Formatting.GOLD)); + } + } + + //::3 + + //::1 +} +//::1 diff --git a/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java b/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java new file mode 100644 index 000000000..d786c1e93 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java @@ -0,0 +1,47 @@ +package com.example.docs.item.custom; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; + +public class CustomSoundItem extends Item { + public CustomSoundItem(Settings settings) { + super(settings); + } + + // :::1 + @Override + public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { + // As stated above, don't use the playSound() method on the client side + // ... it won't work! + if (!entity.getWorld().isClient()) { + // Play the sound as if it was coming from the entity. + entity.playSound(SoundEvents.ENTITY_PILLAGER_AMBIENT, 2f, 0.7f); + } + + return super.useOnEntity(stack, user, entity, hand); + } + + // :::1 + // :::2 + @Override + public ActionResult useOnBlock(ItemUsageContext context) { + if (!context.getWorld().isClient()) { + // Play the sound and specify location, category and who made the sound. + // No entity made the sound, so we specify null. + context.getWorld().playSound(null, context.getBlockPos(), + SoundEvents.BLOCK_COPPER_PLACE, SoundCategory.PLAYERS, + 1f, 1f); + } + + return super.useOnBlock(context); + } + + // :::2 +} diff --git a/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java b/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java new file mode 100644 index 000000000..c7477af01 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java @@ -0,0 +1,56 @@ +package com.example.docs.item.custom; + +import java.util.List; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LightningEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +// :::1 +public class LightningStick extends Item { + public LightningStick(Settings settings) { + super(settings); + } + + // :::1 + // :::2 + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + // Ensure we don't spawn the lightning only on the client. + // This is to prevent desync. + if (world.isClient) { + return TypedActionResult.pass(user.getStackInHand(hand)); + } + + BlockPos frontOfPlayer = user.getBlockPos().offset(user.getHorizontalFacing(), 10); + + // Spawn the lightning bolt. + LightningEntity lightningBolt = new LightningEntity(EntityType.LIGHTNING_BOLT, world); + lightningBolt.setPosition(frontOfPlayer.toCenterPos()); + world.spawnEntity(lightningBolt); + + // Nothing has changed to the item stack, + // so we just return it how it was. + return TypedActionResult.success(user.getStackInHand(hand)); + } + + // :::2 + // :::3 + @Override + public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + tooltip.add(Text.translatable("itemTooltip.fabric-docs-reference.lightning_stick").formatted(Formatting.GOLD)); + } + + // :::3 + // :::1 +} +// :::1 diff --git a/reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java b/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java similarity index 100% rename from reference/latest/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java rename to reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java diff --git a/reference/1.21/src/main/java/com/example/docs/mixin/ExampleMixin.java b/reference/1.21/src/main/java/com/example/docs/mixin/ExampleMixin.java new file mode 100644 index 000000000..3a385b0aa --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/mixin/ExampleMixin.java @@ -0,0 +1,16 @@ +package com.example.docs.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.server.MinecraftServer; + +@Mixin(MinecraftServer.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "loadWorld") + private void init(CallbackInfo info) { + // This code is injected into the start of MinecraftServer.loadWorld()V + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java b/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java new file mode 100644 index 000000000..60fa33213 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java @@ -0,0 +1,27 @@ +package com.example.docs.mixin.event; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.entity.passive.SheepEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; + +import com.example.docs.event.SheepShearCallback; + +// ::: +@Mixin(SheepEntity.class) +public class SheepEntityMixin { + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;sheared(Lnet/minecraft/sound/SoundCategory;)V"), method = "interactMob", cancellable = true) + private void onShear(final PlayerEntity player, final Hand hand, final CallbackInfoReturnable info) { + ActionResult result = SheepShearCallback.EVENT.invoker().interact(player, (SheepEntity) (Object) this); + + if (result == ActionResult.FAIL) { + info.setReturnValue(result); + } + } +} +// ::: diff --git a/reference/1.21/src/main/java/com/example/docs/networking/FabricDocsReferenceNetworking.java b/reference/1.21/src/main/java/com/example/docs/networking/FabricDocsReferenceNetworking.java new file mode 100644 index 000000000..eac2b8ad2 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/networking/FabricDocsReferenceNetworking.java @@ -0,0 +1,20 @@ +package com.example.docs.networking; + +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ModInitializer; + +import com.example.docs.FabricDocsReference; + +public class FabricDocsReferenceNetworking implements ModInitializer { + public static final String MOD_ID = FabricDocsReference.MOD_ID; + + @Override + public void onInitialize() { + NetworkPayloads.initialize(); + } + + public static Identifier getId(String input) { + return Identifier.of(MOD_ID, input); + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/networking/NetworkPayloads.java b/reference/1.21/src/main/java/com/example/docs/networking/NetworkPayloads.java new file mode 100644 index 000000000..3eec7d13c --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/networking/NetworkPayloads.java @@ -0,0 +1,27 @@ +package com.example.docs.networking; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; + +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; + +import com.example.docs.networking.payload.EngineSoundInstancePacket; + +@SuppressWarnings("SameParameterValue") +public class NetworkPayloads { + static { + registerS2C(EngineSoundInstancePacket.IDENTIFIER, EngineSoundInstancePacket.CODEC); + } + + private static void registerS2C(CustomPayload.Id packetIdentifier, PacketCodec codec) { + PayloadTypeRegistry.playS2C().register(packetIdentifier, codec); + } + + private static void registerC2S(CustomPayload.Id packetIdentifier, PacketCodec codec) { + PayloadTypeRegistry.playC2S().register(packetIdentifier, codec); + } + + public static void initialize() { + } +} diff --git a/reference/1.21/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java b/reference/1.21/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java new file mode 100644 index 000000000..25b3084ff --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java @@ -0,0 +1,25 @@ +package com.example.docs.networking.payload; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.math.BlockPos; + +import com.example.docs.sound.FabricDocsReferenceSounds; + +public record EngineSoundInstancePacket(boolean shouldStart, BlockPos blockEntityPos) implements CustomPayload { + public static final CustomPayload.Id IDENTIFIER = + new CustomPayload.Id<>(FabricDocsReferenceSounds.identifierOf("sound_instance")); + + @Override + public Id getId() { + return IDENTIFIER; + } + + public static final PacketCodec CODEC = PacketCodec.tuple( + PacketCodecs.BOOL, EngineSoundInstancePacket::shouldStart, + BlockPos.PACKET_CODEC, EngineSoundInstancePacket::blockEntityPos, + EngineSoundInstancePacket::new + ); +} diff --git a/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java b/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java new file mode 100644 index 000000000..3431e8596 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java @@ -0,0 +1,42 @@ +package com.example.docs.potion; + +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.item.Items; +import net.minecraft.potion.Potion; +import net.minecraft.potion.Potions; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.registry.FabricBrewingRecipeRegistryBuilder; + +import com.example.docs.effect.FabricDocsReferenceEffects; + +// :::1 +public class FabricDocsReferencePotions implements ModInitializer { + public static final Potion TATER_POTION = + Registry.register( + Registries.POTION, + Identifier.of("fabric-docs-reference", "tater"), + new Potion( + new StatusEffectInstance( + FabricDocsReferenceEffects.TATER, + 3600, + 0))); + + @Override + public void onInitialize() { + FabricBrewingRecipeRegistryBuilder.BUILD.register(builder -> { + builder.registerPotionRecipe( + // Input potion. + Potions.WATER, + // Ingredient + Items.POTATO, + // Output potion. + Registries.POTION.getEntry(TATER_POTION) + ); + }); + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java b/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java new file mode 100644 index 000000000..3e3e1a4c9 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java @@ -0,0 +1,33 @@ +package com.example.docs.sound; + +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.Identifier; + +// :::1 +public class CustomSounds { + private CustomSounds() { + // private empty constructor to avoid accidental instantiation + } + + // ITEM_METAL_WHISTLE is the name of the custom sound event + // and is called in the mod to use the custom sound + public static final SoundEvent ITEM_METAL_WHISTLE = registerSound("metal_whistle"); + public static final SoundEvent ENGINE_LOOP = registerSound("engine"); + + // actual registration of all the custom SoundEvents + private static SoundEvent registerSound(String id) { + Identifier identifier = Identifier.of(FabricDocsReferenceSounds.MOD_ID, id); + return Registry.register(Registries.SOUND_EVENT, identifier, SoundEvent.of(identifier)); + } + + // This static method starts class initialization, which then initializes + // the static class variables (e.g. ITEM_METAL_WHISTLE). + public static void initialize() { + FabricDocsReferenceSounds.LOGGER.info("Registering " + FabricDocsReferenceSounds.MOD_ID + " Sounds"); + // Technically this method can stay empty, but some developers like to notify + // the console, that certain parts of the mod have been successfully initialized + } +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/sound/DynamicSoundSource.java b/reference/1.21/src/main/java/com/example/docs/sound/DynamicSoundSource.java new file mode 100644 index 000000000..13fd9ee8e --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/sound/DynamicSoundSource.java @@ -0,0 +1,17 @@ +package com.example.docs.sound; + +import net.minecraft.util.math.Vec3d; + +// :::1 +public interface DynamicSoundSource { + // gets access to how many ticks have passed for e.g. a BlockEntity instance + int getTick(); + + // gets access to where currently this instance is placed in the world + Vec3d getPosition(); + + // holds a normalized (range of 0-1) value, showing how much stress this instance is currently experiencing + // It is more or less just an arbitrary value, which will cause the sound to change its pitch while playing. + float getNormalizedStress(); +} +// :::1 diff --git a/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java b/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java new file mode 100644 index 000000000..cfb84ee73 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java @@ -0,0 +1,34 @@ +package com.example.docs.sound; + +import org.slf4j.Logger; + +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ModInitializer; + +import com.example.docs.FabricDocsReference; + +// :::2 +public class FabricDocsReferenceSounds implements ModInitializer { + public static final String MOD_ID = FabricDocsReference.MOD_ID; + public static final Logger LOGGER = FabricDocsReference.LOGGER; + + @Override + public void onInitialize() { + // This is the basic registering. Use a new class for registering sounds + // instead, to keep the ModInitializer implementing class clean! + Registry.register(Registries.SOUND_EVENT, Identifier.of(MOD_ID, "metal_whistle_simple"), + SoundEvent.of(Identifier.of(MOD_ID, "metal_whistle_simple"))); + + // ... the cleaner approach. // [!code focus] + CustomSounds.initialize(); // [!code focus] + } + + public static Identifier identifierOf(String path) { + return Identifier.of(FabricDocsReference.MOD_ID, path); + } +} +// :::2 diff --git a/reference/1.21/src/main/java/com/example/docs/sound/TransitionState.java b/reference/1.21/src/main/java/com/example/docs/sound/TransitionState.java new file mode 100644 index 000000000..4cf6686c9 --- /dev/null +++ b/reference/1.21/src/main/java/com/example/docs/sound/TransitionState.java @@ -0,0 +1,23 @@ +package com.example.docs.sound; + +import net.minecraft.util.Identifier; + +import com.example.docs.FabricDocsReference; + +// :::1 +public enum TransitionState { + STARTING("starting_phase"), + RUNNING("idle_phase"), + ENDING("ending_phase"); + + private final Identifier identifier; + + TransitionState(String name) { + this.identifier = Identifier.of(FabricDocsReference.MOD_ID, name); + } + + public Identifier getIdentifier() { + return identifier; + } +} +// :::1 diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/counter_block.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/counter_block.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/counter_block.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/counter_block.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/tater.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/tater.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/blockstates/tater.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/tater.json diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/icon.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/icon.png new file mode 100644 index 000000000..047b91f23 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/icon.png differ diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/counter_block.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/counter_block.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/counter_block.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/counter_block.json diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/prismarine_lamp.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/prismarine_lamp.json new file mode 100644 index 000000000..1c1d9b017 --- /dev/null +++ b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/prismarine_lamp.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "fabric-docs-reference:block/prismarine_lamp" + } +} diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/prismarine_lamp_on.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/prismarine_lamp_on.json new file mode 100644 index 000000000..267bd3ca5 --- /dev/null +++ b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/prismarine_lamp_on.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "fabric-docs-reference:block/prismarine_lamp_on" + } +} diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/tater.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/tater.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/block/tater.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/tater.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/condensed_oak_log.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_oak_log.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/condensed_oak_log.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_oak_log.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/counter.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/counter.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/counter.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/counter.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/counter_block.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/counter_block.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/counter_block.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/counter_block.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_boots.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_boots.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_boots.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_boots.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_chestplate.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_chestplate.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_chestplate.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_chestplate.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_leggings.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_leggings.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_leggings.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_leggings.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/lightning_stick.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/lightning_stick.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/lightning_stick.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/lightning_stick.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/poisonous_apple.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/poisonous_apple.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/poisonous_apple.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/poisonous_apple.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/prismarine_lamp.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/prismarine_lamp.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/prismarine_lamp.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/prismarine_lamp.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/tater.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/tater.json similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/models/item/tater.json rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/tater.json diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json new file mode 100644 index 000000000..bab11ba59 --- /dev/null +++ b/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json @@ -0,0 +1,3 @@ +{ + "textures": ["fabric-docs-reference:sparkle_particle_texture"] +} diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json b/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json new file mode 100644 index 000000000..79ca29285 --- /dev/null +++ b/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json @@ -0,0 +1,14 @@ +{ + "metal_whistle": { + "subtitle": "sound.fabric-docs-reference.metal_whistle", + "sounds": [ + "fabric-docs-reference:metal_whistle" + ] + }, + "engine": { + "subtitle": "sound.fabric-docs-reference.engine", + "sounds": [ + "fabric-docs-reference:engine" + ] + } +} diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds/engine.ogg b/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds/engine.ogg new file mode 100644 index 000000000..ccf2bf931 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds/engine.ogg differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds/metal_whistle.ogg b/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds/metal_whistle.ogg new file mode 100644 index 000000000..1d57897cb Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds/metal_whistle.ogg differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_oak_log.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_oak_log.png new file mode 100644 index 000000000..038c0380f Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_oak_log.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_oak_log_top.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_oak_log_top.png new file mode 100644 index 000000000..80a4fb02b Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_oak_log_top.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/counter_block.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/counter_block.png new file mode 100644 index 000000000..5d1ed0de5 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/counter_block.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/prismarine_lamp.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/prismarine_lamp.png new file mode 100644 index 000000000..249cd6cee Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/prismarine_lamp.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/prismarine_lamp_on.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/prismarine_lamp_on.png new file mode 100644 index 000000000..870fe9052 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/prismarine_lamp_on.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/tater.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/tater.png new file mode 100644 index 000000000..37fc5de37 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/block/tater.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/gui/test-uv-drawing.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/gui/test-uv-drawing.png new file mode 100644 index 000000000..8d1604a38 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/gui/test-uv-drawing.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_boots.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_boots.png new file mode 100644 index 000000000..b6092f234 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_boots.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_chestplate.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_chestplate.png new file mode 100644 index 000000000..996534bfd Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_chestplate.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_helmet.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_helmet.png new file mode 100644 index 000000000..e0c6582db Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_helmet.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_leggings.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_leggings.png new file mode 100644 index 000000000..4d37c8da9 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_leggings.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_sword.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_sword.png new file mode 100644 index 000000000..fcaeb83d6 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/guidite_sword.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/poisonous_apple.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/poisonous_apple.png new file mode 100644 index 000000000..2da937261 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/poisonous_apple.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/suspicious_substance.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/suspicious_substance.png new file mode 100644 index 000000000..9575ebbc9 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/item/suspicious_substance.png differ diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/mob_effect/tater.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/mob_effect/tater.png new file mode 100644 index 000000000..511a7bc68 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/mob_effect/tater.png differ diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_1.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_1.png similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_1.png rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_1.png diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_2.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_2.png similarity index 100% rename from reference/latest/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_2.png rename to reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/models/armor/guidite_layer_2.png diff --git a/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/particle/sparkle_particle_texture.png b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/particle/sparkle_particle_texture.png new file mode 100644 index 000000000..b72786571 Binary files /dev/null and b/reference/1.21/src/main/resources/assets/fabric-docs-reference/textures/particle/sparkle_particle_texture.png differ diff --git a/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json b/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json new file mode 100644 index 000000000..8ebda993d --- /dev/null +++ b/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "fabric-docs-reference:condensed_dirt" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} diff --git a/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json b/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json new file mode 100644 index 000000000..8d7268f3e --- /dev/null +++ b/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json @@ -0,0 +1,4 @@ +{ + "replace": false, + "values": ["fabric-docs-reference:condensed_dirt"] +} diff --git a/reference/1.21/src/main/resources/fabric-docs-reference.mixins.json b/reference/1.21/src/main/resources/fabric-docs-reference.mixins.json new file mode 100644 index 000000000..87806775b --- /dev/null +++ b/reference/1.21/src/main/resources/fabric-docs-reference.mixins.json @@ -0,0 +1,9 @@ +{ + "required": true, + "package": "com.example.docs.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": ["ExampleMixin", "event.SheepEntityMixin"], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/reference/1.21/src/main/resources/fabric.mod.json b/reference/1.21/src/main/resources/fabric.mod.json new file mode 100644 index 000000000..ca1657485 --- /dev/null +++ b/reference/1.21/src/main/resources/fabric.mod.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "id": "fabric-docs-reference", + "version": "1.0.0", + "name": "Fabric docs reference", + "icon": "assets/fabric-docs-reference/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "com.example.docs.FabricDocsReference", + "com.example.docs.event.FabricDocsReferenceEvents", + "com.example.docs.command.FabricDocsReferenceCommands", + "com.example.docs.effect.FabricDocsReferenceEffects", + "com.example.docs.potion.FabricDocsReferencePotions", + "com.example.docs.sound.FabricDocsReferenceSounds", + "com.example.docs.damage.FabricDocsReferenceDamageTypes", + "com.example.docs.item.FabricDocsReferenceItems", + "com.example.docs.enchantment.FabricDocsReferenceEnchantments", + "com.example.docs.block.FabricDocsReferenceBlocks", + "com.example.docs.block.entity.FabricDocsReferenceBlockEntities", + "com.example.docs.component.FabricDocsReferenceComponents", + "com.example.docs.advancement.FabricDocsReferenceDatagenAdvancement", + "com.example.docs.networking.FabricDocsReferenceNetworking" + ], + "client": [ + "com.example.docs.FabricDocsReferenceClient", + "com.example.docs.client.command.FabricDocsReferenceClientCommands", + "com.example.docs.FabricDocsDynamicSound", + "com.example.docs.FabricDocsBlockEntityRenderer" + ], + "fabric-datagen": [ + "com.example.docs.datagen.FabricDocsReferenceDataGenerator" + ] + }, + "mixins": [ + "fabric-docs-reference.mixins.json", + { + "config": "fabric-docs-reference.client.mixins.json", + "environment": "client" + } + ], + "depends": {} +} diff --git a/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java b/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java new file mode 100644 index 000000000..5a7d46170 --- /dev/null +++ b/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java @@ -0,0 +1,81 @@ +package com.example.docs.codec; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.mojang.serialization.JsonOps; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import net.minecraft.Bootstrap; +import net.minecraft.SharedConstants; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +// :::automatic-testing:4 +public class BeanTypeTest { + private static final Gson GSON = new GsonBuilder().create(); + + @BeforeAll + static void beforeAll() { + // :::automatic-testing:4 + // :::automatic-testing:7 + SharedConstants.createGameVersion(); + Bootstrap.initialize(); + // :::automatic-testing:7 + // :::automatic-testing:4 + BeanTypes.register(); + } + + @Test + void testBeanCodec() { + StringyBean expectedBean = new StringyBean("This bean is stringy!"); + Bean actualBean = Bean.BEAN_CODEC.parse(JsonOps.INSTANCE, GSON.fromJson("{\"type\":\"example:stringy_bean\",\"stringy_string\":\"This bean is stringy!\"}", JsonObject.class)).getOrThrow(); + + Assertions.assertInstanceOf(StringyBean.class, actualBean); + Assertions.assertEquals(expectedBean.getType(), actualBean.getType()); + Assertions.assertEquals(expectedBean.getStringyString(), ((StringyBean) actualBean).getStringyString()); + } + + @Test + void testDiamondItemStack() { + // I know this isn't related to beans, but I need an example :) + ItemStack diamondStack = new ItemStack(Items.DIAMOND, 65); + + Assertions.assertTrue(diamondStack.isOf(Items.DIAMOND)); + Assertions.assertEquals(65, diamondStack.getCount()); + } +} +// :::automatic-testing:4 + +/* +// :::automatic-testing:5 +java.lang.ExceptionInInitializerError + at net.minecraft.item.ItemStack.(ItemStack.java:94) + at com.example.docs.codec.BeanTypeTest.testBeanCodec(BeanTypeTest.java:20) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) +Caused by: java.lang.IllegalArgumentException: Not bootstrapped (called from registry ResourceKey[minecraft:root / minecraft:game_event]) + at net.minecraft.Bootstrap.createNotBootstrappedException(Bootstrap.java:118) + at net.minecraft.Bootstrap.ensureBootstrapped(Bootstrap.java:111) + at net.minecraft.registry.Registries.create(Registries.java:238) + at net.minecraft.registry.Registries.create(Registries.java:229) + at net.minecraft.registry.Registries.(Registries.java:139) + ... 5 more + +Not bootstrapped (called from registry ResourceKey[minecraft:root / minecraft:game_event]) +java.lang.IllegalArgumentException: Not bootstrapped (called from registry ResourceKey[minecraft:root / minecraft:game_event]) + at net.minecraft.Bootstrap.createNotBootstrappedException(Bootstrap.java:118) + at net.minecraft.Bootstrap.ensureBootstrapped(Bootstrap.java:111) + at net.minecraft.registry.Registries.create(Registries.java:238) + at net.minecraft.registry.Registries.create(Registries.java:229) + at net.minecraft.registry.Registries.(Registries.java:139) + at net.minecraft.item.ItemStack.(ItemStack.java:94) + at com.example.docs.codec.BeanTypeTest.testBeanCodec(BeanTypeTest.java:20) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) +// :::automatic-testing:5 + */ diff --git a/reference/gradle.properties b/reference/gradle.properties index cafa20b46..ccc1363e3 100644 --- a/reference/gradle.properties +++ b/reference/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx1G org.gradle.parallel=true -loader_version=0.16.8 \ No newline at end of file +loader_version=0.16.9 \ No newline at end of file diff --git a/reference/latest/build.gradle b/reference/latest/build.gradle index 94a88fcb6..dcfaa58cc 100644 --- a/reference/latest/build.gradle +++ b/reference/latest/build.gradle @@ -1,6 +1,6 @@ -def minecraftVersion = "1.21" -def yarnVersion = "1.21+build.7" -def fabricApiVersion = "0.102.0+1.21" +def minecraftVersion = "1.21.4" +def yarnVersion = "1.21.4+build.4" +def fabricApiVersion = "0.114.0+1.21.4" dependencies { minecraft "com.mojang:minecraft:${minecraftVersion}" diff --git a/reference/latest/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java b/reference/latest/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java index 8232ec86b..c81da067b 100644 --- a/reference/latest/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java +++ b/reference/latest/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java @@ -31,7 +31,7 @@ protected void configure(RegistryWrapper.WrapperLookup registries, Entries entri // Our new enchantment, "Thundering." register(entries, ModEnchantmentEffects.THUNDERING, Enchantment.builder( Enchantment.definition( - registries.getWrapperOrThrow(RegistryKeys.ITEM).getOrThrow(ItemTags.WEAPON_ENCHANTABLE), + registries.getOrThrow(RegistryKeys.ITEM).getOrThrow(ItemTags.WEAPON_ENCHANTABLE), // this is the "weight" or probability of our enchantment showing up in the table 10, // the maximum level of the enchantment diff --git a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java index 784d4fabd..49e40671f 100644 --- a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java +++ b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java @@ -9,7 +9,9 @@ import net.minecraft.advancement.AdvancementFrame; import net.minecraft.advancement.criterion.ConsumeItemCriterion; import net.minecraft.advancement.criterion.InventoryChangedCriterion; +import net.minecraft.item.Item; import net.minecraft.item.Items; +import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryWrapper; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -46,9 +48,10 @@ public void generateAdvancement(RegistryWrapper.WrapperLookup wrapperLookup, Con // "got_dirt" is the name referenced by other advancements when they want to have "requirements." .criterion("got_dirt", InventoryChangedCriterion.Conditions.items(Items.DIRT)) // Give the advancement an id - .build(consumer, FabricDocsReference.MOD_ID + "/get_dirt"); + .build(consumer, FabricDocsReference.MOD_ID + ":get_dirt"); // :::datagen-advancements:simple-advancement // :::datagen-advancements:second-advancement + final RegistryWrapper.Impl itemLookup = wrapperLookup.getOrThrow(RegistryKeys.ITEM); AdvancementEntry appleAndBeef = Advancement.Builder.create() .parent(getDirt) .display( @@ -61,9 +64,9 @@ public void generateAdvancement(RegistryWrapper.WrapperLookup wrapperLookup, Con true, false ) - .criterion("ate_apple", ConsumeItemCriterion.Conditions.item(Items.APPLE)) - .criterion("ate_cooked_beef", ConsumeItemCriterion.Conditions.item(Items.COOKED_BEEF)) - .build(consumer, FabricDocsReference.MOD_ID + "/apple_and_beef"); + .criterion("ate_apple", ConsumeItemCriterion.Conditions.item(wrapperLookup.getOrThrow(RegistryKeys.ITEM), Items.APPLE)) + .criterion("ate_cooked_beef", ConsumeItemCriterion.Conditions.item(itemLookup, Items.COOKED_BEEF)) + .build(consumer, FabricDocsReference.MOD_ID + ":apple_and_beef"); // :::datagen-advancements:second-advancement // :::datagen-advancements:custom-criteria-advancement AdvancementEntry breakBlockWithTool = Advancement.Builder.create() @@ -79,7 +82,7 @@ public void generateAdvancement(RegistryWrapper.WrapperLookup wrapperLookup, Con false ) .criterion("break_block_with_tool", ModCriteria.USE_TOOL.create(new UseToolCriterion.Conditions(Optional.empty()))) - .build(consumer, FabricDocsReference.MOD_ID + "/break_block_with_tool"); + .build(consumer, FabricDocsReference.MOD_ID + ":break_block_with_tool"); // :::datagen-advancements:custom-criteria-advancement // :::datagen-advancements:new-custom-criteria-advancement AdvancementEntry breakBlockWithToolFiveTimes = Advancement.Builder.create() @@ -95,7 +98,7 @@ public void generateAdvancement(RegistryWrapper.WrapperLookup wrapperLookup, Con false ) .criterion("break_block_with_tool_five_times", ModCriteria.PARAMETERIZED_USE_TOOL.create(new ParameterizedUseToolCriterion.Conditions(Optional.empty(), 5))) - .build(consumer, FabricDocsReference.MOD_ID + "/break_block_with_tool_five_times"); + .build(consumer, FabricDocsReference.MOD_ID + ":break_block_with_tool_five_times"); // :::datagen-advancements:new-custom-criteria-advancement // :::datagen-advancements:provider-start } diff --git a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java index ad940193f..d92bb3c3f 100644 --- a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java +++ b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java @@ -9,6 +9,7 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import com.example.docs.damage.FabricDocsReferenceDamageTypes; +import com.example.docs.datagen.internal.FabricDocsReferenceInternalModelProvider; // :::datagen-setup:generator public class FabricDocsReferenceDataGenerator implements DataGeneratorEntrypoint { @@ -35,6 +36,8 @@ public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { pack.addProvider(FabricDocsReferenceDamageTypesProvider.TaterDamageTypesGenerator::new); pack.addProvider(FabricDocsReferenceDamageTypesProvider.TaterDamageTypeTagGenerator::new); + pack.addProvider(FabricDocsReferenceInternalModelProvider::new); + // :::datagen-setup:generator } diff --git a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java index fdd422d2c..96c72ffb6 100644 --- a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java +++ b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java @@ -9,6 +9,7 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider; +import com.example.docs.block.ModBlocks; import com.example.docs.item.ModItems; // :::datagen-translations:provider @@ -44,10 +45,18 @@ public void generateTranslations(RegistryWrapper.WrapperLookup wrapperLookup, Tr translationBuilder.add("item.fabric-docs-reference.counter.info", "Used %1$s times"); translationBuilder.add("itemTooltip.fabric-docs-reference.lightning_stick", "This is an extremely powerful weapon that can summon lightning bolts."); translationBuilder.add("itemGroup.fabric_docs_reference", "Fabric Docs Reference"); - translationBuilder.add("block.fabric-docs-reference.condensed_dirt", "Condensed Dirt"); - translationBuilder.add("block.fabric-docs-reference.condensed_oak_log", "Condensed Oak Log"); - translationBuilder.add("block.fabric-docs-reference.prismarine_lamp", "Prismarine Lamp"); - translationBuilder.add("enchantment.FabricDocsReference.thundering", "Thundering"); + translationBuilder.add("enchantment.fabric-docs-reference.thundering", "Thundering"); + + translationBuilder.add(ModBlocks.CONDENSED_DIRT, "Condensed Dirt"); + translationBuilder.add(ModBlocks.CONDENSED_OAK_LOG, "Condensed Oak Log"); + translationBuilder.add(ModBlocks.COUNTER_BLOCK, "Counter Block"); + translationBuilder.add(ModBlocks.PRISMARINE_LAMP, "Prismarine Lamp"); + translationBuilder.add(ModBlocks.ENGINE_BLOCK, "Engine Block"); + translationBuilder.add(ModBlocks.CONDENSED_DIRT.asItem(), "Condensed Dirt"); + translationBuilder.add(ModBlocks.CONDENSED_OAK_LOG.asItem(), "Condensed Oak Log"); + translationBuilder.add(ModBlocks.COUNTER_BLOCK.asItem(), "Counter Block"); + translationBuilder.add(ModBlocks.PRISMARINE_LAMP.asItem(), "Prismarine Lamp"); + translationBuilder.add(ModBlocks.ENGINE_BLOCK.asItem(), "Engine Block"); // :::datagen-translations:provider } } diff --git a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java index 72ab5493e..0e5256115 100644 --- a/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java +++ b/reference/latest/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java @@ -4,12 +4,13 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import net.minecraft.data.server.recipe.RecipeExporter; -import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; -import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.data.recipe.RecipeExporter; +import net.minecraft.data.recipe.RecipeGenerator; +import net.minecraft.item.Item; import net.minecraft.item.Items; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.tag.ItemTags; @@ -22,46 +23,58 @@ public FabricDocsReferenceRecipeProvider(FabricDataOutput output, CompletableFut } @Override - public void generate(RecipeExporter recipeExporter) { - // :::datagen-recipes:provider - // :::datagen-recipes:shapeless - ShapelessRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, Items.DIRT) // You can also specify an int to produce more than one - .input(Items.COARSE_DIRT) // You can also specify an int to require more than one, or a tag to accept multiple things - // Create an advancement that gives you the recipe - .criterion(FabricRecipeProvider.hasItem(Items.COARSE_DIRT), FabricRecipeProvider.conditionsFromItem(Items.COARSE_DIRT)) - .offerTo(recipeExporter); - // :::datagen-recipes:shapeless - // :::datagen-recipes:shaped - ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.CRAFTING_TABLE, 4) - .pattern("ll") - .pattern("ll") - .input('l', ItemTags.LOGS) // 'l' means "any log" - .group("multi_bench") // Put it in a group called "multi_bench" - groups are shown in one slot in the recipe book - .criterion(FabricRecipeProvider.hasItem(Items.CRAFTING_TABLE), FabricRecipeProvider.conditionsFromItem(Items.CRAFTING_TABLE)) - .offerTo(recipeExporter); - ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.LOOM, 4) - .pattern("ww") - .pattern("ll") - .input('w', ItemTags.WOOL) // 'w' means "any wool" - .input('l', ItemTags.LOGS) - .group("multi_bench") - .criterion(FabricRecipeProvider.hasItem(Items.LOOM), FabricRecipeProvider.conditionsFromItem(Items.LOOM)) - .offerTo(recipeExporter); - FabricRecipeProvider.createDoorRecipe(Items.OAK_DOOR, Ingredient.ofItems(Items.OAK_BUTTON)) // Using a helper method! - .criterion(FabricRecipeProvider.hasItem(Items.OAK_BUTTON), FabricRecipeProvider.conditionsFromItem(Items.OAK_BUTTON)) - .offerTo(recipeExporter); - // :::datagen-recipes:shaped - // :::datagen-recipes:other - FabricRecipeProvider.offerSmelting(recipeExporter, - List.of(Items.BREAD, Items.COOKIE, Items.HAY_BLOCK), // Inputs - RecipeCategory.FOOD, // Category - Items.WHEAT, // Output - 0.1f, // Experience - 300, // Cooking time - "food_to_wheat" // group - ); - // :::datagen-recipes:other - // :::datagen-recipes:provider + protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup registryLookup, RecipeExporter exporter) { + return new RecipeGenerator(registryLookup, exporter) { + @Override + public void generate() { + RegistryWrapper.Impl itemLookup = registries.getOrThrow(RegistryKeys.ITEM); + // :::datagen-recipes:provider + // :::datagen-recipes:shapeless + + createShapeless(RecipeCategory.BUILDING_BLOCKS, Items.DIRT) // You can also specify an int to produce more than one + .input(Items.COARSE_DIRT) // You can also specify an int to require more than one, or a tag to accept multiple things + // Create an advancement that gives you the recipe + .criterion(hasItem(Items.COARSE_DIRT), conditionsFromItem(Items.COARSE_DIRT)) + .offerTo(exporter); + // :::datagen-recipes:shapeless + // :::datagen-recipes:shaped + createShaped(RecipeCategory.MISC, Items.CRAFTING_TABLE, 4) + .pattern("ll") + .pattern("ll") + .input('l', ItemTags.LOGS) // 'l' means "any log" + .group("multi_bench") // Put it in a group called "multi_bench" - groups are shown in one slot in the recipe book + .criterion(hasItem(Items.CRAFTING_TABLE), conditionsFromItem(Items.CRAFTING_TABLE)) + .offerTo(exporter); + createShaped(RecipeCategory.MISC, Items.LOOM, 4) + .pattern("ww") + .pattern("ll") + .input('w', ItemTags.WOOL) // 'w' means "any wool" + .input('l', ItemTags.LOGS) + .group("multi_bench") + .criterion(hasItem(Items.LOOM), conditionsFromItem(Items.LOOM)) + .offerTo(exporter); + createDoorRecipe(Items.OAK_DOOR, Ingredient.ofItems(Items.OAK_BUTTON)) // Using a helper method! + .criterion(hasItem(Items.OAK_BUTTON), conditionsFromItem(Items.OAK_BUTTON)) + .offerTo(exporter); + // :::datagen-recipes:shaped + // :::datagen-recipes:other + offerSmelting( + List.of(Items.BREAD, Items.COOKIE, Items.HAY_BLOCK), // Inputs + RecipeCategory.FOOD, // Category + Items.WHEAT, // Output + 0.1f, // Experience + 300, // Cooking time + "food_to_wheat" // group + ); + // :::datagen-recipes:other + // :::datagen-recipes:provider + } + }; + } + + @Override + public String getName() { + return "FabricDocsReferenceRecipeProvider"; } } // :::datagen-recipes:provider diff --git a/reference/latest/src/client/java/com/example/docs/datagen/internal/FabricDocsReferenceInternalModelProvider.java b/reference/latest/src/client/java/com/example/docs/datagen/internal/FabricDocsReferenceInternalModelProvider.java new file mode 100644 index 000000000..902876d83 --- /dev/null +++ b/reference/latest/src/client/java/com/example/docs/datagen/internal/FabricDocsReferenceInternalModelProvider.java @@ -0,0 +1,62 @@ +package com.example.docs.datagen.internal; + +import net.minecraft.client.data.BlockStateModelGenerator; +import net.minecraft.client.data.BlockStateVariant; +import net.minecraft.client.data.ItemModelGenerator; +import net.minecraft.client.data.ModelIds; +import net.minecraft.client.data.Models; +import net.minecraft.client.data.MultipartBlockStateSupplier; +import net.minecraft.client.data.VariantSettings; +import net.minecraft.client.data.When; + +import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; + +import com.example.docs.block.ModBlocks; +import com.example.docs.block.custom.PrismarineLampBlock; +import com.example.docs.item.ModItems; + +/** + * This generator is just for the reference item and block models. + * Not for describing how to use the model provider. + */ +public class FabricDocsReferenceInternalModelProvider extends FabricModelProvider { + public FabricDocsReferenceInternalModelProvider(FabricDataOutput output) { + super(output); + } + + @Override + public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { + blockStateModelGenerator.registerSimpleCubeAll(ModBlocks.CONDENSED_DIRT); + blockStateModelGenerator.registerSimpleCubeAll(ModBlocks.COUNTER_BLOCK); + + // TODO: This would be a good example for the model generation page. Move when needed. + // TODO: Actually make the model for the prismarine lamp - not sure how to do it via datagen. + blockStateModelGenerator.blockStateCollector.accept(MultipartBlockStateSupplier.create(ModBlocks.PRISMARINE_LAMP) + .with(When.create().set(PrismarineLampBlock.ACTIVATED, true), + BlockStateVariant.create().put(VariantSettings.MODEL, ModelIds.getBlockSubModelId(ModBlocks.PRISMARINE_LAMP, "_on"))) + .with(When.create().set(PrismarineLampBlock.ACTIVATED, false), + BlockStateVariant.create().put(VariantSettings.MODEL, ModelIds.getBlockModelId(ModBlocks.PRISMARINE_LAMP))) + ); + + blockStateModelGenerator.registerLog(ModBlocks.CONDENSED_OAK_LOG).log(ModBlocks.CONDENSED_OAK_LOG); + } + + @Override + public void generateItemModels(ItemModelGenerator itemModelGenerator) { + itemModelGenerator.register(ModItems.COUNTER, Models.GENERATED); + itemModelGenerator.register(ModItems.LIGHTNING_STICK, Models.GENERATED); + itemModelGenerator.register(ModItems.GUIDITE_BOOTS, Models.GENERATED); + itemModelGenerator.register(ModItems.GUIDITE_CHESTPLATE, Models.GENERATED); + itemModelGenerator.register(ModItems.GUIDITE_HELMET, Models.GENERATED); + itemModelGenerator.register(ModItems.GUIDITE_LEGGINGS, Models.GENERATED); + itemModelGenerator.register(ModItems.POISONOUS_APPLE, Models.GENERATED); + itemModelGenerator.register(ModItems.SUSPICIOUS_SUBSTANCE, Models.GENERATED); + itemModelGenerator.register(ModItems.GUIDITE_SWORD, Models.HANDHELD); + } + + @Override + public String getName() { + return "FabricDocsReference Internal Model Provider"; + } +} diff --git a/reference/latest/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java b/reference/latest/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java index 2f79aa2f7..a40da0652 100644 --- a/reference/latest/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java +++ b/reference/latest/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java @@ -2,6 +2,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.render.RenderLayer; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -56,15 +57,15 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { // :::5 Identifier texture = Identifier.of("minecraft", "textures/block/deepslate.png"); - // texture, x, y, u, v, width, height, textureWidth, textureHeight - context.drawTexture(texture, 90, 90, 0, 0, 16, 16, 16, 16); + // renderLayer, texture, x, y, u, v, width, height, textureWidth, textureHeight + context.drawTexture(RenderLayer::getGuiTextured, texture, 90, 90, 0, 0, 16, 16, 16, 16); // :::5 // :::6 Identifier texture2 = Identifier.of("fabric-docs-reference", "textures/gui/test-uv-drawing.png"); int u = 10, v = 13, regionWidth = 14, regionHeight = 14; - // texture, x, y, width, height, u, v, regionWidth, regionHeight, textureWidth, textureHeight - context.drawTexture(texture2, 90, 190, 14, 14, u, v, regionWidth, regionHeight, 256, 256); + // renderLayer, texture, x, y, width, height, u, v, regionWidth, regionHeight, textureWidth, textureHeight + context.drawTexture(RenderLayer::getGuiTextured, texture2, 90, 190, 14, 14, u, v, regionWidth, regionHeight, 256, 256); // :::6 // :::7 diff --git a/reference/latest/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java b/reference/latest/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java index d226f49fe..58bcc05d4 100644 --- a/reference/latest/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java +++ b/reference/latest/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java @@ -1,5 +1,6 @@ package com.example.docs.rendering; +import net.minecraft.util.Util; import net.minecraft.util.math.ColorHelper; import net.minecraft.util.math.MathHelper; @@ -7,20 +8,19 @@ import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; public class HudRenderingEntrypoint implements ClientModInitializer { - private float totalTickDelta = 0.0F; @Override public void onInitializeClient() { // :::1 - HudRenderCallback.EVENT.register((context, tickDeltaManager) -> { + HudRenderCallback.EVENT.register((context, renderTickCounter) -> { int color = 0xFFFF0000; // Red int targetColor = 0xFF00FF00; // Green - // Total tick delta is stored in a field, so we can use it later. - totalTickDelta += tickDeltaManager.getTickDelta(true); + // You can use the Util.getMeasuringTimeMs(); function to get the current time in seconds. + double currentTime = Util.getMeasuringTimeMs(); // "lerp" simply means "linear interpolation", which is a fancy way of saying "blend". - float lerpedAmount = MathHelper.abs(MathHelper.sin(totalTickDelta / 50F)); - int lerpedColor = ColorHelper.Argb.lerp(lerpedAmount, color, targetColor); + float lerpedAmount = MathHelper.abs(MathHelper.sin((float) (currentTime / 50.0f))); + int lerpedColor = ColorHelper.lerp(lerpedAmount, color, targetColor); // Draw a square with the lerped color. // x1, x2, y1, y2, z, color diff --git a/reference/latest/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java b/reference/latest/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java index 311ea2434..8accf786f 100644 --- a/reference/latest/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java +++ b/reference/latest/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java @@ -3,9 +3,9 @@ import com.mojang.blaze3d.systems.RenderSystem; import org.joml.Matrix4f; +import net.minecraft.client.gl.ShaderProgramKeys; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferRenderer; -import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; @@ -72,8 +72,9 @@ public void onInitializeClient() { buffer.vertex(transformationMatrix, 35, 40, 5).color(0xFF000000); buffer.vertex(transformationMatrix, 20, 60, 5).color(0xFF414141); - // We'll get to this bit in the next section. - RenderSystem.setShader(GameRenderer::getPositionColorProgram); + // Make sure the correct shader for your chosen vertex format is set! + // You can find all the shaders in the ShaderProgramKeys class. + RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); // Draw the buffer onto the screen. diff --git a/reference/latest/src/client/java/com/example/docs/sound/DynamicSoundManager.java b/reference/latest/src/client/java/com/example/docs/sound/DynamicSoundManager.java index a8650d34b..a1fc96e14 100644 --- a/reference/latest/src/client/java/com/example/docs/sound/DynamicSoundManager.java +++ b/reference/latest/src/client/java/com/example/docs/sound/DynamicSoundManager.java @@ -56,7 +56,7 @@ public void stop(T soundInstance) { public Optional getPlayingSoundInstance(SoundEvent soundEvent) { for (var activeSound : this.activeSounds) { // SoundInstances use their SoundEvent's id by default - if (activeSound.getId().equals(soundEvent.getId())) { + if (activeSound.getId().equals(soundEvent.id())) { return Optional.of(activeSound); } } diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_dirt.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_dirt.json new file mode 100644 index 000000000..1ed6b759a --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_dirt.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "fabric-docs-reference:block/condensed_dirt" + } + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_oak_log.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_oak_log.json new file mode 100644 index 000000000..b60ae0d01 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/condensed_oak_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "fabric-docs-reference:block/condensed_oak_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "fabric-docs-reference:block/condensed_oak_log" + }, + "axis=z": { + "model": "fabric-docs-reference:block/condensed_oak_log_horizontal", + "x": 90 + } + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/counter_block.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/counter_block.json new file mode 100644 index 000000000..f879bbb4e --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/counter_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "fabric-docs-reference:block/counter_block" + } + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/prismarine_lamp.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/prismarine_lamp.json new file mode 100644 index 000000000..a3bef3fb5 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/blockstates/prismarine_lamp.json @@ -0,0 +1,20 @@ +{ + "multipart": [ + { + "apply": { + "model": "fabric-docs-reference:block/prismarine_lamp_on" + }, + "when": { + "activated": "true" + } + }, + { + "apply": { + "model": "fabric-docs-reference:block/prismarine_lamp" + }, + "when": { + "activated": "false" + } + } + ] +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_dirt.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_dirt.json new file mode 100644 index 000000000..95289f3cd --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_dirt.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:block/condensed_dirt" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_oak_log.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_oak_log.json new file mode 100644 index 000000000..a7a004d94 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/condensed_oak_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:block/condensed_oak_log" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/counter.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/counter.json new file mode 100644 index 000000000..a79d704d6 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/counter.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/counter" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/counter_block.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/counter_block.json new file mode 100644 index 000000000..a0ad24e53 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/counter_block.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:block/counter_block" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/engine.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/engine.json new file mode 100644 index 000000000..419a09ad4 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/engine.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:block/engine" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_boots.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_boots.json new file mode 100644 index 000000000..56bab5076 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_boots.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/guidite_boots" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_chestplate.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_chestplate.json new file mode 100644 index 000000000..aa7c2858c --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_chestplate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/guidite_chestplate" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_helmet.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_helmet.json new file mode 100644 index 000000000..03feb2d27 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_helmet.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/guidite_helmet" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_leggings.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_leggings.json new file mode 100644 index 000000000..65d9c9a1a --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_leggings.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/guidite_leggings" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_sword.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_sword.json new file mode 100644 index 000000000..8ea2ef51e --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/guidite_sword.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/guidite_sword" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/lightning_stick.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/lightning_stick.json new file mode 100644 index 000000000..776a9a864 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/lightning_stick.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/lightning_stick" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/poisonous_apple.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/poisonous_apple.json new file mode 100644 index 000000000..13abaee0a --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/poisonous_apple.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/poisonous_apple" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/prismarine_lamp.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/prismarine_lamp.json new file mode 100644 index 000000000..38a28e1f4 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/prismarine_lamp.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:block/prismarine_lamp" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/suspicious_substance.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/suspicious_substance.json new file mode 100644 index 000000000..d28094fa5 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/suspicious_substance.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:item/suspicious_substance" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/items/tater.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/tater.json new file mode 100644 index 000000000..045e74a0d --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/items/tater.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "fabric-docs-reference:block/tater" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/lang/en_us.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/lang/en_us.json index c4f66182f..46e48bef6 100644 --- a/reference/latest/src/main/generated/assets/fabric-docs-reference/lang/en_us.json +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/lang/en_us.json @@ -1,12 +1,18 @@ { "block.fabric-docs-reference.condensed_dirt": "Condensed Dirt", "block.fabric-docs-reference.condensed_oak_log": "Condensed Oak Log", + "block.fabric-docs-reference.counter_block": "Counter Block", + "block.fabric-docs-reference.engine": "Engine Block", "block.fabric-docs-reference.prismarine_lamp": "Prismarine Lamp", "death.attack.tater": "%1$s died from Tater damage!", "effect.fabric-docs-reference.tater": "Tater", - "enchantment.FabricDocsReference.thundering": "Thundering", + "enchantment.fabric-docs-reference.thundering": "Thundering", + "item.fabric-docs-reference.condensed_dirt": "Condensed Dirt", + "item.fabric-docs-reference.condensed_oak_log": "Condensed Oak Log", "item.fabric-docs-reference.counter": "Counter", "item.fabric-docs-reference.counter.info": "Used %1$s times", + "item.fabric-docs-reference.counter_block": "Counter Block", + "item.fabric-docs-reference.engine": "Engine Block", "item.fabric-docs-reference.guidite_boots": "Guidite Boots", "item.fabric-docs-reference.guidite_chestplate": "Guidite Chestplate", "item.fabric-docs-reference.guidite_helmet": "Guidite Helmet", @@ -14,6 +20,7 @@ "item.fabric-docs-reference.guidite_sword": "Guidite Sword", "item.fabric-docs-reference.lightning_stick": "Lightning Stick", "item.fabric-docs-reference.poisonous_apple": "Poisonous Apple", + "item.fabric-docs-reference.prismarine_lamp": "Prismarine Lamp", "item.fabric-docs-reference.suspicious_substance": "Suspicious Substance", "item.minecraft.potion.effect.tater": "Tater Potion", "itemGroup.fabric_docs_reference": "Fabric Docs Reference", diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_dirt.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_dirt.json new file mode 100644 index 000000000..378931bb4 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_dirt.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "fabric-docs-reference:block/condensed_dirt" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log.json new file mode 100644 index 000000000..df0610c85 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "fabric-docs-reference:block/condensed_oak_log_top", + "side": "fabric-docs-reference:block/condensed_oak_log" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json new file mode 100644 index 000000000..74f7500f0 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "fabric-docs-reference:block/condensed_oak_log_top", + "side": "fabric-docs-reference:block/condensed_oak_log" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/counter_block.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/counter_block.json new file mode 100644 index 000000000..2acbc6b41 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/block/counter_block.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "fabric-docs-reference:block/counter_block" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/counter.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/counter.json new file mode 100644 index 000000000..b7d703c2f --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/counter.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/counter" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_boots.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_boots.json new file mode 100644 index 000000000..a3128d04c --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/guidite_boots" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_chestplate.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_chestplate.json new file mode 100644 index 000000000..6ad106462 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/guidite_chestplate" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_helmet.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_helmet.json new file mode 100644 index 000000000..2176b0188 --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/guidite_helmet" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_leggings.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_leggings.json new file mode 100644 index 000000000..8b303a23a --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/guidite_leggings" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_sword.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_sword.json new file mode 100644 index 000000000..f7ed6f91a --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/guidite_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "fabric-docs-reference:item/guidite_sword" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/lightning_stick.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/lightning_stick.json new file mode 100644 index 000000000..52359c0aa --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/lightning_stick.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/lightning_stick" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/poisonous_apple.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/poisonous_apple.json new file mode 100644 index 000000000..2a8abcefe --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/poisonous_apple.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/poisonous_apple" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/suspicious_substance.json b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/suspicious_substance.json new file mode 100644 index 000000000..9d3a9ee6b --- /dev/null +++ b/reference/latest/src/main/generated/assets/fabric-docs-reference/models/item/suspicious_substance.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "fabric-docs-reference:item/suspicious_substance" + } +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/apple_and_beef.json b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/apple_and_beef.json new file mode 100644 index 000000000..a5e3509f7 --- /dev/null +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/apple_and_beef.json @@ -0,0 +1,39 @@ +{ + "parent": "fabric-docs-reference:get_dirt", + "criteria": { + "ate_apple": { + "conditions": { + "item": { + "items": "minecraft:apple" + } + }, + "trigger": "minecraft:consume_item" + }, + "ate_cooked_beef": { + "conditions": { + "item": { + "items": "minecraft:cooked_beef" + } + }, + "trigger": "minecraft:consume_item" + } + }, + "display": { + "description": "Ate an apple and beef", + "frame": "challenge", + "icon": { + "count": 1, + "id": "minecraft:apple" + }, + "title": "Apple and Beef" + }, + "requirements": [ + [ + "ate_apple" + ], + [ + "ate_cooked_beef" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/break_block_with_tool.json b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/break_block_with_tool.json new file mode 100644 index 000000000..9cb64eff1 --- /dev/null +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/break_block_with_tool.json @@ -0,0 +1,23 @@ +{ + "parent": "fabric-docs-reference:get_dirt", + "criteria": { + "break_block_with_tool": { + "trigger": "minecraft:fabric-docs-reference/use_tool" + } + }, + "display": { + "description": "That's not a shovel (probably)", + "frame": "goal", + "icon": { + "count": 1, + "id": "minecraft:diamond_shovel" + }, + "title": "Not a Shovel" + }, + "requirements": [ + [ + "break_block_with_tool" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/break_block_with_tool_five_times.json b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/break_block_with_tool_five_times.json new file mode 100644 index 000000000..e76733a8c --- /dev/null +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/break_block_with_tool_five_times.json @@ -0,0 +1,26 @@ +{ + "parent": "fabric-docs-reference:break_block_with_tool", + "criteria": { + "break_block_with_tool_five_times": { + "conditions": { + "requiredTimes": 5 + }, + "trigger": "minecraft:fabric-docs-reference/parameterized_use_tool" + } + }, + "display": { + "description": "That's still not a shovel (probably)", + "frame": "goal", + "icon": { + "count": 1, + "id": "minecraft:golden_shovel" + }, + "title": "Not a Shovel Still" + }, + "requirements": [ + [ + "break_block_with_tool_five_times" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/get_dirt.json b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/get_dirt.json new file mode 100644 index 000000000..606469518 --- /dev/null +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/advancement/get_dirt.json @@ -0,0 +1,29 @@ +{ + "criteria": { + "got_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:dirt" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "display": { + "background": "minecraft:textures/gui/advancements/backgrounds/adventure.png", + "description": "Now make a house from it", + "icon": { + "count": 1, + "id": "minecraft:dirt" + }, + "title": "Your First Dirt Block" + }, + "requirements": [ + [ + "got_dirt" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json index a7712f67d..ccd5680a3 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/crafting_table.json @@ -3,9 +3,7 @@ "category": "misc", "group": "multi_bench", "key": { - "l": { - "tag": "minecraft:logs" - } + "l": "#minecraft:logs" }, "pattern": [ "ll", diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/dirt.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/dirt.json index e864fc682..93967858f 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/dirt.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/dirt.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shapeless", "category": "building", "ingredients": [ - { - "item": "minecraft:coarse_dirt" - } + "minecraft:coarse_dirt" ], "result": { "count": 1, diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/loom.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/loom.json index 013eac197..49c84c1db 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/loom.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/loom.json @@ -3,12 +3,8 @@ "category": "misc", "group": "multi_bench", "key": { - "l": { - "tag": "minecraft:logs" - }, - "w": { - "tag": "minecraft:wool" - } + "l": "#minecraft:logs", + "w": "#minecraft:wool" }, "pattern": [ "ww", diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json index 477fcc1d4..fdc8c074d 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/oak_door.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "item": "minecraft:oak_button" - } + "#": "minecraft:oak_button" }, "pattern": [ "##", diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json index 17017b6aa..9a8d13cfe 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_bread.json @@ -4,9 +4,7 @@ "cookingtime": 300, "experience": 0.1, "group": "food_to_wheat", - "ingredient": { - "item": "minecraft:bread" - }, + "ingredient": "minecraft:bread", "result": { "id": "minecraft:wheat" } diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json index e87077791..d93f9361c 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_cookie.json @@ -4,9 +4,7 @@ "cookingtime": 300, "experience": 0.1, "group": "food_to_wheat", - "ingredient": { - "item": "minecraft:cookie" - }, + "ingredient": "minecraft:cookie", "result": { "id": "minecraft:wheat" } diff --git a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json index 2936c5d63..842ebd4c4 100644 --- a/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json +++ b/reference/latest/src/main/generated/data/fabric-docs-reference/recipe/wheat_from_smelting_hay_block.json @@ -4,9 +4,7 @@ "cookingtime": 300, "experience": 0.1, "group": "food_to_wheat", - "ingredient": { - "item": "minecraft:hay_block" - }, + "ingredient": "minecraft:hay_block", "result": { "id": "minecraft:wheat" } diff --git a/reference/latest/src/main/java/com/example/docs/block/ModBlocks.java b/reference/latest/src/main/java/com/example/docs/block/ModBlocks.java index de1c61733..d503a9bb8 100644 --- a/reference/latest/src/main/java/com/example/docs/block/ModBlocks.java +++ b/reference/latest/src/main/java/com/example/docs/block/ModBlocks.java @@ -7,6 +7,8 @@ import net.minecraft.item.Item; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; @@ -23,66 +25,98 @@ public class ModBlocks { // :::1 // :::2 + public static final RegistryKey CONDENSED_DIRT_KEY = RegistryKey.of( + RegistryKeys.BLOCK, + Identifier.of(FabricDocsReference.MOD_ID, "condensed_dirt") + ); + public static final Block CONDENSED_DIRT = register( - new Block(AbstractBlock.Settings.create().sounds(BlockSoundGroup.GRASS)), - "condensed_dirt", + new Block(AbstractBlock.Settings.create().registryKey(CONDENSED_DIRT_KEY).sounds(BlockSoundGroup.GRASS)), + CONDENSED_DIRT_KEY, true ); + // :::2 // :::3 + public static final RegistryKey CONDENSED_OAK_LOG_KEY = RegistryKey.of( + RegistryKeys.BLOCK, + Identifier.of(FabricDocsReference.MOD_ID, "condensed_oak_log") + ); + public static final Block CONDENSED_OAK_LOG = register( new PillarBlock( AbstractBlock.Settings.create() + .registryKey(CONDENSED_OAK_LOG_KEY) .sounds(BlockSoundGroup.WOOD) - ), "condensed_oak_log", true + ), CONDENSED_OAK_LOG_KEY, true ); + // :::3 // :::4 + public static final RegistryKey PRISMARINE_LAMP_KEY = RegistryKey.of( + RegistryKeys.BLOCK, + Identifier.of(FabricDocsReference.MOD_ID, "prismarine_lamp") + ); public static final Block PRISMARINE_LAMP = register( new PrismarineLampBlock( AbstractBlock.Settings.create() + .registryKey(PRISMARINE_LAMP_KEY) .sounds(BlockSoundGroup.LANTERN) .luminance(PrismarineLampBlock::getLuminance) - ), "prismarine_lamp", true + ), PRISMARINE_LAMP_KEY, true ); // :::4 + public static final RegistryKey ENGINE_BLOCK_KEY = RegistryKey.of( + RegistryKeys.BLOCK, + Identifier.of(FabricDocsReference.MOD_ID, "engine") + ); public static final Block ENGINE_BLOCK = register( - new EngineBlock(AbstractBlock.Settings.create()), "engine", true + new EngineBlock(AbstractBlock.Settings.create().registryKey(ENGINE_BLOCK_KEY)), ENGINE_BLOCK_KEY, true ); // :::5 + public static final RegistryKey COUNTER_BLOCK_KEY = RegistryKey.of( + RegistryKeys.BLOCK, + Identifier.of(FabricDocsReference.MOD_ID, "counter_block") + ); public static final Block COUNTER_BLOCK = register( - new CounterBlock(AbstractBlock.Settings.create()), "counter_block", true + new CounterBlock(AbstractBlock.Settings.create().registryKey(COUNTER_BLOCK_KEY)), COUNTER_BLOCK_KEY, true ); // :::5 // :::1 - public static Block register(Block block, String name, boolean shouldRegisterItem) { - // Register the block and its item. - Identifier id = Identifier.of(FabricDocsReference.MOD_ID, name); - + public static Block register(Block block, RegistryKey blockKey, boolean shouldRegisterItem) { // Sometimes, you may not want to register an item for the block. // Eg: if it's a technical block like `minecraft:air` or `minecraft:end_gateway` if (shouldRegisterItem) { - BlockItem blockItem = new BlockItem(block, new Item.Settings()); - Registry.register(Registries.ITEM, id, blockItem); + // Items need to be registered with a different type of registry key, but the ID + // can be the same. + RegistryKey itemKey = RegistryKey.of(RegistryKeys.ITEM, blockKey.getValue()); + + BlockItem blockItem = new BlockItem(block, new Item.Settings().registryKey(itemKey)); + Registry.register(Registries.ITEM, itemKey, blockItem); } - return Registry.register(Registries.BLOCK, id, block); + return Registry.register(Registries.BLOCK, blockKey, block); } // :::1 public static void initialize() { - // :::3 + setupItemGroups(); + } + + public static void setupItemGroups() { + // :::6 ItemGroupEvents.modifyEntriesEvent(ModItems.CUSTOM_ITEM_GROUP_KEY).register((itemGroup) -> { itemGroup.add(ModBlocks.CONDENSED_DIRT.asItem()); }); - // :::3 + // :::6 ItemGroupEvents.modifyEntriesEvent(ModItems.CUSTOM_ITEM_GROUP_KEY).register((itemGroup) -> { itemGroup.add(ModBlocks.CONDENSED_OAK_LOG.asItem()); itemGroup.add(ModBlocks.PRISMARINE_LAMP.asItem()); itemGroup.add(ModBlocks.COUNTER_BLOCK.asItem()); + itemGroup.add(ModBlocks.ENGINE_BLOCK.asItem()); }); } diff --git a/reference/latest/src/main/java/com/example/docs/block/entity/ModBlockEntities.java b/reference/latest/src/main/java/com/example/docs/block/entity/ModBlockEntities.java index 8d38b4289..775e32996 100644 --- a/reference/latest/src/main/java/com/example/docs/block/entity/ModBlockEntities.java +++ b/reference/latest/src/main/java/com/example/docs/block/entity/ModBlockEntities.java @@ -7,6 +7,8 @@ import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; +import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; + import com.example.docs.FabricDocsReference; import com.example.docs.block.ModBlocks; import com.example.docs.block.entity.custom.CounterBlockEntity; @@ -21,10 +23,10 @@ public class ModBlockEntities { register("counter", CounterBlockEntity::new, ModBlocks.COUNTER_BLOCK); private static BlockEntityType register(String name, - BlockEntityType.BlockEntityFactory entityFactory, + FabricBlockEntityTypeBuilder.Factory entityFactory, Block... blocks) { Identifier id = Identifier.of(FabricDocsReference.MOD_ID, name); - return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, BlockEntityType.Builder.create(entityFactory, blocks).build()); + return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, FabricBlockEntityTypeBuilder.create(entityFactory, blocks).build()); } // :::1 diff --git a/reference/latest/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java b/reference/latest/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java index b8c8d714b..4c3ddf48b 100644 --- a/reference/latest/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java +++ b/reference/latest/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java @@ -13,15 +13,18 @@ import net.fabricmc.api.ModInitializer; +import com.example.docs.FabricDocsReference; + public class FabricDocsReferenceDamageTypes implements ModInitializer { - public static final Block TATER_BLOCK = new TaterBlock(AbstractBlock.Settings.create()); + public static final RegistryKey TATER_BLOCK_KEY = RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(FabricDocsReference.MOD_ID, "tater")); + public static final Block TATER_BLOCK = new TaterBlock(AbstractBlock.Settings.create().registryKey(TATER_BLOCK_KEY)); // :::1 - public static final RegistryKey TATER_DAMAGE = RegistryKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of("fabric-docs-reference", "tater")); + public static final RegistryKey TATER_DAMAGE = RegistryKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of(FabricDocsReference.MOD_ID, "tater")); // :::1 @Override public void onInitialize() { - Registry.register(Registries.BLOCK, Identifier.of("fabric-docs-reference", "tater"), TATER_BLOCK); - Registry.register(Registries.ITEM, Identifier.of("fabric-docs-reference", "tater"), new BlockItem(TATER_BLOCK, new Item.Settings())); + Registry.register(Registries.BLOCK, Identifier.of(FabricDocsReference.MOD_ID, "tater"), TATER_BLOCK); + Registry.register(Registries.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "tater"), new BlockItem(TATER_BLOCK, new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, TATER_BLOCK_KEY.getValue())))); } } diff --git a/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java b/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java index 87e217764..728df7667 100644 --- a/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java +++ b/reference/latest/src/main/java/com/example/docs/damage/TaterBlock.java @@ -6,6 +6,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -17,12 +18,13 @@ public TaterBlock(Settings settings) { @Override public void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity) { - if (entity instanceof LivingEntity) { + if (entity instanceof LivingEntity && world instanceof ServerWorld serverWorld) { DamageSource damageSource = new DamageSource( world.getRegistryManager() - .get(RegistryKeys.DAMAGE_TYPE) - .entryOf(FabricDocsReferenceDamageTypes.TATER_DAMAGE)); - entity.damage(damageSource, 5.0f); + .getOrThrow(RegistryKeys.DAMAGE_TYPE) + .getEntry(FabricDocsReferenceDamageTypes.TATER_DAMAGE.getValue()).get() + ); + entity.damage(serverWorld, damageSource, 5.0f); } } } diff --git a/reference/latest/src/main/java/com/example/docs/effect/TaterEffect.java b/reference/latest/src/main/java/com/example/docs/effect/TaterEffect.java index eb0a705b5..b26d11d46 100644 --- a/reference/latest/src/main/java/com/example/docs/effect/TaterEffect.java +++ b/reference/latest/src/main/java/com/example/docs/effect/TaterEffect.java @@ -4,6 +4,7 @@ import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectCategory; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; // :::1 public class TaterEffect extends StatusEffect { @@ -22,12 +23,12 @@ public boolean canApplyUpdateEffect(int duration, int amplifier) { // Called when the effect is applied. @Override - public boolean applyUpdateEffect(LivingEntity entity, int amplifier) { + public boolean applyUpdateEffect(ServerWorld world, LivingEntity entity, int amplifier) { if (entity instanceof PlayerEntity) { ((PlayerEntity) entity).addExperience(1 << amplifier); // Higher amplifier gives you experience faster } - return super.applyUpdateEffect(entity, amplifier); + return super.applyUpdateEffect(world, entity, amplifier); } } // :::1 diff --git a/reference/latest/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java b/reference/latest/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java index 150d6b616..b3304609b 100644 --- a/reference/latest/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java +++ b/reference/latest/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java @@ -9,6 +9,7 @@ import net.minecraft.loot.LootTable; import net.minecraft.loot.entry.ItemEntry; import net.minecraft.registry.RegistryKey; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; import net.fabricmc.api.ModInitializer; @@ -17,7 +18,7 @@ // Class to contain all mod events. public class FabricDocsReferenceEvents implements ModInitializer { - private static final RegistryKey COAL_ORE_LOOT_TABLE_ID = Blocks.COAL_ORE.getLootTableKey(); + private static final RegistryKey COAL_ORE_LOOT_TABLE_ID = Blocks.COAL_ORE.getLootTableKey().get(); @Override public void onInitialize() { @@ -26,8 +27,8 @@ public void onInitialize() { BlockState state = world.getBlockState(pos); // Manual spectator check is necessary because AttackBlockCallbacks fire before the spectator check - if (!player.isSpectator() && player.getMainHandStack().isEmpty() && state.isToolRequired()) { - player.damage(world.getDamageSources().generic(), 1.0F); + if (!player.isSpectator() && player.getMainHandStack().isEmpty() && state.isToolRequired() && world instanceof ServerWorld serverWorld) { + player.damage(serverWorld, world.getDamageSources().generic(), 1.0F); } return ActionResult.PASS; diff --git a/reference/latest/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java b/reference/latest/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java index fc7222cb0..68d98da4a 100644 --- a/reference/latest/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java +++ b/reference/latest/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java @@ -2,17 +2,10 @@ import net.fabricmc.api.ModInitializer; -import com.example.docs.item.armor.ModArmorMaterials; - // :::1 public class FabricDocsReferenceItems implements ModInitializer { @Override public void onInitialize() { - // :::1 - // :::2 - ModArmorMaterials.initialize(); - // :::2 - // :::1 ModItems.initialize(); } } diff --git a/reference/latest/src/main/java/com/example/docs/item/ModItems.java b/reference/latest/src/main/java/com/example/docs/item/ModItems.java index 928f1578e..0a87c31d7 100644 --- a/reference/latest/src/main/java/com/example/docs/item/ModItems.java +++ b/reference/latest/src/main/java/com/example/docs/item/ModItems.java @@ -1,5 +1,7 @@ package com.example.docs.item; +import net.minecraft.component.type.ConsumableComponent; +import net.minecraft.component.type.ConsumableComponents; import net.minecraft.component.type.FoodComponent; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; @@ -9,43 +11,70 @@ import net.minecraft.item.ItemGroups; import net.minecraft.item.ItemStack; import net.minecraft.item.SwordItem; +import net.minecraft.item.ToolMaterial; +import net.minecraft.item.consume.ApplyEffectsConsumeEffect; +import net.minecraft.item.equipment.EquipmentType; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.BlockTags; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.api.registry.CompostingChanceRegistry; -import net.fabricmc.fabric.api.registry.FuelRegistry; +import net.fabricmc.fabric.api.registry.FuelRegistryEvents; import com.example.docs.FabricDocsReference; import com.example.docs.component.ModComponents; -import com.example.docs.item.armor.ModArmorMaterials; +import com.example.docs.item.armor.GuiditeArmorMaterial; import com.example.docs.item.custom.CounterItem; import com.example.docs.item.custom.LightningStick; -import com.example.docs.item.tool.GuiditeMaterial; // :::1 public class ModItems { // :::1 + // :::guidite_tool_material + public static final ToolMaterial GUIDITE_TOOL_MATERIAL = new ToolMaterial( + BlockTags.INCORRECT_FOR_WOODEN_TOOL, + 455, + 5.0F, + 1.5F, + 22, + GuiditeArmorMaterial.REPAIRS_GUIDITE_ARMOR + ); + // :::guidite_tool_material + // :::6 - public static final Item GUIDITE_HELMET = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.HELMET, new Item.Settings().maxDamage(ArmorItem.Type.HELMET.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_helmet"); - public static final Item GUIDITE_CHESTPLATE = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.CHESTPLATE, new Item.Settings().maxDamage(ArmorItem.Type.CHESTPLATE.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_chestplate"); - public static final Item GUIDITE_LEGGINGS = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.LEGGINGS, new Item.Settings().maxDamage(ArmorItem.Type.LEGGINGS.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_leggings"); - public static final Item GUIDITE_BOOTS = register(new ArmorItem(ModArmorMaterials.GUIDITE, ArmorItem.Type.BOOTS, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(ModArmorMaterials.GUIDITE_DURABILITY_MULTIPLIER))), "guidite_boots"); + public static final RegistryKey GUIDITE_HELMET_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "guidite_helmet")); + public static final Item GUIDITE_HELMET = register(new ArmorItem(GuiditeArmorMaterial.INSTANCE, EquipmentType.HELMET, new Item.Settings().registryKey(GUIDITE_HELMET_KEY).maxDamage(EquipmentType.HELMET.getMaxDamage(GuiditeArmorMaterial.BASE_DURABILITY))), GUIDITE_HELMET_KEY); + + public static final RegistryKey GUIDITE_CHESTPLATE_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "guidite_chestplate")); + public static final Item GUIDITE_CHESTPLATE = register(new ArmorItem(GuiditeArmorMaterial.INSTANCE, EquipmentType.CHESTPLATE, new Item.Settings().registryKey(GUIDITE_CHESTPLATE_KEY).maxDamage(EquipmentType.CHESTPLATE.getMaxDamage(GuiditeArmorMaterial.BASE_DURABILITY))), GUIDITE_CHESTPLATE_KEY); + + public static final RegistryKey GUIDITE_LEGGINGS_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "guidite_leggings")); + public static final Item GUIDITE_LEGGINGS = register(new ArmorItem(GuiditeArmorMaterial.INSTANCE, EquipmentType.LEGGINGS, new Item.Settings().registryKey(GUIDITE_LEGGINGS_KEY).maxDamage(EquipmentType.LEGGINGS.getMaxDamage(GuiditeArmorMaterial.BASE_DURABILITY))), GUIDITE_LEGGINGS_KEY); + + public static final RegistryKey GUIDITE_BOOTS_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "guidite_boots")); + public static final Item GUIDITE_BOOTS = register(new ArmorItem(GuiditeArmorMaterial.INSTANCE, EquipmentType.BOOTS, new Item.Settings().registryKey(GUIDITE_BOOTS_KEY).maxDamage(EquipmentType.BOOTS.getMaxDamage(GuiditeArmorMaterial.BASE_DURABILITY))), GUIDITE_BOOTS_KEY); // :::6 - public static final Item LIGHTNING_STICK = register(new LightningStick(new Item.Settings()), "lightning_stick"); + public static final RegistryKey LIGHTNING_STICK_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "lightning_stick")); + public static final Item LIGHTNING_STICK = register(new LightningStick(new Item.Settings().registryKey(LIGHTNING_STICK_KEY)), LIGHTNING_STICK_KEY); // :::7 - public static final Item GUIDITE_SWORD = register(new SwordItem(GuiditeMaterial.INSTANCE, new Item.Settings()), "guidite_sword"); + public static final RegistryKey GUIDITE_SWORD_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "guidite_sword")); + public static final Item GUIDITE_SWORD = register(new SwordItem(GUIDITE_TOOL_MATERIAL, 1f, 1f, new Item.Settings().registryKey(GUIDITE_SWORD_KEY)), GUIDITE_SWORD_KEY); // :::7 // :::_13 + public static final RegistryKey COUNTER_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "counter")); public static final Item COUNTER = register(new CounterItem( - // Initialize the click count component with a default value of 0 - new Item.Settings().component(ModComponents.CLICK_COUNT_COMPONENT, 0) - ), "counter"); + new Item.Settings() + .registryKey(COUNTER_KEY) + // Initialize the click count component with a default value of 0 + .component(ModComponents.CLICK_COUNT_COMPONENT, 0) + ), COUNTER_KEY); // :::_13 // :::9 public static final RegistryKey CUSTOM_ITEM_GROUP_KEY = RegistryKey.of(Registries.ITEM_GROUP.getKey(), Identifier.of(FabricDocsReference.MOD_ID, "item_group")); @@ -55,35 +84,35 @@ public class ModItems { .build(); // :::9 // :::5 + public static final ConsumableComponent POISON_FOOD_CONSUMABLE_COMPONENT = ConsumableComponents.food() + // The duration is in ticks, 20 ticks = 1 second + .consumeEffect(new ApplyEffectsConsumeEffect(new StatusEffectInstance(StatusEffects.POISON, 6 * 20, 1), 1.0f)) + .build(); public static final FoodComponent POISON_FOOD_COMPONENT = new FoodComponent.Builder() .alwaysEdible() - .snack() - // The duration is in ticks, 20 ticks = 1 second - .statusEffect(new StatusEffectInstance(StatusEffects.POISON, 6 * 20, 1), 1.0f) .build(); // :::5 // :::poisonous_apple + public static final RegistryKey POISONOUS_APPLE_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "poisonous_apple")); public static final Item POISONOUS_APPLE = register( - new Item(new Item.Settings().food(POISON_FOOD_COMPONENT)), - "poisonous_apple" + new Item(new Item.Settings().registryKey(POISONOUS_APPLE_KEY).food(POISON_FOOD_COMPONENT, POISON_FOOD_CONSUMABLE_COMPONENT)), + POISONOUS_APPLE_KEY ); // :::poisonous_apple // :::2 + public static final RegistryKey SUSPICIOUS_SUBSTANCE_KEY = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(FabricDocsReference.MOD_ID, "suspicious_substance")); public static final Item SUSPICIOUS_SUBSTANCE = register( - new Item(new Item.Settings()), - "suspicious_substance" + new Item(new Item.Settings().registryKey(SUSPICIOUS_SUBSTANCE_KEY)), + SUSPICIOUS_SUBSTANCE_KEY ); // :::2 // :::1 - public static Item register(Item item, String id) { - // Create the identifier for the item. - Identifier itemID = Identifier.of(FabricDocsReference.MOD_ID, id); - + public static Item register(Item item, RegistryKey registryKey) { // Register the item. - Item registeredItem = Registry.register(Registries.ITEM, itemID, item); + Item registeredItem = Registry.register(Registries.ITEM, registryKey.getValue(), item); // Return the registered item! return registeredItem; @@ -141,7 +170,9 @@ public static void initialize() { // Add the suspicious substance to the registry of fuels, with a burn time of 30 seconds. // Remember, Minecraft deals with logical based-time using ticks. // 20 ticks = 1 second. - FuelRegistry.INSTANCE.add(ModItems.SUSPICIOUS_SUBSTANCE, 30 * 20); + FuelRegistryEvents.BUILD.register((builder, context) -> { + builder.add(ModItems.SUSPICIOUS_SUBSTANCE, 30 * 20); + }); // :::_11 // :::3 } diff --git a/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java b/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java index eb0ed42df..93126a613 100644 --- a/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java +++ b/reference/latest/src/main/java/com/example/docs/item/armor/GuiditeArmorMaterial.java @@ -1,97 +1,48 @@ -//package com.example.docs.item.armor; -// -//import net.minecraft.item.ArmorItem; -//import net.minecraft.item.ArmorMaterial; -//import net.minecraft.recipe.Ingredient; -//import net.minecraft.sound.SoundEvent; -//import net.minecraft.sound.SoundEvents; -// -//import com.example.docs.item.ModItems; -// -//// :::1 -//public class GuiditeArmorMaterial implements ArmorMaterial { -// // ... -// //:::1 -// // :::_10 -// public static final GuiditeArmorMaterial INSTANCE = new GuiditeArmorMaterial(); -// -// // :::_10 -// // :::2 -// @Override -// public int getDurability(ArmorItem.Type type) { -// // Replace this multiplier by a constant value for the durability of the armor. -// // For reference, diamond uses 33 for all armor pieces, whilst leather uses 5. -// int DURABILITY_MULTIPLIER = 12; -// return switch (type) { -// case BOOTS -> 13 * DURABILITY_MULTIPLIER; -// case LEGGINGS -> 15 * DURABILITY_MULTIPLIER; -// case CHESTPLATE -> 16 * DURABILITY_MULTIPLIER; -// case HELMET -> 11 * DURABILITY_MULTIPLIER; -// default -> 0; -// }; -// } -// -// // :::2 -// // :::3 -// @Override -// public int getProtection(ArmorItem.Type type) { -// // Protection values for all the slots. -// // For reference, diamond uses 3 for boots, 6 for leggings, 8 for chestplate, and 3 for helmet, -// // whilst leather uses 1, 2, 3 and 1 respectively. -// return switch (type) { -// case BOOTS, HELMET -> 3; -// case LEGGINGS -> 6; -// case CHESTPLATE -> 8; -// default -> 0; -// }; -// } -// -// // :::3 -// // :::4 -// @Override -// public int getEnchantability() { -// return 5; -// } -// -// // :::4 -// // :::5 -// @Override -// public SoundEvent getEquipSound() { -// // Example for Iron Armor -// return SoundEvents.ITEM_ARMOR_EQUIP_IRON; -// } -// -// // :::5 -// // :::6 -// @Override -// public Ingredient getRepairIngredient() { -// return Ingredient.ofItems(ModItems.SUSPICIOUS_SUBSTANCE); -// } -// -// // :::6 -// // :::7 -// @Override -// public String getName() { -// return "guidite"; -// } -// -// // :::7 -// // :::8 -// @Override -// public float getToughness() { -// return 2.0F; -// } -// -// // :::8 -// // :::9 -// @Override -// public float getKnockbackResistance() { -// // We don't want knockback resistance for guidite armor, but if you do, -// // change this value to 0.XF, where X is the level of knockback resistance you want. -// return 0; -// } -// -// // :::9 -// // :::1 -//} -//// :::1 +package com.example.docs.item.armor; + +import java.util.Map; + +import net.minecraft.item.Item; +import net.minecraft.item.equipment.ArmorMaterial; +import net.minecraft.item.equipment.EquipmentAsset; +import net.minecraft.item.equipment.EquipmentAssetKeys; +import net.minecraft.item.equipment.EquipmentType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; + +import com.example.docs.FabricDocsReference; + +public class GuiditeArmorMaterial { + // :::base_durability + public static final int BASE_DURABILITY = 15; + // :::base_durability + + // :::material_key + public static final RegistryKey GUIDITE_ARMOR_MATERIAL_KEY = RegistryKey.of(EquipmentAssetKeys.REGISTRY_KEY, Identifier.of(FabricDocsReference.MOD_ID, "guidite")); + // :::material_key + + // :::repair_tag + public static final TagKey REPAIRS_GUIDITE_ARMOR = TagKey.of(Registries.ITEM.getKey(), Identifier.of(FabricDocsReference.MOD_ID, "repairs_guidite_armor")); + // :::repair_tag + + // :::guidite_armor_material + public static final ArmorMaterial INSTANCE = new ArmorMaterial( + BASE_DURABILITY, + Map.of( + EquipmentType.HELMET, 3, + EquipmentType.CHESTPLATE, 8, + EquipmentType.LEGGINGS, 6, + EquipmentType.BOOTS, 3 + ), + 5, + SoundEvents.ITEM_ARMOR_EQUIP_IRON, + 0.0F, + 0.0F, + REPAIRS_GUIDITE_ARMOR, + GUIDITE_ARMOR_MATERIAL_KEY + ); + // :::guidite_armor_material +} diff --git a/reference/latest/src/main/java/com/example/docs/item/custom/CounterItem.java b/reference/latest/src/main/java/com/example/docs/item/custom/CounterItem.java index 4bf333922..7a0cfe0bf 100644 --- a/reference/latest/src/main/java/com/example/docs/item/custom/CounterItem.java +++ b/reference/latest/src/main/java/com/example/docs/item/custom/CounterItem.java @@ -7,9 +7,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.tooltip.TooltipType; import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; import net.minecraft.util.Formatting; import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; import com.example.docs.component.ModComponents; @@ -24,20 +24,19 @@ public CounterItem(Settings settings) { @Override //::2 - public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + public ActionResult use(World world, PlayerEntity user, Hand hand) { ItemStack stack = user.getStackInHand(hand); // Don't do anything on the client if (world.isClient()) { - return TypedActionResult.success(stack); + return ActionResult.SUCCESS; } // Read the current count and increase it by one int count = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); stack.set(ModComponents.CLICK_COUNT_COMPONENT, ++count); - // Return the original stack - return TypedActionResult.success(stack); + return ActionResult.SUCCESS; } //::2 diff --git a/reference/latest/src/main/java/com/example/docs/item/custom/LightningStick.java b/reference/latest/src/main/java/com/example/docs/item/custom/LightningStick.java index c7477af01..0b5d7645a 100644 --- a/reference/latest/src/main/java/com/example/docs/item/custom/LightningStick.java +++ b/reference/latest/src/main/java/com/example/docs/item/custom/LightningStick.java @@ -9,9 +9,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.tooltip.TooltipType; import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; import net.minecraft.util.Formatting; import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -24,11 +24,11 @@ public LightningStick(Settings settings) { // :::1 // :::2 @Override - public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + public ActionResult use(World world, PlayerEntity user, Hand hand) { // Ensure we don't spawn the lightning only on the client. // This is to prevent desync. if (world.isClient) { - return TypedActionResult.pass(user.getStackInHand(hand)); + return ActionResult.PASS; } BlockPos frontOfPlayer = user.getBlockPos().offset(user.getHorizontalFacing(), 10); @@ -38,9 +38,7 @@ public TypedActionResult use(World world, PlayerEntity user, Hand han lightningBolt.setPosition(frontOfPlayer.toCenterPos()); world.spawnEntity(lightningBolt); - // Nothing has changed to the item stack, - // so we just return it how it was. - return TypedActionResult.success(user.getStackInHand(hand)); + return ActionResult.SUCCESS; } // :::2 diff --git a/reference/latest/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java b/reference/latest/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java index 60fa33213..1b19da5f5 100644 --- a/reference/latest/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java +++ b/reference/latest/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java @@ -15,7 +15,7 @@ // ::: @Mixin(SheepEntity.class) public class SheepEntityMixin { - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;sheared(Lnet/minecraft/sound/SoundCategory;)V"), method = "interactMob", cancellable = true) + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;sheared(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/sound/SoundCategory;Lnet/minecraft/item/ItemStack;)V"), method = "interactMob", cancellable = true) private void onShear(final PlayerEntity player, final Hand hand, final CallbackInfoReturnable info) { ActionResult result = SheepShearCallback.EVENT.invoker().interact(player, (SheepEntity) (Object) this); diff --git a/reference/latest/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java b/reference/latest/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java index 25b3084ff..dc63c4d9f 100644 --- a/reference/latest/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java +++ b/reference/latest/src/main/java/com/example/docs/networking/payload/EngineSoundInstancePacket.java @@ -18,7 +18,7 @@ public Id getId() { } public static final PacketCodec CODEC = PacketCodec.tuple( - PacketCodecs.BOOL, EngineSoundInstancePacket::shouldStart, + PacketCodecs.BOOLEAN, EngineSoundInstancePacket::shouldStart, BlockPos.PACKET_CODEC, EngineSoundInstancePacket::blockEntityPos, EngineSoundInstancePacket::new ); diff --git a/reference/latest/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java b/reference/latest/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java index 3431e8596..a666a39c9 100644 --- a/reference/latest/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java +++ b/reference/latest/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java @@ -19,7 +19,7 @@ public class FabricDocsReferencePotions implements ModInitializer { Registry.register( Registries.POTION, Identifier.of("fabric-docs-reference", "tater"), - new Potion( + new Potion("tater", new StatusEffectInstance( FabricDocsReferenceEffects.TATER, 3600, diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/equipment/guidite.json b/reference/latest/src/main/resources/assets/fabric-docs-reference/equipment/guidite.json new file mode 100644 index 000000000..6b3bd9200 --- /dev/null +++ b/reference/latest/src/main/resources/assets/fabric-docs-reference/equipment/guidite.json @@ -0,0 +1,14 @@ +{ + "layers": { + "humanoid": [ + { + "texture": "fabric-docs-reference:guidite" + } + ], + "humanoid_leggings": [ + { + "texture": "fabric-docs-reference:guidite" + } + ] + } +} \ No newline at end of file diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_dirt.png b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_dirt.png new file mode 100644 index 000000000..0ba734bc5 Binary files /dev/null and b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/block/condensed_dirt.png differ diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/entity/equipment/humanoid/guidite.png b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/entity/equipment/humanoid/guidite.png new file mode 100644 index 000000000..a02174be7 Binary files /dev/null and b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/entity/equipment/humanoid/guidite.png differ diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/entity/equipment/humanoid_leggings/guidite.png b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/entity/equipment/humanoid_leggings/guidite.png new file mode 100644 index 000000000..a2c9693c3 Binary files /dev/null and b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/entity/equipment/humanoid_leggings/guidite.png differ diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/item/counter.png b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/item/counter.png new file mode 100644 index 000000000..e2e1e796f Binary files /dev/null and b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/item/counter.png differ diff --git a/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/item/lightning_stick.png b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/item/lightning_stick.png new file mode 100644 index 000000000..8c082d2d6 Binary files /dev/null and b/reference/latest/src/main/resources/assets/fabric-docs-reference/textures/item/lightning_stick.png differ diff --git a/reference/settings.gradle b/reference/settings.gradle index 281aa1097..076cb4609 100644 --- a/reference/settings.gradle +++ b/reference/settings.gradle @@ -10,4 +10,5 @@ pluginManagement { } include "latest" -include "1.20.4" \ No newline at end of file +include "1.20.4" +include "1.21" \ No newline at end of file diff --git a/versions/1.21/develop/automatic-testing.md b/versions/1.21/develop/automatic-testing.md new file mode 100644 index 000000000..d49f89373 --- /dev/null +++ b/versions/1.21/develop/automatic-testing.md @@ -0,0 +1,93 @@ +--- +title: Automated Testing +description: A guide to writing automatic tests with Fabric Loader JUnit. +authors: + - kevinthegreat1 + +search: false +--- + +# Automated Testing {#automated-testing} + +This page explains how to write code to automatically test parts of your mod. There are two ways to automatically test your mod: unit tests with Fabric Loader JUnit or game tests with the Gametest framework from Minecraft. + +Unit tests should be used to test components of your code, such as methods and helper classes, while game tests spin up an actual Minecraft client and server to run your tests, which makes it suitable for testing features and gameplay. + +::: warning +Currently, this guide only covers unit testing. +::: + +## Unit Testing {#unit-testing} + +Since Minecraft modding relies on runtime byte-code modification tools such as Mixin, simply adding and using JUnit normally would not work. That's why Fabric provides Fabric Loader JUnit, a JUnit plugin that enables unit testing in Minecraft. + +### Setting up Fabric Loader JUnit {#setting-up-fabric-loader-junit} + +First, we need to add Fabric Loader JUnit to the development environment. Add the following to your dependencies block in your `build.gradle`: + +@[code lang=groovy transcludeWith=:::automatic-testing:1](@/reference/build.gradle) + +Then, we need to tell Gradle to use Fabric Loader JUnit for testing. You can do so by adding the following code to your `build.gradle`: + +@[code lang=groovy transcludeWith=:::automatic-testing:2](@/reference/1.21/build.gradle) + +### Writing Tests {#writing-tests} + +Once you reload Gradle, you're now ready to write tests. + +These tests are written just like regular JUnit tests, with a bit of additional setup if you want to access any registry-dependent class, such as `ItemStack`. If you're comfortable with JUnit, you can skip to [Setting Up Registries](#setting-up-registries). + +#### Setting Up Your First Test Class {#setting-up-your-first-test-class} + +Tests are written in the `src/test/java` directory. + +One naming convention is to mirror the package structure of the class you are testing. For example, to test `src/main/java/com/example/docs/codec/BeanType.java`, you'd create a class at `src/test/java/com/example/docs/codec/BeanTypeTest.java`. Notice how we added `Test` to the end of the class name. This also allows you to easily access package-private methods and fields. + +Another naming convention is to have a `test` package, such as `src/test/java/com/example/docs/test/codec/BeanTypeTest.java`. This prevents some problems that may arise with using the same package if you use Java modules. + +After creating the test class, use ⌘/CTRLN to bring up the Generate menu. Select Test and start typing your method name, usually starting with `test`. Press ENTER when you're done. For more tips and tricks on using the IDE, see [IDE Tips and Tricks](./ide-tips-and-tricks#code-generation). + +![Generating a test method](/assets/develop/misc/automatic-testing/unit_testing_01.png) + +You can, of course, write the method signature by hand, and any instance method with no parameters and a void return type will be identified as a test method. You should end up with the following: + +![A blank test method with test indicators](/assets/develop/misc/automatic-testing/unit_testing_02.png) + +Notice the green arrow indicators in the gutter: you can easily run a test by clicking them. Alternately, your tests will run automatically on every build, including CI builds such as GitHub Actions. If you're using GitHub Actions, don't forget to read [Setting Up GitHub Actions](#setting-up-github-actions). + +Now, it's time to write your actual test code. You can assert conditions using `org.junit.jupiter.api.Assertions`. Check out the following test: + +@[code lang=java transcludeWith=:::automatic-testing:4](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +For an explanation of what this code actually does, see [Codecs](./codecs#registry-dispatch). + +#### Setting Up Registries {#setting-up-registries} + +Great, the first test worked! But wait, the second test failed? In the logs, we get one of the following errors. + +@[code lang=java transcludeWith=:::automatic-testing:5](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +This is because we're trying to access the registry or a class that depends on the registry (or, in rare cases, depends on other Minecraft classes such as `SharedConstants`), but Minecraft has not been initialized. We just need to initialize it a little bit to have registries working. Simply add the following code to the beginning of your `beforeAll` method. + +@[code lang=java transcludeWith=:::automatic-testing:7](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +### Setting Up GitHub Actions {#setting-up-github-actions} + +::: info +This section assumes that you are using the standard GitHub Action workflow included with the example mod and with the mod template. +::: + +Your tests will now run on every build, including those by CI providers such as GitHub Actions. But what if a build fails? We need to upload the logs as an artifact so we can view the test reports. + +Add this to your `.github/workflows/build.yml` file, below the `./gradlew build` step. + +```yaml +- name: Store reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: reports + path: | + **/build/reports/ + **/build/test-results/ +``` diff --git a/versions/1.21/develop/blocks/block-entities.md b/versions/1.21/develop/blocks/block-entities.md new file mode 100644 index 000000000..602586217 --- /dev/null +++ b/versions/1.21/develop/blocks/block-entities.md @@ -0,0 +1,114 @@ +--- +title: Block Entities +description: Learn how to create block entities for your custom blocks. +authors: + - natri0 + +search: false +--- + +# Block Entities {#block-entities} + +Block entities are a way to store additional data for a block, that is not part of the block state: inventory contents, custom name and so on. +Minecraft uses block entities for blocks like chests, furnaces, and command blocks. + +As an example, we will create a block that counts how many times it has been right-clicked. + +## Creating the Block Entity {#creating-the-block-entity} + +To make Minecraft recognize and load the new block entities, we need to create a block entity type. This is done by extending the `BlockEntity` class and registering it in a new `ModBlockEntities` class. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Registering a `BlockEntity` yields a `BlockEntityType` like the `COUNTER_BLOCK_ENTITY` we've used above: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java) + +::: tip +Note how the constructor of the `CounterBlockEntity` takes two parameters, but the `BlockEntity` constructor takes three: the `BlockEntityType`, the `BlockPos`, and the `BlockState`. +If we didn't hard-code the `BlockEntityType`, the `ModBlockEntities` class wouldn't compile! This is because the `BlockEntityFactory`, which is a functional interface, describes a function that only takes two parameters, just like our constructor. +::: + +## Creating the Block {#creating-the-block} + +Next, to actually use the block entity, we need a block that implements `BlockEntityProvider`. Let's create one and call it `CounterBlock`. + +::: tip +There's two ways to approach this: + +- create a block that extends `BlockWithEntity` and implement the `createBlockEntity` method (_and_ the `getRenderType` method, since `BlockWithEntity` makes it invisible by default) +- create a block that implements `BlockEntityProvider` by itself and override the `createBlockEntity` method + +We'll use the first approach in this example, since `BlockWithEntity` also provides some nice utilities. +::: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Using `BlockWithEntity` as the parent class means we also need to implement the `createCodec` method, which is rather easy. + +Unlike blocks, which are singletons, a new block entity is created for every instance of the block. This is done with the `createBlockEntity` method, which takes the position and `BlockState`, and returns a `BlockEntity`, or `null` if there shouldn't be one. + +Don't forget to register the block in the `ModBlocks` class, just like in the [Creating Your First Block](../blocks/first-block) guide: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +## Using the Block Entity {#using-the-block-entity} + +Now that we have a block entity, we can use it to store the number of times the block has been right-clicked. We'll do this by adding a `clicks` field to the `CounterBlockEntity` class: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +The `markDirty` method, used in `incrementClicks`, tells the game that this entity's data has been updated; this will be useful when we add the methods to serialize the counter and load it back from the save file. + +Next, we need to increment this field every time the block is right-clicked. This is done by overriding the `onUse` method in the `CounterBlock` class: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Since the `BlockEntity` is not passed into the method, we use `world.getBlockEntity(pos)`, and if the `BlockEntity` is not valid, return from the method. + +!["You've clicked the block for the 6th time" message on screen after right-clicking](/assets/develop/blocks/block_entities_1.png) + +## Saving and Loading Data {#saving-loading} + +Now that we have a functional block, we should make it so that the counter doesn't reset between game restarts. This is done by serializing it into NBT when the game saves, and deserializing when it's loading. + +Serialization is done with the `writeNbt` method: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Here, we add the fields that should be saved into the passed `NbtCompound`: in the case of the counter block, that's the `clicks` field. + +Reading is similar, but instead of saving to the `NbtCompound` you get the values you saved previously, and save them in the BlockEntity's fields: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Now, if we save and reload the game, the counter block should continue from where it left off when saved. + +## Tickers {#tickers} + +The `BlockEntityProvider` interface also defines a method called `getTicker`, which can be used to run code every tick for each instance of the block. We can implement that by creating a static method that will be used as the `BlockEntityTicker`: + +The `getTicker` method should also check if the passed `BlockEntityType` is the same as the one we're using, and if it is, return the function that will be called every tick. Thankfully, there is a utility function that does the check in `BlockWithEntity`: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +`CounterBlockEntity::tick` is a reference to the static method `tick` we should create in the `CounterBlockEntity` class. Structuring it like this is not required, but it's a good practice to keep the code clean and organized. + +Let's say we want to make it so that the counter can only be incremented once every 10 ticks (2 times a second). We can do this by adding a `ticksSinceLast` field to the `CounterBlockEntity` class, and increasing it every tick: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Don't forget to serialize and deserialize this field! + +Now we can use `ticksSinceLast` to check if the counter can be increased in `incrementClicks`: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +::: tip +If the block entity does not seem to tick, try checking the registration code! It should pass the blocks that are valid for this entity into the `BlockEntityType.Builder`, or else it will give a warning in the console: + +```text +[13:27:55] [Server thread/WARN] (Minecraft) Block entity fabric-docs-reference:counter @ BlockPos{x=-29, y=125, z=18} state Block{fabric-docs-reference:counter_block} invalid for ticking: +``` + +::: diff --git a/versions/1.21/develop/blocks/block-entity-renderer.md b/versions/1.21/develop/blocks/block-entity-renderer.md new file mode 100644 index 000000000..d337f8e81 --- /dev/null +++ b/versions/1.21/develop/blocks/block-entity-renderer.md @@ -0,0 +1,101 @@ +--- +title: Block Entity Renderers +description: Learn how to spice rendering up with block entity renderers. +authors: + - natri0 + +search: false +--- + +# Block Entity Renderers {#block-entity-renderers} + +Sometimes, using Minecraft's model format is not enough. If you need to add dynamic rendering to it, you will need to use a `BlockEntityRenderer`. + +For example, let's make the Counter Block from the [Block Entities article](../blocks/block-entities) show the number of clicks on its top side. + +## Creating a BlockEntityRenderer {#creating-a-blockentityrenderer} + +First, we need to create a `BlockEntityRenderer` for our `CounterBlockEntity`. + +When creating a `BlockEntityRenderer` for the `CounterBlockEntity`, it's important to place the class in the appropriate source set, such as `src/client/`, if your project uses split source sets for client and server. Accessing rendering-related classes directly in the `src/main/` source set is not safe because those classes might be loaded on a server. + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +The new class has a constructor with `BlockEntityRendererFactory.Context` as a parameter. The `Context` has a few useful rendering utilities, like the `ItemRenderer` or `TextRenderer`. +Also, by including a constructor like this, it becomes possible to use the constructor as the `BlockEntityRendererFactory` functional interface itself: + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java) + +Add the entrypoint to the `fabric.mod.json` file, so that the renderer is registered. + +`BlockEntityRendererFactories` is a registry that maps each `BlockEntityType` with custom rendering code to its respective `BlockEntityRenderer`. + +## Drawing on Blocks {#drawing-on-blocks} + +Now that we have a renderer, we can draw. The `render` method is called every frame, and it's where the rendering magic happens. + +### Moving Around {#moving-around} + +First, we need to offset and rotate the text so that it's on the block's top side. + +::: info +As the name suggests, the `MatrixStack` is a _stack_, meaning that you can push and pop transformations. +A good rule-of-thumb is to push a new one at the beginning of the `render` method and pop it at the end, so that the rendering of one block doesn't affect others. + +More information about the `MatrixStack` can be found in the [Basic Rendering Concepts article](../rendering/basic-concepts). +::: + +To make the translations and rotations needed easier to understand, let's visualize them. In this picture, the green block is where the text would be drawn, by default in the furthest bottom-left point of the block: + +![Default rendering position](/assets/develop/blocks/block_entity_renderer_1.png) + +So first we need to move the text halfway across the block on the X and Z axes, and then move it up to the top of the block on the Y axis: + +![Green block in the topmost center point](/assets/develop/blocks/block_entity_renderer_2.png) + +This is done with a single `translate` call: + +```java +matrices.translate(0.5, 1, 0.5); +``` + +That's the _translation_ done, _rotation_ and _scale_ remain. + +By default, the text is drawn on the XY plane, so we need to rotate it 90 degrees around the X axis to make it face upwards on the XZ plane: + +![Green block in the topmost center point, facing upwards](/assets/develop/blocks/block_entity_renderer_3.png) + +The `MatrixStack` does not have a `rotate` function, instead we need to use `multiply` and `RotationAxis.POSITIVE_X`: + +```java +matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); +``` + +Now the text is in the correct position, but it's too large. The `BlockEntityRenderer` maps the whole block to a `[-0.5, 0.5]` cube, while the `TextRenderer` uses Y coordinates of `[0, 9]`. As such, we need to scale it down by a factor of 18: + +```java +matrices.scale(1/18f, 1/18f, 1/18f); +``` + +Now, the whole transformation looks like this: + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +### Drawing Text {#drawing-text} + +As mentioned earlier, the `Context` passed into the constructor of our renderer has a `TextRenderer` that we can use to draw text. For this example we'll save it in a field. + +The `TextRenderer` has methods to measure text (`getWidth`), which is useful for centering, and to draw it (`draw`). + +@[code transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +The `draw` method takes a lot of parameters, but the most important ones are: + +- the `Text` (or `String`) to draw; +- its `x` and `y` coordinates; +- the RGB `color` value; +- the `Matrix4f` describing how it should be transformed (to get one from a `MatrixStack`, we can use `.peek().getPositionMatrix()` to get the `Matrix4f` for the topmost entry). + +And after all this work, here's the result: + +![Counter Block with a number on top](/assets/develop/blocks/block_entity_renderer_4.png) diff --git a/versions/1.21/develop/blocks/blockstates.md b/versions/1.21/develop/blocks/blockstates.md new file mode 100644 index 000000000..03ff0a0f7 --- /dev/null +++ b/versions/1.21/develop/blocks/blockstates.md @@ -0,0 +1,129 @@ +--- +title: Block States +description: Learn why blockstates are a great way to add visual functionality to your blocks. +authors: + - IMB11 + +search: false +--- + +# Block States {#block-states} + +A block state is a piece of data attached to a singular block in the Minecraft world containing information on the block in the form of properties - some examples of properties vanilla stores in block states: + +- Rotation: Mostly used for logs and other natural blocks. +- Activated: Heavily used in redstone devices, and blocks such as the furnace or smoker. +- Age: Used in crops, plants, saplings, kelp etc. + +You can probably see why they are useful - they avoid the need to store NBT data in a block entity - reducing the world size, and preventing TPS issues! + +Blockstate definitions are found in the `assets//blockstates` folder. + +## Example: Pillar Block {#pillar-block} + + + +Minecraft has some custom classes already that allow you quickly create certain types of blocks - this example goes through the creation of a block with the `axis` property by creating a "Condensed Oak Log" block. + +The vanilla `PillarBlock` class allows the block to be placed in the X, Y or Z axis. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Pillar blocks have two textures, top and side - they use the `block/cube_column` model. + +As always, with all block textures, the texture files can be found in `assets//textures/block` + +Textures + +Since the pillar block has two positions, horizontal and vertical, we'll need to make two separate model files: + +- `condensed_oak_log_horizontal.json` which extends the `block/cube_column_horizontal` model. +- `condensed_oak_log.json` which extends the `block/cube_column` model. + +An example of the `condensed_oak_log_horizontal.json` file: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +For a more in-depth look at all the modifiers available in the blockstate files, check out the [Minecraft Wiki - Models (Block States)](https://minecraft.wiki/w/Tutorials/Models#Block_states) page. +::: + +Next, we need to create a blockstate file. The blockstate file is where the magic happens—pillar blocks have three axes, so we'll use specific models for the following situations: + +- `axis=x` - When the block is placed along the X axis, we will rotate the model to face the positive X direction. +- `axis=y` - When the block is placed along the Y axis, we will use the normal vertical model. +- `axis=z` - When the block is placed along the Z axis, we will rotate the model to face the positive X direction. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +As always, you'll need to create a translation for your block, and an item model which parents either of the two models. + +![Example of Pillar block in-game](/assets/develop/blocks/blockstates_1.png) + +## Custom Block States {#custom-block-states} + +Custom block states are great if your block has unique properties - sometimes you may find that your block can re-use vanilla properties. + +This example will create a unique boolean property called `activated` - when a player right-clicks on the block, the block will go from `activated=false` to `activated=true` - changing its texture accordingly. + +### Creating The Property {#creating-the-property} + +Firstly, you'll need to create the property itself - since this is a boolean, we'll use the `BooleanProperty.of` method. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Next, we have to append the property to the blockstate manager in the `appendProperties` method. You'll need to override the method to access the builder: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +You'll also have to set a default state for the `activated` property in the constructor of your custom block. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +::: warning +Don't forget to register your block using the custom class instead of `Block`! +::: + +### Using The Property {#using-the-property} + +This example flips the boolean `activated` property when the player interacts with the block. We can override the `onUse` method for this: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### Visualizing The Property {#visualizing-the-property} + +Before creating the blockstate file, you will need to provide textures for both the activated and deactivated states of the block, as well as the block model. + +Textures + +Use your knowledge of block models to create two models for the block: one for the activated state and one for the deactivated state. Once you've done that, you can begin creating the blockstate file. + +Since you created a new property, you will need to update the blockstate file for the block to account for that property. + +If you have multiple properties on a block, you'll need to account for all possible combinations. For example, `activated` and `axis` would lead to 6 combinations (two possible values for `activated` and three possible values for `axis`). + +Since this block only has two possible variants, as it only has one property (`activated`), the blockstate JSON will look something like this: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +Since the example block is a lamp, we also need to make it emit light when the `activated` property is true. This can be done through the block settings passed to the constructor when registering the block. + +You can use the `luminance` method to set the light level emitted by the block, we can create a static method in the `PrismarineLampBlock` class to return the light level based on the `activated` property, and pass it as a method reference to the `luminance` method: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +Once you've completed everything, the final result should look something like the following: + + diff --git a/versions/1.21/develop/blocks/first-block.md b/versions/1.21/develop/blocks/first-block.md new file mode 100644 index 000000000..8f3fa825b --- /dev/null +++ b/versions/1.21/develop/blocks/first-block.md @@ -0,0 +1,172 @@ +--- +title: Creating Your First Block +description: Learn how to create your first custom block in Minecraft. +authors: + - IMB11 + - xEobardThawne + - its-miroma + +search: false +--- + +# Creating Your First Block {#creating-your-first-block} + +Blocks are the building blocks of Minecraft (no pun intended) - just like everything else in Minecraft, they're stored in registries. + +## Preparing Your Blocks Class {#preparing-your-blocks-class} + +If you've completed the [Creating Your First Item](../items/first-item) page, this process will feel extremely familiar - you will need to create a method that registers your block, and its block item. + +You should put this method in a class called `ModBlocks` (or whatever you want to name it). + +Mojang does something extremely similar like this with vanilla blocks; you can refer to the `Blocks` class to see how they do it. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Just like with items, you need to ensure that the class is loaded so that all static fields containing your block instances are initialized. + +You can do this by creating a dummy `initialize` method, which can be called in your [mod's initializer](./getting-started/project-structure#entrypoints) to trigger the static initialization. + +::: info +If you are unaware of what static initialization is, it is the process of initializing static fields in a class. This is done when the class is loaded by the JVM, and is done before any instances of the class are created. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## Creating And Registering Your Block {#creating-and-registering-your-block} + +Similarly to items, blocks take a `Blocks.Settings` class in their constructor, which specifies properties about the block, such as its sound effects and mining level. + +We will not cover all the options here—you can view the class yourself to see the various options, which should be self-explanatory. + +For example purposes, we will be creating a simple block that has the properties of dirt, but is a different material. + +::: tip +You can also use `AbstractBlock.Settings.copy(AbstractBlock block)` to copy the settings of an existing block, in this case, we could have used `Blocks.DIRT` to copy the settings of dirt, but for example purposes we'll use the builder. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +To automatically create the block item, we can pass `true` to the `shouldRegisterItem` parameter of the `register` method we created in the previous step. + +### Adding Your Block to an Item Group {#adding-your-block-to-an-item-group} + +Since the `BlockItem` is automatically created and registered, to add it to an item group, you must use the `Block.asItem()` method to get the `BlockItem` instance. + +For this example, we'll use a custom item group created in the [Custom Item Groups](../items/custom-item-groups) page. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +You should now notice that your block is in the creative inventory, and can be placed in the world! + +![Block in world without suitable model or texture](/assets/develop/blocks/first_block_0.png) + +There are a few issues though - the block item is not named, and the block has no texture, block model or item model. + +## Adding Block Translations {#adding-block-translations} + +To add a translation, you must create a translation key in your translation file - `assets//lang/en_us.json`. + +Minecraft will use this translation in the creative inventory and other places where the block name is displayed, such as command feedback. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +You can either restart the game or build your mod and press F3+T to apply changes - and you should see that the block has a name in the creative inventory and other places such as the statistics screen. + +## Models and Textures {#models-and-textures} + +All block textures can be found in the `assets//textures/block` folder - an example texture for the "Condensed Dirt" block is free to use. + +Texture + +To make the texture show up in-game, you must create a block and item model which can be found in the respective locations for the "Condensed Dirt" block: + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +The item model is pretty simple, it can just use the block model as a parent - since most block models have support for being rendered in a GUI: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +The block model however, in our case, must parent the `block/cube_all` model: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +When you load into the game, you may notice that the texture is still missing. This is because you need to add a blockstate definition. + +## Creating the Block State Definition {#creating-the-block-state-definition} + +The blockstate definition is used to instruct the game on which model to render based on the current state of the block. + +For the example block, which doesn't have a complex blockstate, only one entry is needed in the definition. + +This file should be located in the `assets/mod_id/blockstates` folder, and its name should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_dirt`, the file should be named `condensed_dirt.json`. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +Blockstates are really complex, which is why they are addressed in an upcoming page: [Block States](./blockstates) + +Restarting the game, or reloading via F3+T to apply changes - you should be able to see the block texture in the inventory and physically in the world: + +![Block in world with suitable texture and model](/assets/develop/blocks/first_block_4.png) + +## Adding Block Drops {#adding-block-drops} + +When breaking the block in survival, you may see that the block does not drop - you might want this functionality, however to make your block drop as an item on break you must implement its loot table - the loot table file should be placed in the `data//loot_table/blocks/` folder. + +::: info +For a greater understanding of loot tables, you can refer to the [Minecraft Wiki - Loot Tables](https://minecraft.wiki/w/Loot_table) page. +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +This loot table provides a single item drop of the block item when the block is broken, and when it is blown up by an explosion. + +## Recommending a Harvesting Tool {#recommending-a-harvesting-tool} + +You may also want your block to be harvestable only by a specific tool - for example, you may want to make your block faster to harvest with a shovel. + +All the tool tags should be placed in the `data/minecraft/tags/block/mineable/` folder - where the name of the file depends on the type of tool used, one of the following: + +- `hoe.json` +- `axe.json` +- `pickaxe.json` +- `shovel.json` + +The contents of the file are quite simple - it is a list of items that should be added to the tag. + +This example adds the "Condensed Dirt" block to the `shovel` tag. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +If you wish for a tool to be required to mine the block, you'll want to append `.requiresTool()` to your block settings, as well as add the appropriate mining tag. + +## Mining Levels {#mining-levels} + +Similarly, the mining level tag can be found in the `data/minecraft/tags/block/` folder, and respects the following format: + +- `needs_stone_tool.json` - A minimum level of stone tools +- `needs_iron_tool.json` - A minimum level of iron tools +- `needs_diamond_tool.json` - A minimum level of diamond tools. + +The file has the same format as the harvesting tool file - a list of items to be added to the tag. + +## Extra Notes {#extra-notes} + +If you're adding multiple blocks to your mod, you may want to consider using [Data Generation](https://fabricmc.net/wiki/tutorial:datagen_setup) to automate the process of creating block and item models, blockstate definitions, and loot tables. diff --git a/versions/1.21/develop/codecs.md b/versions/1.21/develop/codecs.md new file mode 100644 index 000000000..6a4b7d648 --- /dev/null +++ b/versions/1.21/develop/codecs.md @@ -0,0 +1,464 @@ +--- +title: Codecs +description: A comprehensive guide for understanding and using Mojang's codec system for serializing and deserializing objects. +authors: + - enjarai + - Syst3ms + +search: false +--- + +# Codecs {#codecs} + +Codec is a system for easily serializing Java objects, and is included in Mojang's DataFixerUpper (DFU) +library, which is included with Minecraft. In a modding context they can be used as an alternative +to GSON and Jankson when reading and writing custom json files, though they're starting to become +more and more relevant, as Mojang is rewriting a lot of old code to use Codecs. + +Codecs are used in conjunction with another API from DFU, `DynamicOps`. A codec defines the structure of an object, while +dynamic ops are used to define a format to be serialized to and from, such as json or NBT. This means any codec can be +used with any dynamic ops, and vice versa, allowing for great flexibility. + +## Using Codecs {#using-codecs} + +### Serializing and Deserializing {#serializing-and-deserializing} + +The basic usage of a codec is to serialize and deserialize objects to and from a specific format. + +Since a few vanilla classes already have codecs defined, we can use those as an example. Mojang has also provided us +with two dynamic ops classes by default, `JsonOps` and `NbtOps`, which tend to cover most use cases. + +Now, let's say we want to serialize a `BlockPos` to json and back. We can do this using the codec statically stored +at `BlockPos.CODEC` with the `Codec#encodeStart` and `Codec#parse` methods, respectively. + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// Serialize the BlockPos to a JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +When using a codec, values are returned in the form of a `DataResult`. This is a wrapper that can represent either a +success or a failure. We can use this in several ways: If we just want our serialized value, `DataResult#result` will +simply return an `Optional` containing our value, while `DataResult#resultOrPartial` also lets us supply a function to +handle any errors that may have occurred. The latter is particularly useful for custom datapack resources, where we'd +want to log errors without causing issues elsewhere. + +So let's grab our serialized value and turn it back into a `BlockPos`: + +```java +// When actually writing a mod, you'll want to properly handle empty Optionals of course +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Here we have our json value, which should correspond to `[1, 2, 3]`, +// as that's the format used by the BlockPos codec. +LOGGER.info("Serialized BlockPos: {}", json); + +// Now we'll deserialize the JsonElement back into a BlockPos +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// Again, we'll just grab our value from the result +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// And we can see that we've successfully serialized and deserialized our BlockPos! +LOGGER.info("Deserialized BlockPos: {}", pos); +``` + +### Built-in Codecs {#built-in-codecs} + +As mentioned earlier, Mojang has already defined codecs for several vanilla and standard Java classes, including but not +limited to `BlockPos`, `BlockState`, `ItemStack`, `Identifier`, `Text`, and regex `Pattern`s. Codecs for Mojang's own +classes are usually found as static fields named `CODEC` on the class itself, while most others are kept in the `Codecs` +class. It should also be noted that all vanilla registries contain a `getCodec()` method, for example, you +can use `Registries.BLOCK.getCodec()` to get a `Codec` which serializes to the block id and back. + +The Codec API itself also contains some codecs for primitive types, such as `Codec.INT` and `Codec.STRING`. These are +available as statics on the `Codec` class, and are usually used as the base for more complex codecs, as explained below. + +## Building Codecs {#building-codecs} + +Now that we've seen how to use codecs, let's take a look at how we can build our own. Suppose we have the following +class, and we want to deserialize instances of it from json files: + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +The corresponding json file might look something like this: + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +We can make a codec for this class by putting together multiple smaller codecs into a larger one. In this case, we'll +need one for each field: + +- a `Codec` +- a `Codec` +- a `Codec>` + +We can get the first one from the aforementioned primitive codecs in the `Codec` class, specifically `Codec.INT`. While +the second one can be obtained from the `Registries.ITEM` registry, which has a `getCodec()` method that returns a +`Codec`. We don't have a default codec for `List`, but we can make one from `BlockPos.CODEC`. + +### Lists {#lists} + +`Codec#listOf` can be used to create a list version of any codec: + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +It should be noted that codecs created in this way will always deserialize to an `ImmutableList`. If you need a mutable +list instead, you can make use of [xmap](#mutually-convertible-types) to convert to one during +deserialization. + +### Merging Codecs for Record-Like Classes {#merging-codecs-for-record-like-classes} + +Now that we have separate codecs for each field, we can combine them into one codec for our class using +a `RecordCodecBuilder`. This assumes that our class has a constructor containing every field we want to serialize, and +that every field has a corresponding getter method. This makes it perfect to use in conjunction with records, but it can +also be used with regular classes. + +Let's take a look at how to create a codec for our `CoolBeansClass`: + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // Up to 16 fields can be declared here +).apply(instance, CoolBeansClass::new)); +``` + +Each line in the group specifies a codec, a field name, and a getter method. The `Codec#fieldOf` call is used to convert +the codec into a [map codec](#mapcodec), and the `forGetter` call specifies the getter method used to retrieve the value +of the field from an instance of the class. Meanwhile, the `apply` call specifies the constructor used to create new +instances. Note that the order of the fields in the group should be the same as the order of the arguments in the +constructor. + +You can also use `Codec#optionalFieldOf` in this context to make a field optional, as explained in +the [Optional Fields](#optional-fields) section. + +### MapCodec, Not to Be Confused With Codec<Map> {#mapcodec} + +Calling `Codec#fieldOf` will convert a `Codec` into a `MapCodec`, which is a variant, but not direct +implementation of `Codec`. `MapCodec`s, as their name suggests are guaranteed to serialize into a +key to value map, or its equivalent in the `DynamicOps` used. Some functions may require one over a regular codec. + +This particular way of creating a `MapCodec` essentially boxes the value of the source codec +inside a map, with the given field name as the key. For example, a `Codec` +when serialized into json would look like this: + +```json +[1, 2, 3] +``` + +But when converted into a `MapCodec` using `BlockPos.CODEC.fieldOf("pos")`, it would look like this: + +```json +{ + "pos": [1, 2, 3] +} +``` + +While the most common use for map codecs is to be merged with other map codecs to construct a codec for a full class worth of +fields, as explained in the [Merging Codecs for Record-like Classes](#merging-codecs-for-record-like-classes) section +above, they can also be turned back into regular codecs using `MapCodec#codec`, which will retain the same behavior of +boxing their input value. + +#### Optional Fields {#optional-fields} + +`Codec#optionalFieldOf` can be used to create an optional map codec. This will, when the specified field is not present +in the container during deserialization, either be deserialized as an empty `Optional` or a specified default value. + +```java +// Without a default value +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// With a default value +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +Do note that optional fields will silently ignore any errors that may occur during deserialization. This means that if +the field is present, but the value is invalid, the field will always be deserialized as the default value. + +**Since 1.20.2**, Minecraft itself (not DFU!) does however provide `Codecs#createStrictOptionalFieldCodec`, +which fails to deserialize at all if the field value is invalid. + +### Constants, Constraints, and Composition {#constants-constraints-composition} + +#### Unit {#unit} + +`Codec.unit` can be used to create a codec that always deserializes to a constant value, regardless of the input. When +serializing, it will do nothing. + +```java +Codec theMeaningOfCodec = Codec.unit(42); +``` + +#### Numeric Ranges {#numeric-ranges} + +`Codec.intRange` and its pals, `Codec.floatRange` and `Codec.doubleRange` can be used to create a codec that only +accepts number values within a specified **inclusive** range. This applies to both serialization and deserialization. + +```java +// Can't be more than 2 +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Pair {#pair} + +`Codec.pair` merges two codecs, `Codec` and `Codec`, into a `Codec>`. Keep in mind it only works +properly with codecs that serialize to a specific field, such as [converted `MapCodec`s](#mapcodec) or +[record codecs](#merging-codecs-for-record-like-classes). +The resulting codec will serialize to a map combining the fields of both codecs used. + +For example, running this code: + +```java +// Create two separate boxed codecs +Codec firstCodec = Codec.INT.fieldOf("i_am_number").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("this_statement_is_false").codec(); + +// Merge them into a pair codec +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// Use it to serialize data +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +Will output this json: + +```json +{ + "i_am_number": 23, + "this_statement_is_false": true +} +``` + +#### Either {#either} + +`Codec.either` combines two codecs, `Codec` and `Codec`, into a `Codec>`. The resulting codec will, +during deserialization, attempt to use the first codec, and _only if that fails_, attempt to use the second one. +If the second one also fails, the error of the _second_ codec will be returned. + +#### Maps {#maps} + +For processing maps with arbitrary keys, such as `HashMap`s, `Codec.unboundedMap` can be used. This returns a +`Codec>` for a given `Codec` and `Codec`. The resulting codec will serialize to a json object or +whatever equivalent is available for the current dynamic ops. + +Due to limitations of json and nbt, the key codec used _must_ serialize to a string. This includes codecs for types that +aren't strings themselves, but do serialize to them, such as `Identifier.CODEC`. See the example below: + +```java +// Create a codec for a map of identifiers to integers +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// Use it to serialize data +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "number"), 23, + new Identifier("example", "the_cooler_number"), 42 +)); +``` + +This will output this json: + +```json +{ + "example:number": 23, + "example:the_cooler_number": 42 +} +``` + +As you can see, this works because `Identifier.CODEC` serializes directly to a string value. A similar effect can be +achieved for simple objects that don't serialize to strings by using [xmap & friends](#mutually-convertible-types) to +convert them. + +### Mutually Convertible Types {#mutually-convertible-types} + +#### `xmap` {#xmap} + +Say we have two classes that can be converted to each other, but don't have a parent-child relationship. For example, +a vanilla `BlockPos` and `Vec3d`. If we have a codec for one, we can use `Codec#xmap` to create a codec for the other by +specifying a conversion function for each direction. + +`BlockPos` already has a codec, but let's pretend it doesn't. We can create one for it by basing it on the +codec for `Vec3d` like this: + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // Convert Vec3d to BlockPos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // Convert BlockPos to Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// When converting an existing class (`X` for example) +// to your own class (`Y`) this way, it may be nice to +// add `toX` and static `fromX` methods to `Y` and use +// method references in your `xmap` call. +``` + +#### flatComapMap, comapFlatMap, and flatXMap {#flatcomapmap-comapflatmap-flatxmap} + +`Codec#flatComapMap`, `Codec#comapFlatMap` and `flatXMap` are similar to xmap, but they allow one or both of the +conversion functions to return a DataResult. This is useful in practice because a specific object instance may not +always be valid for conversion. + +Take for example vanilla `Identifier`s. While all identifiers can be turned into strings, not all strings are valid identifiers, +so using xmap would mean throwing ugly exceptions when the conversion fails. +Because of this, its built-in codec is actually a `comapFlatMap` on `Codec.STRING`, nicely +illustrating how to use it: + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Not a valid resource location: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +While these methods are really helpful, their names are a bit confusing, so here's a table to help you remember which +one to use: + +| Method | A -> B always valid? | B -> A always valid? | +| ----------------------- | -------------------- | -------------------- | +| `Codec#xmap` | Yes | Yes | +| `Codec#comapFlatMap` | No | Yes | +| `Codec#flatComapMap` | Yes | No | +| `Codec#flatXMap` | No | No | + +### Registry Dispatch {#registry-dispatch} + +`Codec#dispatch` let us define a registry of codecs and dispatch to a specific one based on the value of a +field in the serialized data. This is very useful when deserializing objects that have different fields depending on +their type, but still represent the same thing. + +For example, say we have an abstract `Bean` interface with two implementing classes: `StringyBean` and `CountingBean`. To serialize +these with a registry dispatch, we'll need a few things: + +- Separate codecs for every type of bean. +- A `BeanType` class or record that represents the type of bean, and can return the codec for it. +- A function on `Bean` to retrieve its `BeanType`. +- A map or registry to map `Identifier`s to `BeanType`s. +- A `Codec>` based on this registry. If you use a `net.minecraft.registry.Registry`, one can be easily made + using `Registry#getCodec`. + +With all of this, we can create a registry dispatch codec for beans: + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// Now we can create a codec for bean types +// based on the previously created registry +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// And based on that, here's our registry dispatch codec for beans! +// The first argument is the field name for the bean type. +// When left out, it will default to "type". +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::codec); +``` + +Our new codec will serialize beans to json like this, grabbing only fields that are relevant to their specific type: + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "This bean is stringy!" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### Recursive Codecs {#recursive-codecs} + +Sometimes it is useful to have a codec that uses _itself_ to decode specific fields, for example when dealing with certain recursive data structures. In vanilla code, this is used for `Text` objects, which may store other `Text`s as children. Such a codec can be constructed using `Codec#recursive`. + +For example, let's try to serialize a singly-linked list. This way of representing lists consists of a bunch of nodes that hold both a value and a reference to the next node in the list. The list is then represented by its first node, and traversing the list is done by following the next node until none remain. Here is a simple implementation of nodes that store integers. + +```java +public record ListNode(int value, ListNode next) {} +``` + +We can't construct a codec for this by ordinary means, because what codec would we use for the `next` field? We would need a `Codec`, which is what we are in the middle of constructing! `Codec#recursive` lets us achieve that using a magic-looking lambda: + +```java +Codec codec = Codec.recursive( + "ListNode", // a name for the codec + selfCodec -> { + // Here, `selfCodec` represents the `Codec`, as if it was already constructed + // This lambda should return the codec we wanted to use from the start, + // that refers to itself through `selfCodec` + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // the `next` field will be handled recursively with the self-codec + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +A serialized `ListNode` may then look like this: + +```json +{ + "value": 2, + "next": { + "value": 3, + "next": { + "value": 5 + } + } +} +``` + +## References {#references} + +- A much more comprehensive documentation of Codecs and related APIs can be found at the + [Unofficial DFU JavaDoc](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec). +- The general structure of this guide was heavily inspired by the + [Forge Community Wiki's page on Codecs](https://forge.gemwire.uk/wiki/Codecs), a more Forge-specific take on the same + topic. diff --git a/versions/1.21/develop/commands/arguments.md b/versions/1.21/develop/commands/arguments.md new file mode 100644 index 000000000..a5507385b --- /dev/null +++ b/versions/1.21/develop/commands/arguments.md @@ -0,0 +1,72 @@ +--- +title: Command Arguments +description: Learn how to create commands with complex arguments. + +search: false +--- + +# Command Arguments {#command-arguments} + +Arguments are used in most of the commands. Sometimes they can be optional, which means if you do not provide that +argument, +the command will also run. One node may have multiple argument types, but be aware that there is a possibility of +ambiguity, which should be avoided. + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +In this case, after the command text `/command_with_arg`, you should type an integer. For example, if you +run `/command_with_arg 3`, you will get the feedback message: + +> Called /command_with_arg with value = 3 + +If you type `/command_with_arg` without arguments, the command cannot be correctly parsed. + +Then we add an optional second argument: + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Now you can type one or two integers. If you give one integer, a feedback text with a single value is printed. If you +provide two integers, a feedback text with two values will be printed. + +You may find it unnecessary to specify similar executions twice. Therefore, we can create a method that will be used in +both executions. + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Custom Argument Types {#custom-argument-types} + +If vanilla does not have the argument type you need, you can create your own. To do this, you need to create a class that inherits the `ArgumentType` interface where `T` is the type of the argument. + +You will need to implement the `parse` method, which will parse the input string into the desired type. + +For example, you can create an argument type that parses a `BlockPos` from a string with the following format: `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Registering Custom Argument Types {#registering-custom-argument-types} + +::: warning +You need to register the custom argument type on both the server and the client or else the command will not work! +::: + +You can register your custom argument type in the `onInitialize` method of your [mod's initializer](./getting-started/project-structure#entrypoints) using the `ArgumentTypeRegistry` class: + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Using Custom Argument Types {#using-custom-argument-types} + +We can use our custom argument type in a command - by passing an instance of it into the `.argument` method on the command builder. + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Running the command, we can test whether or not the argument type works: + +![Invalid argument](/assets/develop/commands/custom-arguments_fail.png) + +![Valid argument](/assets/develop/commands/custom-arguments_valid.png) + +![Command result](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/develop/commands/basics.md b/versions/1.21/develop/commands/basics.md new file mode 100644 index 000000000..db62bdcdd --- /dev/null +++ b/versions/1.21/develop/commands/basics.md @@ -0,0 +1,212 @@ +--- +title: Creating Commands +description: Create commands with complex arguments and actions. +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple + +search: false +--- + +# Creating Commands {#creating-commands} + +Creating commands can allow a mod developer to add functionality that can be used through a command. This tutorial will +teach you how to register commands and the general command structure of Brigadier. + +::: info +Brigadier is a command parser and dispatcher written by Mojang for Minecraft. It is a tree-based command library where +you build a tree of commands and arguments. + +Brigadier is open-source: +::: + +## The `Command` Interface {#the-command-interface} + +`com.mojang.brigadier.Command` is a functional interface, which runs some specific code, and throws a +`CommandSyntaxException` in certain cases. It has a generic type `S`, which defines the type of the _command source_. +The command +source provides some context in which a command was run. In Minecraft, the command source is typically a +`ServerCommandSource` which can represent a server, a command block, a remote connection (RCON), a player or an entity. + +The single method in `Command`, `run(CommandContext)` takes a `CommandContext` as the sole parameter and returns +an integer. The command context holds your command source of `S` and allows you to obtain arguments, look at the parsed +command nodes and see the input used in this command. + +Like other functional interfaces, it is usually used as a lambda or a method reference: + +```java +Command command = context -> { + return 0; +}; +``` + +The integer can be considered the result of the command. Typically values less than or equal to zero mean a command has failed and will +do nothing. Positive values mean the command was successful and did something. Brigadier provides a constant to indicate +success; `Command#SINGLE_SUCCESS`. + +### What Can the `ServerCommandSource` Do? {#what-can-the-servercommandsource-do} + +A `ServerCommandSource` provides some additional implementation-specific context when a command is run. This includes +the +ability to get the entity that executed the command, the world the command was run in or the server the command was run +on. + +You can access the command source from a command context by calling `getSource()` on the `CommandContext` instance. + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## Registering a Basic Command {#registering-a-basic-command} + +Commands are registered within the `CommandRegistrationCallback` provided by the Fabric API. + +::: info +For information on registering callbacks, please see the [Events](../events) guide. +::: + +The event should be registered in your [mod's initializer](./getting-started/project-structure#entrypoints). + +The callback has three parameters: + +- `CommandDispatcher dispatcher` - Used to register, parse and execute commands. `S` is the type + of command source the command dispatcher supports. +- `CommandRegistryAccess registryAccess` - Provides an abstraction to registries that may be passed to certain command + argument methods +- `CommandManager.RegistrationEnvironment environment` - Identifies the type of server the commands are being registered + on. + +In the mod's initializer, we just register a simple command: + +@[code lang=java transcludeWith=:::test_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +In the `sendFeedback()` method, the first parameter is the text to be sent, which is a `Supplier` to avoid +instantiating Text objects when not needed. + +The second parameter determines whether to broadcast the feedback to other +operators. Generally, if the command is to query something without actually affecting the world, such as query the +current time or some player's score, it should be `false`. If the command does something, such as changing the +time or modifying someone's score, it should be `true`. + +If the command fails, instead of calling `sendFeedback()`, you may directly throw any exception and the server or client +will handle it appropriately. + +`CommandSyntaxException` is generally thrown to indicate syntax errors in commands or arguments. You can also implement +your own exception. + +To execute this command, you must type `/test_command`, which is case-sensitive. + +::: info +From this point onwards, we will be extracting the logic written within the lambda passed into `.execute()` builders into individual methods. We can then pass a method reference to `.execute()`. This is done for clarity. +::: + +### Registration Environment {#registration-environment} + +If desired, you can also make sure a command is only registered under some specific circumstances, for example, only in +the dedicated environment: + +@[code lang=java highlight={2} transcludeWith=:::dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Command Requirements {#command-requirements} + +Let's say you have a command that you only want operators to be able to execute. This is where the `requires()` method +comes into play. The `requires()` method has one argument of a `Predicate` which will supply a `ServerCommandSource` +to test with and determine if the `CommandSource` can execute the command. + +@[code lang=java highlight={3} transcludeWith=:::required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +This command will only execute if the source of the command is a level 2 operator at a minimum, including command +blocks. Otherwise, the command is not registered. + +This has the side effect of not showing this command in tab completion to anyone who is not a level 2 operator. This is +also why you cannot tab-complete most commands when you do not enable cheats. + +### Sub Commands {#sub-commands} + +To add a sub command, you register the first literal node of the command normally. To have a sub command, you have to append the next literal node to the existing node. + +@[code lang=java highlight={3} transcludeWith=:::sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Similar to arguments, sub command nodes can also be set optional. In the following case, both `/command_two` +and `/command_two sub_command_two` will be valid. + +@[code lang=java highlight={2,8} transcludeWith=:::sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Client Commands {#client-commands} + +Fabric API has a `ClientCommandManager` in `net.fabricmc.fabric.api.client.command.v2` package that can be used to register client-side commands. The code should exist only in client-side code. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## Command Redirects {#command-redirects} + +Command redirects - also known as aliases - are a way to redirect the functionality of one command to another. This is useful for when you want to change the name of a command, but still want to support the old name. + +::: warning +Brigadier [will only redirect command nodes with arguments](https://github.com/Mojang/brigadier/issues/46). If you want to redirect a command node without arguments, provide an `.executes()` builder with a reference to the same logic as outlined in the example. +::: + +@[code lang=java transcludeWith=:::redirect_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_redirected_by](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## FAQ {#faq} + +### Why Does My Code Not Compile? {#why-does-my-code-not-compile} + +- Catch or throw a `CommandSyntaxException` - `CommandSyntaxException` is not a `RuntimeException`. If you throw it, + that should be in methods that throw `CommandSyntaxException` in method signatures, or it should be caught. + Brigadier will handle the checked exceptions and forward the proper error message in the game for you. + +- Issues with generics - You may have an issue with generics once in a while. If you are registering server + commands (which are most of the case), make sure you are using `CommandManager.literal` + or `CommandManager.argument` instead of `LiteralArgumentBuilder.literal` or `RequiredArgumentBuilder.argument`. + +- Check `sendFeedback()` method - You may have forgotten to provide a boolean as the second argument. Also remember + that, since Minecraft 1.20, the first parameter is `Supplier` instead of `Text`. + +- A Command should return an integer - When registering commands, the `executes()` method accepts a `Command` object, + which is usually a lambda. The lambda should return an integer, instead of other types. + +### Can I Register Commands at Runtime? {#can-i-register-commands-at-runtime} + +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +After that, you need to send the command tree to every player again +using `CommandManager.sendCommandTree(ServerPlayerEntity)`. + +This is required because the client locally caches the command tree it receives during login (or when operator packets +are sent) for local completions-rich error messages. +::: + +### Can I Unregister Commands at Runtime? {#can-i-unregister-commands-at-runtime} + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +To keep things simple, you need to use reflection on Brigadier and remove nodes. After this, you need to send the +command tree to every player again using `sendCommandTree(ServerPlayerEntity)`. + +If you don't send the updated command tree, the client may think a command still exists, even though the server will +fail execution. +::: diff --git a/versions/1.21/develop/commands/suggestions.md b/versions/1.21/develop/commands/suggestions.md new file mode 100644 index 000000000..dfbc5a9c7 --- /dev/null +++ b/versions/1.21/develop/commands/suggestions.md @@ -0,0 +1,51 @@ +--- +title: Command Suggestions +description: Learn how to suggest command argument values to users. +authors: + - IMB11 + +search: false +--- + +# Command Suggestions {#command-suggestions} + +Minecraft has a powerful command suggestion system that's used in many places, such as the `/give` command. This system allows you to suggest values for command arguments to the user, which they can then select from - it's a great way to make your commands more user-friendly and ergonomic. + +## Suggestion Providers {#suggestion-providers} + +A `SuggestionProvider` is used to make a list of suggestions that will be sent to the client. A suggestion provider is a functional interface that takes a `CommandContext` and a `SuggestionBuilder` and returns some `Suggestions`. The `SuggestionProvider` returns a `CompletableFuture` as the suggestions may not be available immediately. + +## Using Suggestion Providers {#using-suggestion-providers} + +To use a suggestion provider, you need to call the `suggests` method on the argument builder. This method takes a `SuggestionProvider` and returns the modified argument builder with the suggestion provider attached. + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Built-in Suggestion Providers {#built-in-suggestion-providers} + +There are a few built-in suggestion providers that you can use: + +| Suggestion Provider | Description | +| ----------------------------------------- | -------------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | Suggests all entities that can be summoned. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | Suggests all sounds that can be played. | +| `LootCommand.SUGGESTION_PROVIDER` | Suggests all loot tables that are available. | +| `SuggestionProviders.ALL_BIOMES` | Suggests all biomes that are available. | + +## Creating a Custom Suggestion Provider {#creating-a-custom-suggestion-provider} + +If a built-in provider doesn't satisfy your needs, you can create your own suggestion provider. To do this, you need to create a class that implements the `SuggestionProvider` interface and override the `getSuggestions` method. + +For this example, we'll make a suggestion provider that suggests all the player usernames on the server. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +To use this suggestion provider, you would simply pass an instance of it into the `.suggests` method on the argument builder. + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Obviously, suggestion providers can be more complex, since they can also read the command context to provide suggestions based on the command's state - such as the arguments that have already been provided. + +This could be in the form of reading the player's inventory and suggesting items, or entities that are nearby the player. diff --git a/versions/1.21/develop/data-generation/advancements.md b/versions/1.21/develop/data-generation/advancements.md new file mode 100644 index 000000000..1176a1e0a --- /dev/null +++ b/versions/1.21/develop/data-generation/advancements.md @@ -0,0 +1,169 @@ +--- +title: Advancement Generation +description: A guide to setting up advancement generation with datagen. +authors: + - skycatminepokie + - MattiDragon + - Spinoscythe +authors-nogithub: + - jmanc3 + - mcrafterzz + +search: false +--- + +# Advancement Generation {#advancement-generation} + +::: info PREREQUISITES +Make sure you've completed the [datagen setup](./setup) process first. +::: + +## Setup {#setup} + +First, we need to make our provider. Create a class that `extends FabricAdvancementProvider` and fill out the base methods: + +@[code lang=java transcludeWith=:::datagen-advancements:provider-start](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. + +@[code lang=java transclude={24-24}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Advancement Structure {#advancement-structure} + +An advancement is made up a few different components. Along with the requirements, called "criterion," it may have: + +- An `AdvancementDisplay` that tells the game how to show the advancement to players, +- `AdvancementRequirements`, which are lists of lists of criteria, requiring at least one criterion from each sub-list to be completed, +- `AdvancementRewards`, which the player receives for completing the advancement. +- A `CriterionMerger`, which tells the advancement how to handle multiple criterion, and +- A parent `Advancement`, which organizes the hierarchy you see on the "Advancements" screen. + +## Simple Advancements {#simple-advancements} + +Here's a simple advancement for getting a dirt block: + +@[code lang=java transcludeWith=:::datagen-advancements:simple-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +::: details JSON Output +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/fabric-docs-reference/get_dirt.json) +::: + +## One More Example {#one-more-example} + +Just to get the hang of it, let's add one more advancement. We'll practice adding rewards, using multiple criterion, and assigning parents: + +@[code lang=java transcludeWith=:::datagen-advancements:second-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Don't forget to generate them! Use the terminal command below or the run configuration in IntelliJ. + +::: code-group + +```sh [Windows] +gradlew runDatagen +``` + +```sh [Linux] +./gradlew runDatagen +``` + +::: + +## Custom Criteria {#custom-criteria} + +::: warning +While datagen can be on the client side, `Criterion`s and `Predicate`s are in the main source set (both sides), since the server needs to trigger and evaluate them. +::: + +### Definitions {#definitions} + +A **criterion** (plural: criteria) is something a player can do (or that can happen to a player) that may be counted towards an advancement. The game comes with many [criteria](https://minecraft.wiki/w/Advancement_definition#List_of_triggers), which can be found in the `net.minecraft.advancement.criterion` package. Generally, you'll only need a new criterion if you implement a custom mechanic into the game. + +**Conditions** are evaluated by criteria. A criterion is only counted if all the relevant conditions are met. Conditions are usually expressed with a predicate. + +A **predicate** is something that takes a value and returns a `boolean`. For example, a `Predicate` might return `true` if the item is a diamond, while a `Predicate` might return `true` if the entity is not hostile to villagers. + +### Creating Custom Criteria {#creating-custom-criteria} + +First, we'll need a new mechanic to implement. Let's tell the player what tool they used every time they break a block. + +@[code lang=java transcludeWith=:::datagen-advancements:entrypoint](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Note that this code is really bad. The `HashMap` is not stored anywhere persistent, so it will be reset every time the game is restarted. It's just to show off `Criterion`s. Start the game and try it out! + +Next, let's create our custom criterion, `UseToolCriterion`. It's going to need its own `Conditions` class to go with it, so we'll make them both at once: + +@[code lang=java transcludeWith=:::datagen-advancements:criterion-base](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Whew, that's a lot! Let's break it down. + +- `UseToolCriterion` is an `AbstractCriterion`, which `Conditions` can apply to. +- `Conditions` has a `playerPredicate` field. All `Conditions` should have a player predicate (technically a `LootContextPredicate`). +- `Conditions` also has a `CODEC`. This `Codec` is simply the codec for its one field, `playerPredicate`, with extra instructions to convert between them (`xmap`). + +::: info +To learn more about codecs, see the [Codecs](../codecs) page. +::: + +We're going to need a way to check if the conditions are met. Let's add a helper method to `Conditions`: + +@[code lang=java transcludeWith=:::datagen-advancements:conditions-test](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Now that we've got a criterion and its conditions, we need a way to trigger it. Add a trigger method to `UseToolCriterion`: + +@[code lang=java transcludeWith=:::datagen-advancements:criterion-trigger](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Almost there! Next, we need an instance of our criterion to work with. Let's put it in a new class, called `ModCriteria`. + +@[code lang=java transcludeWith=:::datagen-advancements:mod-criteria](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +To make sure that our criteria are initialized at the right time, add a blank `init` method: + +@[code lang=java transcludeWith=:::datagen-advancements:mod-criteria-init](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +And call it in your mod initializer: + +@[code lang=java transcludeWith=:::datagen-advancements:call-init](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Finally, we need to trigger our criteria. Add this to where we sent a message to the player in the main mod class. + +@[code lang=java transcludeWith=:::datagen-advancements:trigger-criterion](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Your shiny new criterion is now ready to use! Let's add it to our provider: + +@[code lang=java transcludeWith=:::datagen-advancements:custom-criteria-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Run the datagen task again, and you've got your new advancement to play with! + +## Conditions with Parameters {#conditions-with-parameters} + +This is all well and good, but what if we want to only grant an advancement once we've done something 5 times? And why not another one at 10 times? For this, we need to give our condition a parameter. You can stay with `UseToolCriterion`, or you can follow along with a new `ParameterizedUseToolCriterion`. In practice, you should only have the parameterized one, but we'll keep both for this tutorial. + +Let's work bottom-up. We'll need to check if the requirements are met, so let's edit our `Condtions#requirementsMet` method: + +@[code lang=java transcludeWith=:::datagen-advancements:new-requirements-met](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +`requiredTimes` doesn't exist, so make it a parameter of `Conditions`: + +@[code lang=java transcludeWith=:::datagen-advancements:new-parameter](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Now our codec is erroring. Let's write a new codec for the new changes: + +@[code lang=java transcludeWith=:::datagen-advancements:new-codec](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Moving on, we now need to fix our `trigger` method: + +@[code lang=java transcludeWith=:::datagen-advancements:new-trigger](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +If you've made a new criterion, we need to add it to `ModCriteria` + +@[code lang=java transcludeWith=:::datagen-advancements:new-mod-criteria](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +And call it in our main class, right where the old one is: + +@[code lang=java transcludeWith=:::datagen-advancements:trigger-new-criterion](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Add the advancement to your provider: + +@[code lang=java transcludeWith=:::datagen-advancements:new-custom-criteria-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Run datagen again, and you're finally done! diff --git a/versions/1.21/develop/data-generation/loot-tables.md b/versions/1.21/develop/data-generation/loot-tables.md new file mode 100644 index 000000000..943824071 --- /dev/null +++ b/versions/1.21/develop/data-generation/loot-tables.md @@ -0,0 +1,59 @@ +--- +title: Loot Table Generation +description: A guide to setting up loot table generation with datagen. +authors: + - skycatminepokie + - Spinoscythe + - Alphagamer47 + - matthewperiut + - JustinHuPrime +authors-nogithub: + - mcrafterzz + - jmanc3 + +search: false +--- + +# Loot Table Generation {#loot-table-generation} + +::: info PREREQUISITES +Make sure you've completed the [datagen setup](./setup) process first. +::: + +You will need different providers (classes) for blocks, chests, and entities. Remember to add them all to your pack in your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. + +@[code lang=java transclude={32-33}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Loot Tables Explained {#loot-tables-explained} + +**Loot tables** define what you get from breaking a block (not including contents, like in chests), killing an entity, or opening a newly-generated container. Each loot table has **pools** from which items are selected. Loot tables also have **functions**, which modify the resulting loot in some way. + +Loot pools have **entries**, **conditions**, functions, **rolls**, and **bonus rolls**. Entries are groups, sequences, or possibilities of items, or just items. Conditions are things that are tested for in the world, such as enchantments on a tool or a random chance. The minimum number of entries chosen by a pool are called rolls, and anything over that is called a bonus roll. + +## Blocks {#blocks} + +In order for blocks to drop items - including itself - we need to make a loot table. Create a class that `extends FabricBlockLootTableProvider`: + +@[code lang=java transcludeWith=:::datagen-loot-tables:block-provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java) + +Make sure to add this provider to your pack! + +There's a lot of helper methods available to help you build your loot tables. We won't go over all of them, so make sure to check them out in your IDE. + +Let's add a few drops in the `generate` method: + +@[code lang=java transcludeWith=:::datagen-loot-tables:block-drops](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java) + +## Chests {#chests} + +Chest loot is a little bit tricker than block loot. Create a class that `extends SimpleFabricLootTableProvider` similar to the example below **and add it to your pack**. + +@[code lang=java transcludeWith=:::datagen-loot-tables:chest-provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java) + +We'll need a `RegistryKey` for our loot table. Let's put that in a new class called `ModLootTables`. Make sure this is in your `main` source set if you're using split sources. + +@[code lang=java transcludeWith=:::datagen-loot-tables:mod-loot-tables](@/reference/1.21/src/main/java/com/example/docs/ModLootTables.java) + +Then, we can generate a loot table inside the `generate` method of your provider. + +@[code lang=java transcludeWith=:::datagen-loot-tables:chest-loot](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java) diff --git a/versions/1.21/develop/data-generation/recipes.md b/versions/1.21/develop/data-generation/recipes.md new file mode 100644 index 000000000..b82dc9a80 --- /dev/null +++ b/versions/1.21/develop/data-generation/recipes.md @@ -0,0 +1,52 @@ +--- +title: Recipe Generation +description: A guide to setting up recipe generation with datagen. +authors: + - skycatminepokie + - Spinoscythe +authors-nogithub: + - mcrafterzz + - jmanc3 + +search: false +--- + +# Recipe Generation {#recipe-generation} + +::: info PREREQUISITES +Make sure you've completed the [datagen setup](./setup) process first. +::: + +## Setup {#setup} + +First, we'll need our provider. Make a class that `extends FabricRecipeProvider`. All our recipe generation will happen inside the `generate` method of our provider. + +@[code lang=java transcludeWith=:::datagen-recipes:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. + +@[code lang=java transclude={30-30}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Shapeless Recipes {#shapeless-recipes} + +Shapeless recipes are fairly straightforward. Just add them to the `generate` method in your provider: + +@[code lang=java transcludeWith=:::datagen-recipes:shapeless](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +## Shaped Recipes {#shaped-recipes} + +For a shaped recipe, you define the shape using a `String`, then define what each `char` in the `String` represents. + +@[code lang=java transcludeWith=:::datagen-recipes:shaped](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +::: tip +There's a lot of helper methods for creating common recipes. Check out what `RecipeProvider` has to offer! Use `Alt + 7` in IntelliJ to open the structure of a class, including a method list. +::: + +## Other Recipes {#other-recipes} + +Other recipes work similarly, but require a few extra parameters. For example, smelting recipes need to know how much experience to award. + +@[code lang=java transcludeWith=:::datagen-recipes:other](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +## Custom Recipe Types {#custom-recipe-types} diff --git a/versions/1.21/develop/data-generation/setup.md b/versions/1.21/develop/data-generation/setup.md new file mode 100644 index 000000000..b0581b9d3 --- /dev/null +++ b/versions/1.21/develop/data-generation/setup.md @@ -0,0 +1,90 @@ +--- +title: Data Generation Setup +description: A guide to setting up Data Generation with Fabric API. +authors: + - skycatminepokie + - modmuss50 + - earthcomputer + - shnupbups + - arkosammy12 + - haykam821 + - matthewperiut + - SolidBlock-cn + - Jab125 +authors-nogithub: + - jmanc3 + - macrafterzz + +search: false +--- + +# Data Generation Setup {#data-generation-setup} + +## What Is Data Generation? {#what-is-data-generation} + +Data generation (or datagen) is an API for programmatically generating recipes, advancements, tags, item models, language files, loot tables, and basically anything JSON-based. + +## Enabling Data Generation {#enabling-data-generation} + +### At Project Creation {#enabling-data-generation-at-project-creation} + +The easiest way to enable datagen is at project creation. Check the "Enable Data Generation" box when using the [template generator](https://fabricmc.net/develop/template/). + +![The checked "Data Generation" box on the template generator](/assets/develop/data-generation/data_generation_setup_01.png) + +::: tip +If datagen is enabled, you should have a "Data Generation" run configuration and a `runDatagen` Gradle task. +::: + +### Manually {#manually-enabling-data-generation} + +First, we need to enable datagen in the `build.gradle` file. + +@[code lang=groovy transcludeWith=:::datagen-setup:configure](@/reference/build.gradle) + +Next, we need an entrypoint class. This is where our datagen starts. Place this somewhere in the `client` package - this example places it at `src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java`. + +@[code lang=java transcludeWith=:::datagen-setup:generator](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +Finally, we need to tell Fabric about the entrypoint in our `fabric.mod.json`: + +```json +{ + // ... + "entrypoints": { + // ... + "client": [ + // ... + ], + "fabric-datagen": [ // [!code ++] + "com.exmaple.docs.datagen.FabricDocsReferenceDataGenerator" // [!code ++] + ] // [!code ++] + } +} +``` + +::: warning +Don't forget to add a comma (`,`) after the previous entrypoint block! +::: + +Close and reopen IntelliJ to create a run configuration for datagen. + +## Creating a Pack {#creating-a-pack} + +Inside your datagen entrypoint's `onInitializeDataGenerator` method, we need to create a `Pack`. Later, you'll add **providers**, which put generated data into this `Pack`. + +@[code lang=java transcludeWith=:::datagen-setup:pack](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Running Data Generation {#running-data-generation} + +To run datagen, use the run configuration in your IDE, or run `./gradlew runDatagen` in the console. The generated files will be created in `src/main/generated`. + +## Next Steps {#next-steps} + +Now that datagen is set up, we need to add **providers**. These are what generate the data to add to your `Pack`. The following pages outline how to do this. + +- [Advancements](./advancements) +- [Loot Tables](./loot-tables) +- [Recipes](./recipes) +- [Tags](./tags) +- [Translations](./translations) diff --git a/versions/1.21/develop/data-generation/tags.md b/versions/1.21/develop/data-generation/tags.md new file mode 100644 index 000000000..3414728c7 --- /dev/null +++ b/versions/1.21/develop/data-generation/tags.md @@ -0,0 +1,46 @@ +--- +title: Tag Generation +description: A guide to setting up tag generation with datagen. +authors: + - skycatminepokie + - IMB11 + - Spinoscythe +authors-nogithub: + - mcrafterzz + +search: false +--- + +# Tag Generation {#tag-generation} + +::: info PREREQUISITES +Make sure you've completed the [datagen setup](./setup) process first. +::: + +## Setup {#setup} + +First, create your own class that `extends FabricTagProvider`, where `T` is the type of thing you'd like to provide a tag for. This is your **provider**. Here we'll show how to create `Item` tags, but the same principal applies for other things. Let your IDE fill in the required code, then replace the `registryKey` constructor parameter with the `RegistryKey` for your type: + +@[code lang=java transcludeWith=:::datagen-tags:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) + +::: info NOTE +You will need a different provider for each type of tag (eg. one `FabricTagProvider>` and one `FabricTagProvider`). +::: + +To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. + +@[code lang=java transclude={28-28}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Creating a Tag {#creating-a-tag} + +Now that you've created a provider, let's add a tag to it. First, create a `TagKey`: + +@[code lang=java transcludeWith=:::datagen-tags:tag-key](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) + +Next, call `getOrCreateTagBuilder` inside your provider's `configure` method. From there, you can add individual items, add other tags, or make this tag replace pre-existing tags. + +If you want to add a tag, use `addOptionalTag`, as the tag's contents may not be loaded during datagen. If you are certain the tag is loaded, call `addTag`. + +To forcefully add a tag and ignore the broken format, use `forceAddTag`. + +@[code lang=java transcludeWith=:::datagen-tags:build](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) diff --git a/versions/1.21/develop/data-generation/translations.md b/versions/1.21/develop/data-generation/translations.md new file mode 100644 index 000000000..9fb8689cc --- /dev/null +++ b/versions/1.21/develop/data-generation/translations.md @@ -0,0 +1,51 @@ +--- +title: Translation Generation +description: A guide to setting up translation generation with datagen. +authors: + - skycatminepokie + - MattiDragon + - IMB11 + - Spinoscythe +authors-nogithub: + - sjk1949 + - mcrafterzz + - jmanc3 + +search: false +--- + +# Translation Generation {#translation-generation} + +::: info PREREQUISITES +Make sure you've completed the [datagen setup](./setup) process first. +::: + +## Setup {#setup} + +First, we'll make our **provider**. Remember, providers are what actually generate data for us. Create a class that `extends FabricLanguageProvider` and fill out the base methods: + +@[code lang=java transcludeWith=:::datagen-translations:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) + +::: info NOTE +You will need a different provider for each langauge you want to generate (eg. one `ExampleEnglishLangProvider` and one `ExamplePirateLangProvider`). +::: + +To finish setup, add this provider to your `DataGeneratorEntrypoint` within the `onInitializeDataGenerator` method. + +@[code lang=java transclude={26-26}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Creating Translations {#creating-translations} + +Along with creating raw translations, translations from `Identifier`s, and copying them from an already existing file (by passing a `Path`), there are helper methods for translating items, blocks, tags, stats, entities, status effects, item groups, entity attributes, and enchantments. Simply call `add` on the `translationBuilder` with what you want to translate and what it should translate to: + +@[code lang=java transcludeWith=:::datagen-translations:build](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) + +## Using Translations {#using-translations} + +Generated translations take the place of a lot of translations added in other tutorials, but you can also use them anywhere you use a `Text` object. In our example, if we wanted to allow resource packs to translate our greeting, we use `Text.translatable` instead of `Text.of`: + +```java +ChatHud chatHud = MinecraftClient.getInstance().inGameHud.getChatHud(); +chatHud.addMessage(Text.literal("Hello there!")); // [!code --] +chatHud.addMessage(Text.translatable("text.fabric_docs_reference.greeting")); // [!code ++] +``` diff --git a/versions/1.21/develop/entities/damage-types.md b/versions/1.21/develop/entities/damage-types.md new file mode 100644 index 000000000..48b732766 --- /dev/null +++ b/versions/1.21/develop/entities/damage-types.md @@ -0,0 +1,109 @@ +--- +title: Damage Types +description: Learn how to add custom damage types. +authors: + - dicedpixels + - hiisuuii + - mattidragon + +search: false +--- + +# Damage Types {#damage-types} + +Damage types define types of damage that entities can take. Since Minecraft 1.19.4, the creation of new damage types has +become data-driven, meaning they are created using JSON files. + +## Creating a Damage Type {#creating-a-damage-type} + +Let's create a custom damage type called _Tater_. We start by creating a JSON file for your custom damage. This file +will +be placed in your mod's `data` directory, in a subdirectory named `damage_type`. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +It has the following structure: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +This custom damage type causes 0.1 increase +in [hunger exhaustion](https://minecraft.wiki/w/Hunger#Exhaustion_level_increase) each time a player takes damage, when +the damage is caused by a living, non-player source (e.g., a block). Additionally, the amount of damage dealt will scale +with the world's difficulty + +::: info + +Refer to the [Minecraft Wiki](https://minecraft.wiki/w/Damage_type#JSON_format) for all the possible keys and values. + +::: + +### Accessing Damage Types Through Code {#accessing-damage-types-through-code} + +When we need to access our custom damage type through code, we will use it's `RegistryKey` to build an instance +of `DamageSource`. + +The `RegistryKey` can be obtained as follows: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### Using Damage Types {#using-damage-types} + +To demonstrate the use of custom damage types, we will use a custom block called _Tater Block_. Let's make is so that +when a living entity steps on a _Tater Block_, it deals _Tater_ damage. + +You can override `onSteppedOn` to inflict this damage. + +We start by creating a `DamageSource` of our custom damage type. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Then, we call `entity.damage()` with our `DamageSource` and an amount. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +The complete block implementation: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Now whenever a living entity steps on our custom block, it'll take 5 damage (2.5 hearts) using our custom damage type. + +### Custom Death Message {#custom-death-message} + +You can define a death message for the damage type in the format of `death.attack.` in our +mod's `en_us.json` file. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +Upon death from our damage type, you'll see the following death message: + +![Effect in player inventory](/assets/develop/tater-damage-death.png) + +### Damage Type Tags {#damage-type-tags} + +Some damage types can bypass armor, bypass status effects, and such. Tags are used to control these kinds of properties +of damage types. + +You can find existing damage type tags in `data/minecraft/tags/damage_type`. + +::: info + +Refer to the [Minecraft Wiki](https://minecraft.wiki/w/Tag#Damage_types) for a comprehensive list of damage type +tags. + +::: + +Let's add our Tater damage type to the `bypasses_armor` damage type tag. + +To add our damage type to one of these tags, we create a JSON file under the `minecraft` namespace. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +With the following content: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +Ensure your tag does not replace the existing tag by setting the `replace` key to `false`. diff --git a/versions/1.21/develop/entities/effects.md b/versions/1.21/develop/entities/effects.md new file mode 100644 index 000000000..9974b2e58 --- /dev/null +++ b/versions/1.21/develop/entities/effects.md @@ -0,0 +1,92 @@ +--- +title: Status Effects +description: Learn how to add custom status effects. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil + - Manchick0 +authors-nogithub: + - siglong + - tao0lu + +search: false +--- + +# Status Effects {#status-effects} + +Status effects, also known as effects, are a condition that can affect an entity. They can be positive, negative or neutral in nature. The base game +applies these effects in various ways such as food, potions etc. + +The `/effect` command can be used to apply effects on an entity. + +## Custom Status Effects {#custom-status-effects} + +In this tutorial we'll add a new custom effect called _Tater_ which gives you one experience point every game tick. + +### Extend `StatusEffect` {#extend-statuseffect} + +Let's create a custom effect class by extending `StatusEffect`, which is the base class for all effects. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### Registering Your Custom Effect {#registering-your-custom-effect} + +Similar to block and item registration, we use `Registry.register` to register our custom effect into the +`STATUS_EFFECT` registry. This can be done in our initializer. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### Texture {#texture} + +The status effect icon is a 18x18 PNG which will appear in the player's inventory screen. Place your custom icon in: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + +Example Texture + +### Translations {#translations} + +Like any other translation, you can add an entry with ID format `"effect..": "Value"` to the +language file. + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### Applying The Effect {#applying-the-effect} + +It's worth taking a look at how you'd typically apply an effect to an entity. + +::: tip +For a quick test, it might be a better idea to use the previously mentioned `/effect` command: + +```mcfunction +effect give @p fabric-docs-reference:tater +``` + +::: + +To apply an effect internally, you'd want to use the `LivingEntity#addStatusEffect` method, which takes in +a `StatusEffectInstance`, and returns a boolean, specifying whether the effect was successfully applied. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java) + +| Argument | Type | Description | +|-------------|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `effect` | `RegistryEntry` | A registry entry that represents the effect. | +| `duration` | `int` | The duration of the effect **in ticks**; **not** seconds | +| `amplifier` | `int` | The amplifier to the level of the effect. It doesn't correspond to the **level** of the effect, but is rather added on top. Hence, `amplifier` of `4` => level of `5` | +| `ambient` | `boolean` | This is a tricky one. It basically specifies that the effect was added by the environment (e.g. a **Beacon**) and doesn't have a direct cause. If `true`, the icon of the effect in the HUD will appear with an aqua overlay. | +| `particles` | `boolean` | Whether to show particles. | +| `icon` | `boolean` | Whether to display an icon of the effect in the HUD. The effect will be displayed in the inventory regardless of this flag. | + +::: info +To create a potion that uses this effect, please see the [Potions](../items/potions) guide. +::: diff --git a/versions/1.21/develop/events.md b/versions/1.21/develop/events.md new file mode 100644 index 000000000..508ce1e54 --- /dev/null +++ b/versions/1.21/develop/events.md @@ -0,0 +1,124 @@ +--- +title: Events +description: A guide for using events provided by the Fabric API. +authors: + - dicedpixels + - mkpoli + - daomephsta + - solidblock + - draylar + - jamieswhiteshirt + - PhoenixVX + - Juuxel + - YanisBft + - liach + - natanfudge +authors-nogithub: + - stormyfabric + +search: false +--- + +# Events {#events} + +Fabric API provides a system that allows mods to react to actions or occurrences, also defined as _events_ that occur in the game. + +Events are hooks that satisfy common use cases and/or provide enhanced compatibility and performance between mods that hook into the same areas of the code. The use of events often substitutes the use of mixins. + +Fabric API provides events for important areas in the Minecraft codebase that multiple modders may be interested in hooking into. + +Events are represented by instances of `net.fabricmc.fabric.api.event.Event` which stores and calls _callbacks_. Often there is a single event instance for a callback, which is stored in a static field `EVENT` of the callback interface, but there are other patterns as well. For example, `ClientTickEvents` groups several related events together. + +## Callbacks {#callbacks} + +Callbacks are a piece of code that is passed as an argument to an event. When the event is triggered by the game, the passed piece of code will be executed. + +### Callback Interfaces {#callback-interfaces} + +Each event has a corresponding callback interface, conventionally named `Callback`. Callbacks are registered by calling `register()` method on an event instance, with an instance of the callback interface as the argument. + +All event callback interfaces provided by Fabric API can be found in the `net.fabricmc.fabric.api.event` package. + +## Listening to Events {#listening-to-events} + +This example registers an `AttackBlockCallback` to damage the player when they hit blocks that don't drop an item when hand-mined. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +### Adding Items to Existing Loot Tables {#adding-items-to-existing-loot-tables} + +Sometimes you may want to add items to loot tables. For example, adding your drops to a vanilla block or entity. + +The simplest solution, replacing the loot table file, can break other mods. What if they want to change them as well? We'll take a look at how you can add items to loot tables without overriding the table. + +We'll be adding eggs to the coal ore loot table. + +#### Listening to Loot Table Loading {#listening-to-loot-table-loading} + +Fabric API has an event that is fired when loot tables are loaded, `LootTableEvents.MODIFY`. You can register a callback for it in your [mod's initializer](./getting-started/project-structure#entrypoints). Let's also check that the current loot table is the coal ore loot table. + +@[code lang=java transclude={38-40}](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +#### Adding Items to the Loot Table {#adding-items-to-the-loot-table} + +In loot tables, items are stored in _loot pool entries_, and entries are stored in _loot pools_. To add an item, we'll need to add a pool with an item entry to the loot table. + +We can make a pool with `LootPool#builder`, and add it to the loot table. + +Our pool doesn't have any items either, so we'll make an item entry using `ItemEntry#builder` and add it to the pool. + +@[code highlight={6-7} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +## Custom Events {#custom-events} + +Some areas of the game do not have hooks provided by the Fabric API, so you can either use a mixin or create your own event. + +We'll look at creating an event that is triggered when sheep are sheared. The process of creating an event is: + +- Creating the event callback interface +- Triggering the event from a mixin +- Creating a test implementation + +### Creating the Event Callback Interface {#creating-the-event-callback-interface} + +The callback interface describes what must be implemented by event listeners that will listen to your event. The callback interface also describes how the event will be called from our mixin. It is conventional to place an `Event` object as a field in the callback interface, which will identify our actual event. + +For our `Event` implementation, we will choose to use an array-backed event. The array will contain all event listeners that are listening to the event. + +Our implementation will call the event listeners in order until one of them does not return `ActionResult.PASS`. This means that a listener can say "_cancel this_", "_approve this_" or "_don't care, leave it to the next event listener_" using its return value. + +Using `ActionResult` as a return value is a conventional way to make event handlers cooperate in this fashion. + +You'll need to create an interface that has an `Event` instance and method for response implementation. A basic setup for our sheep shear callback is: + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Let's look at this more in-depth. When the invoker is called, we iterate over all listeners: + +@[code lang=java transclude={21-22}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +We then call our method (in this case, `interact`) on the listener to get its response: + +@[code lang=java transclude={33-33}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +If the listener says we have to cancel (`ActionResult.FAIL`) or fully finish (`ActionResult.SUCCESS`), the callback returns the result and finishes the loop. `ActionResult.PASS` moves on to the next listener, and in most cases should result in success if there are no more listeners registered: + +@[code lang=java transclude={25-30}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +We can add Javadoc comments to the top of callback classes to document what each `ActionResult` does. In our case, it might be: + +@[code lang=java transclude={9-16}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +### Triggering the Event From a Mixin {#triggering-the-event-from-a-mixin} + +We now have the basic event skeleton, but we need to trigger it. Because we want to have the event called when a player attempts to shear a sheep, we call the event `invoker` in `SheepEntity#interactMob` when `sheared()` is called (i.e. sheep can be sheared, and the player is holding shears): + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java) + +### Creating a Test Implementation {#creating-a-test-implementation} + +Now we need to test our event. You can register a listener in your initialization method (or another area, if you prefer) and add custom logic there. Here's an example that drops a diamond instead of wool at the sheep's feet: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +If you enter into your game and shear a sheep, a diamond should drop instead of wool. diff --git a/versions/1.21/develop/getting-started/creating-a-project.md b/versions/1.21/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..182e25fda --- /dev/null +++ b/versions/1.21/develop/getting-started/creating-a-project.md @@ -0,0 +1,73 @@ +--- +title: Creating a Project +description: A step-by-step guide on how to create a new mod project using the Fabric template mod generator. +authors: + - IMB11 + - Cactooz + +search: false +--- + +# Creating a Project {#creating-a-project} + +Fabric provides an easy way to create a new mod project using the Fabric Template Mod Generator - if you want, you can manually create a new project using the example mod repository, you should refer to the [Manual Project Creation](#manual-project-creation) section. + +## Generating a Project {#generating-a-project} + +You can use the [Fabric Template Mod Generator](https://fabricmc.net/develop/template/) to generate a new project for your mod - you should fill in the required fields, such as the mod name, package name, and the Minecraft version that you want to develop for. + +The package name should be lowercase, separated by dots, and unique to avoid conflicts with other programmers' packages. It is typically formatted as a reversed internet domain, such as `com.example.modid`. + +![Preview of the generator](/assets/develop/getting-started/template-generator.png) + +If you want to use Kotlin, use Mojang's official mappings rather than the Yarn mappings, or want to add data generators, you can select the appropriate options in the `Advanced Options` section. + +![Advanced options section](/assets/develop/getting-started/template-generator-advanced.png) + +Once you've filled in the required fields, click the `Generate` button, and the generator will create a new project for you to use in the form of a zip file. + +You should extract this zip file to a location of your choice, and then open the extracted folder in IntelliJ IDEA: + +![Open Project Prompt](/assets/develop/getting-started/open-project.png) + +## Importing the Project {#importing-the-project} + +Once you've opened the project in IntelliJ IDEA, the IDE should automatically load the project's Gradle configuration and perform the necessary setup tasks. + +If you receive a notification talking about a Gradle build script, you should click the `Import Gradle Project` button: + +![Gradle Prompt](/assets/develop/getting-started/gradle-prompt.png) + +Once the project has been imported, you should see the project's files in the project explorer, and you should be able to start developing your mod. + +## Manual Project Creation {#manual-project-creation} + +::: warning +You will need [Git](https://git-scm.com/) installed in order to clone the example mod repository. +::: + +If you cannot use the Fabric Template Mod Generator, you can create a new project manually by following these steps. + +Firstly, clone the example mod repository using Git: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +This will clone the repository into a new folder called `my-mod-project`. + +You should then delete the `.git` folder from the cloned repository, and then open the project in IntelliJ IDEA. If the `.git` folder does not appear, you should enable the display of hidden files in your file manager. + +Once you've opened the project in IntelliJ IDEA, it should automatically load the project's Gradle configuration and perform the necessary setup tasks. + +Again, as previously mentioned, if you receive a notification talking about a Gradle build script, you should click the `Import Gradle Project` button. + +### Modifying the Template {#modifying-the-template} + +Once the project has been imported, you should modify the project's details to match your mod's details: + +- Modify the project's `gradle.properties` file to change the `maven_group` and `archive_base_name` properties to match your mod's details. +- Modify the `fabric.mod.json` file to change the `id`, `name`, and `description` properties to match your mod's details. +- Make sure to update the versions of Minecraft, the mappings, the Loader and the Loom - all of which can be queried through - to match the versions you wish to target. + +You can obviously change the package name and the mod's main class to match your mod's details. diff --git a/versions/1.21/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..689195364 --- /dev/null +++ b/versions/1.21/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,67 @@ +--- +title: Introduction to Fabric and Modding +description: "A brief introduction to Fabric and modding in Minecraft: Java Edition." +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 + +search: false +--- + +# Introduction to Fabric and Modding {#introduction-to-fabric-and-modding} + +## Prerequisites {#prerequisites} + +Before you start, you should have a basic understanding of developing with Java, and an understanding of Object-Oriented Programming (OOP). + +If you are unfamiliar with these concepts, you may want to look into some tutorials on Java and OOP before you start modding, here are some of the resources that you can use to learn Java and OOP: + +- [W3: Java Tutorials](https://www.w3schools.com/java/) +- [Codecademy: Learn Java](https://www.codecademy.com/learn/learn-java) +- [W3: Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium: Introduction to OOP](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### Terminology {#terminology} + +Before we start, let's go over some of the terms that you will encounter when modding with Fabric: + +- **Mod**: A modification to the game, adding new features or changing existing ones. +- **Mod Loader**: A tool that loads mods into the game, such as Fabric Loader. +- **Mixin**: A tool for modifying the game's code at runtime - see [Mixin Introduction](https://fabricmc.net/wiki/tutorial:mixin_introduction) for more information. +- **Gradle**: A build automation tool used to build and compile mods, used by Fabric to build mods. +- **Mappings**: A set of mappings that map obfuscated code to human-readable code. +- **Obfuscation**: The process of making code difficult to understand, used by Mojang to protect Minecraft's code. +- **Remapping**: The process of mapping obfuscated code to human-readable code. + +## What Is Fabric? {#what-is-fabric} + +Fabric is a lightweight modding toolchain for Minecraft: Java Edition. + +It is designed to be a simple and easy-to-use modding platform. Fabric is a community-driven project, and it is open-source, meaning that anyone can contribute to the project. + +You should be aware of the four main components of Fabric: + +- **Fabric Loader**: A flexible platform-independent mod loader designed for Minecraft and other games and applications. +- **Fabric Loom**: A Gradle plugin enabling developers to easily develop and debug mods. +- **Fabric API**: A set of APIs and tools for mod developers to use when creating mods. +- **Yarn**: A set of open Minecraft mappings, free for everyone to use under the Creative Commons Zero license. + +## Why Is Fabric Necessary to Mod Minecraft? {#why-is-fabric-necessary-to-mod-minecraft} + +> Modding is the process of modifying a game in order to change its behavior or add new features - in the case of Minecraft, this can be anything from adding new items, blocks, or entities, to changing the game's mechanics or adding new game modes. + +Minecraft: Java Edition is obfuscated by Mojang, making modification alone difficult. However, with the help of modding tools like Fabric, modding becomes much easier. There are several mapping systems that can assist in this process. + +Loom remaps the obfuscated code to a human-readable format using these mappings, making it easier for modders to understand and modify the game's code. Yarn is a popular and excellent mappings choice for this, but other options exist as well. Each mapping project may have its own strengths or focus. + +Loom allows you to easily develop and compile mods against remapped code, and Fabric Loader allows you to load these mods into the game. + +## What Does Fabric API Provide, and Why Is It Needed? {#what-does-fabric-api-provide-and-why-is-it-needed} + +> Fabric API is a set of APIs and tools for mod developers to use when creating mods. + +Fabric API provides a wide set of APIs that build on top of Minecraft's existing functionality - for example, providing new hooks and events for modders to use, or providing new utilities and tools to make modding easier - such as transitive access wideners and the ability to access internal registries, such as the compostable items registry. + +While Fabric API offers powerful features, some tasks, like basic block registration, can be accomplished without it using the vanilla APIs. diff --git a/versions/1.21/develop/getting-started/launching-the-game.md b/versions/1.21/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..cce2313f0 --- /dev/null +++ b/versions/1.21/develop/getting-started/launching-the-game.md @@ -0,0 +1,74 @@ +--- +title: Launching the Game +description: Learn how to utilize the various launch profiles to start and debug your mods in a live game environment. +authors: + - IMB11 + - Tenneb22 + +search: false +--- + +# Launching the Game {#launching-the-game} + +Fabric Loom provides a variety of launch profiles to help you start and debug your mods in a live game environment. This guide will cover the various launch profiles and how to use them to debug and playtest your mods. + +## Launch Profiles {#launch-profiles} + +If you're using IntelliJ IDEA, you can find the launch profiles in the top-right corner of the window. Click the dropdown menu to see the available launch profiles. + +There should be a client and server profile, with the option to either run it normally or in debug mode: + +![Launch Profiles](/assets/develop/getting-started/launch-profiles.png) + +## Gradle Tasks {#gradle-tasks} + +If you're using the command line, you can use the following Gradle commands to start the game: + +- `./gradlew runClient` - Start the game in client mode. +- `./gradlew runServer` - Start the game in server mode. + +The only problem with this approach is that you can't easily debug your code. If you want to debug your code, you'll need to use the launch profiles in IntelliJ IDEA or via your IDE's Gradle integration. + +## Hotswapping Classes {#hotswapping-classes} + +When you run the game in debug mode, you can hotswap your classes without restarting the game. This is useful for quickly testing changes to your code. + +You're still quite limited though: + +- You can't add or remove methods +- You can't change method parameters +- You can't add or remove fields + +However, by using the [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime), you are able to circumvent most of the limitations, and even add or remove classes and methods. This should allow most changes to take effect without restarting the game. + +Don't forget to add the following to the VM Arguments option in your Minecraft run configuration: + +```:no-line-numbers +-XX:+AllowEnhancedClassRedefinition +``` + +## Hotswapping Mixins {#hotswapping-mixins} + +If you're using Mixins, you can hotswap your Mixin classes without restarting the game. This is useful for quickly testing changes to your Mixins. + +You will need to install the Mixin Java agent for this to work though. + +### 1. Locate the Mixin Library Jar {#1-locate-the-mixin-library-jar} + +In IntelliJ IDEA, you can find the mixin library jar in the "External Libraries" section of the "Project" section: + +![Mixin Library](/assets/develop/getting-started/mixin-library.png) + +You will need to copy the jar's "Absolute Path" for the next step. + +### 2. Add the `-javaagent` VM Argument {#2-add-the--javaagent-vm-argument} + +In your "Minecraft Client" and or "Minecraft Server" run configuration, add the following to the VM Arguments option: + +```:no-line-numbers +-javaagent:"path to mixin library jar here" +``` + +![VM Arguments Screenshot](/assets/develop/getting-started/vm-arguments.png) + +Now, you should be able to modify the contents of your mixin methods during debugging and have the changes take effect without restarting the game. diff --git a/versions/1.21/develop/getting-started/project-structure.md b/versions/1.21/develop/getting-started/project-structure.md new file mode 100644 index 000000000..cbf908f6b --- /dev/null +++ b/versions/1.21/develop/getting-started/project-structure.md @@ -0,0 +1,66 @@ +--- +title: Project Structure +description: An overview of the structure of a Fabric mod project. +authors: + - IMB11 + +search: false +--- + +# Project Structure {#project-structure} + +This page will go over the structure of a Fabric mod project, and the purpose of each file and folder in the project. + +## `fabric.mod.json` {#fabric-mod-json} + +The `fabric.mod.json` file is the main file that describes your mod to Fabric Loader. It contains information such as the mod's ID, version, and dependencies. + +The most important fields in the `fabric.mod.json` file are: + +- `id`: The mod's ID, which should be unique. +- `name`: The mod's name. +- `environment`: The environment that your mod runs in, such as `client`, `server`, or `*` for both. +- `entrypoints`: The entrypoints that your mod provides, such as `main` or `client`. +- `depends`: The mods that your mod depends on. +- `mixins`: The mixins that your mod provides. + +You can see an example `fabric.mod.json` file below - this is the `fabric.mod.json` file for the reference project that powers this documentation site. + +::: details Reference Project `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## Entrypoints {#entrypoints} + +As mentioned before, the `fabric.mod.json` file contains a field called `entrypoints` - this field is used to specify the entrypoints that your mod provides. + +The template mod generator creates both a `main` and `client` entrypoint by default: + +- The `main` entrypoint is used for common code, and it's contained in a class which implements `ModInitializer` +- The `client` entrypoint is used for client-specific code, and its class implements `ClientModInitializer` + +These entrypoints are called respectively when the game starts. + +Here's an example of a simple `main` entrypoint that logs a message to the console when the game starts: + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +## `src/main/resources` {#src-main-resources} + +The `src/main/resources` folder is used to store the resources that your mod uses, such as textures, models, and sounds. + +It's also the location of `fabric.mod.json` and any mixin configuration files that your mod uses. + +Assets are stored in a structure that mirrors the structure of resource packs - for example, a texture for a block would be stored in `assets/modid/textures/block/block.png`. + +## `src/client/resources` {#src-client-resources} + +The `src/client/resources` folder is used to store client-specific resources, such as textures, models, and sounds that are only used on the client side. + +## `src/main/java` {#src-main-java} + +The `src/main/java` folder is used to store the Java source code for your mod - it exists on both the client and server environments. + +## `src/client/java` {#src-client-java} + +The `src/client/java` folder is used to store client-specific Java source code, such as rendering code or client-side logic - such as block color providers. diff --git a/versions/1.21/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..7af620761 --- /dev/null +++ b/versions/1.21/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,57 @@ +--- +title: Setting up a Development Environment +description: A step-by-step guide on how to set up a development environment to create mods using Fabric. +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong + +search: false +--- + +# Setting up a Development Environment {#setting-up-a-development-environment} + +To start developing mods with Fabric, you will need to set up a development environment using IntelliJ IDEA. + +## Installing JDK 21 {#installing-jdk-21} + +To develop mods for Minecraft 1.21, you will need JDK 21. + +If you need help installing Java, you can refer to the various Java installation guides in the [player guides section](../../players/index). + +## Installing IntelliJ IDEA {#installing-intellij-idea} + +::: info +You can obviously use other IDEs, such as Eclipse or Visual Studio Code, but the majority of the pages on this documentation site will assume that you are using IntelliJ IDEA - you should refer to the documentation for your IDE if you are using a different one. +::: + +If you do not have IntelliJ IDEA installed, you can download it from the [official website](https://www.jetbrains.com/idea/download/) - follow the installation steps for your operating system. + +The Community edition of IntelliJ IDEA is free and open-source, and it is the recommended version for modding with Fabric. + +You may have to scroll down to find the Community edition download link - it looks like the following: + +![IDEA Community Edition Download Prompt](/assets/develop/getting-started/idea-community.png) + +## Installing IDEA Plugins {#installing-idea-plugins} + +Although these plugins aren't strictly necessary, they can make modding with Fabric much easier - you should consider installing them. + +### Minecraft Development {#minecraft-development} + +The Minecraft Development plugin provides support for modding with Fabric, and it is the most important plugin to install. + +You can install it by opening IntelliJ IDEA, and then navigating to `File > Settings > Plugins > Marketplace Tab` - search for `Minecraft Development` in the search bar, and then click the `Install` button. + +Alternatively, you can download it from the [plugin page](https://plugins.jetbrains.com/plugin/8327-minecraft-development) and then install it by navigating to `File > Settings > Plugins > Install Plugin From Disk`. diff --git a/versions/1.21/develop/ide-tips-and-tricks.md b/versions/1.21/develop/ide-tips-and-tricks.md new file mode 100644 index 000000000..cfaaac870 --- /dev/null +++ b/versions/1.21/develop/ide-tips-and-tricks.md @@ -0,0 +1,322 @@ +--- +title: IDE Tips and Tricks +description: Useful information to handle and traverse your project using the IDE efficiently. +authors: + - JR1811 + - AnAwesomGuy + +search: false +--- + +# IDE Tips and Tricks {#ide-tips-and-tricks} + +This page gives useful bits of information, to speed up and ease the workflow of developers. Incorporate them into yours, to your liking. +It may take some time to learn and get used to the shortcuts and other options. You can use this page as a reference for that. + +::: warning +Key binds in the text refer to the default keymap of IntelliJ IDEA, if not stated otherwise. +Refer to the `File > Settings > Keymap` Settings or search for the functionality elsewhere if you are using a different keyboard layout. +::: + +## Traversing Projects {#traversing-projects} + +### Manually {#manually} + +IntelliJ has many different ways of traversing projects. If you have generated sources using the `./gradlew genSources` commands in the terminal or +used the `Tasks > fabric > genSources` Gradle tasks in the Gradle Window, you can manually go through the source files of Minecraft in the Project Window's External Libraries. + +![Gradle tasks](/assets/develop/misc/using-the-ide/traversing_01.png) + +The Minecraft source code can be found if you look for `net.minecraft` in the Project Window's External Libraries. +If your project uses split sources from the online [Template mod generator](https://fabricmc.net/develop/template), there will be two sources, as indicated by the name (client/common). +Additionally other sources of projects, libraries and dependencies, which are imported via the `build.gradle` file will also be available. +This method is often used when browsing for assets, tags and other files. + +![External Library](/assets/develop/misc/using-the-ide/traversing_02_1.png) + +![Split sources](/assets/develop/misc/using-the-ide/traversing_02_2.png) + +### Search {#search} + +Pressing Shift twice opens up a Search window. In there you can search for your project's files and classes. When Activating the checkbox `include non-project items` +or by pressing Shift two times again, the search will look not only in your own project, but also in other's, such as the External Libraries. + +You can also use the shortcuts ⌘/CTRL+N to search classes and ⌘/CTRL+Shift+N to search all _files_. + +![Search window](/assets/develop/misc/using-the-ide/traversing_03.png) + +### Recent Window {#recent-window} + +Another useful tool in IntelliJ is the `Recent` window. You can open it with the Shortcut ⌘/CTRL+E. +In there you can jump to the files, which you have already visited and open tool windows, such as the [Structure](#structure-of-a-class) or [Bookmarks](#bookmarks) window. + +![Recent window](/assets/develop/misc/using-the-ide/traversing_04.png) + +## Traversing Code {#traversing-code} + +### Jump to Definition / Usage {#jump-to-definition-usage} + +If you need to check out either the definition or the usage of variables, methods, classes, and other things, you can press ⌘/CTRL+Left Click / B +or use Middle Mouse Button (pressing mouse wheel) on their name. This way you can avoid long scrolling sessions or a manual +search for a definition which is located in another file. + +You can also use ⌘/CTRL+⌥/Shift+Left Click / B to view all the implementations of a class or interface. + +### Bookmarks {#bookmarks} + +You can bookmark lines of code, files or even opened Editor tabs. +Especially when researching source codes, it can help out to mark spots which you want to find again quickly in the future. + +Either right click a file in the `Project` window, an editor tab or the line number in a file. +Creating `Mnemonic Bookmarks` enables you to quickly switch back to those bookmarks using their hotkeys, ⌘/CTRL and the digit, which you have chosen for it. + +![set Bookmark](/assets/develop/misc/using-the-ide/traversing_05.png) + +It is possible to create multiple Bookmark lists at the same time if you need to separate or order them, in the `Bookmarks` window. +[Breakpoints](./basic-problem-solving#breakpoint) will also be displayed there. + +![Bookmark window](/assets/develop/misc/using-the-ide/traversing_06.png) + +## Analyzing Classes {#analyzing-classes} + +### Structure of a Class {#structure-of-a-class} + +By opening the `Structure` window (⌘/Alt+7) you will get an overview of your currently active class. You can see which Classes and Enums +are located in that file, which methods have been implemented and which fields and variables are declared. + +Sometimes it can be helpful, +to activate the `Inherited` option at the top in the View options as well, when looking for potential methods to override. + +![Structure window](/assets/develop/misc/using-the-ide/analyzing_01.png) + +### Type Hierarchy of a Class {#type-hierarchy-of-a-class} + +By placing the cursor on a class name and pressing ⌘/CTRL+H you can open a new Type Hierarchy window, which shows all parent and child classes. + +![Type Hierarchy window](/assets/develop/misc/using-the-ide/analyzing_02.png) + +## Code Utility {#code-utility} + +### Code Completion {#code-completion} + +Code completion should be activated by default. You will automatically get the recommendations while writing your code. +If you closed it by accident or just moved your cursor to a new place, you can use ⌘/CTRL+Space to open them up again. + +For example, when using lambda expressions, you can write them quickly using this method. + +![Lambda with many parameters](/assets/develop/misc/using-the-ide/util_01.png) + +### Code Generation {#code-generation} + +The Generate menu can be quickly accessed with Alt+Insert (⌘ Command+N on Mac) or by going to `Code` at the top and selecting `Generate`. +In a Java file, you will be able to generate constructors, getters, setters, and override or implement methods, and much more. +You can also generate accessors and invokers if you have the [Minecraft Development plugin](./getting-started/setting-up-a-development-environment#minecraft-development) installed. + +In addition, you can quickly override methods with ⌘/CTRL+O and implement methods with ⌘/CTRL+I. + +![Code generation menu in a Java file](/assets/develop/misc/using-the-ide/generate_01.png) + +In a Java test file, you will be given options to generate related testing methods, as follows: + +![Code generation menu in a Java test file](/assets/develop/misc/using-the-ide/generate_02.png) + +### Displaying Parameters {#displaying-parameters} + +Displaying parameters should be activated by default. You will automatically get the types and names of the parameters while writing your code. +If you closed them by accident or just moved your cursor to a new place, you can use ⌘/CTRL+P to open them up again. + +Methods and classes can have multiple implementations with different parameters, also known as Overloading. This way you can decide on which +implementation you want to use, while writing the method call. + +![Displaying method parameters](/assets/develop/misc/using-the-ide/util_02.png) + +### Refactoring {#refactoring} + +Refactoring is the process of restructuring code without changing its runtime functionality. Renaming and deleting parts of the code safely is a part of that, +but things like extracting parts of the code into separate methods and introducing new variables for repeated code statements are also called "refactoring". + +Many IDEs have an extensive tool kit to aid in this process. In IntelliJ simply right click files or parts of the code to get access to the available refactoring tools. + +![Refactoring](/assets/develop/misc/using-the-ide/refactoring_01.png) + +It is especially useful to get used to the `Rename` refactoring tool's key bind, Shift+F6, since you will likely rename many things in the future. +Using this feature, every code occurrence of the renamed code will be renamed and will stay functionally the same. + +You are also able to reformat code according to your code style. +To do this, select the code you want to reformat (if nothing is selected, the entire file will be reformatted) and press ⌘/CTRL+⌥/ALT+L. +To change how IntelliJ formats code, see the settings at `File > Settings > Editor > Code Style > Java`. + +#### Context Actions {#context-actions} + +Context actions allow for specific sections of code to be refactored based on the context. +To use it, simply move your cursor to the area you want to refactor, and press ⌥/ALT+Enter or click the lightbulb to the left. +There will be a popup showing context actions that can be used for the code selected. + +![Example of context actions](/assets/develop/misc/using-the-ide/context_actions_01.png) + +![Example of context actions](/assets/develop/misc/using-the-ide/context_actions_02.png) + +### Search and Replace File Content {#search-and-replace-file-content} + +Sometimes simpler tools are needed to edit code occurrences. + +| Keybind | Function | +| ----------------------------------------------- | ----------------------------------------------------------- | +| ⌘/CTRL+F | Find in current file | +| ⌘/CTRL+R | Replace in current file | +| ⌘/CTRL+Shift+F | Find in a bigger scope (can set specific file type mask) | +| ⌘/CTRL+Shift+R | Replace in a bigger scope (can set specific file type mask) | + +If used, all of those tools allow for a more specific pattern matching through [Regex](https://en.wikipedia.org/wiki/Regular_expression). + +![Regex replace](/assets/develop/misc/using-the-ide/search_and_replace_01.png) + +### Other Useful Keybinds {#other-keybinds} + +Selecting some text and using ⌘/CTRL+Shift+↑ Up / ↓ Down can move the selected text up or down. + +In IntelliJ, the keybind for `Redo` may not be the usual ⌘/CTRL+Y (Delete Line). +Instead, it may be ⌘/CTRL+Shift+Z. You can change this in the **Keymap**. + + +For even more keyboard shortcuts, you can see [IntelliJ's documentation](https://www.jetbrains.com/help/idea/mastering-keyboard-shortcuts.html). + +## Comments {#comments} + +Good code should be easily readable and [self-documenting](https://bytedev.medium.com/code-comment-anti-patterns-and-why-the-comment-you-just-wrote-is-probably-not-needed-919a92cf6758). +Picking expressive names for variables, classes and methods can help a lot, but sometimes comments are necessary to leave notes or **temporarily** disable code for testing. + +To comment out code faster, you can select some text and use the ⌘/CTRL+/ (line comment) and ⌘/CTRL+⌥/Shift+/ (block comment) keybinds. + +Now you can highlight the necessary code (or just have your cursor on it) and use the shortcuts, to comment the section out. + +```java +// private static final int PROTECTION_BOOTS = 2; +private static final int PROTECTION_LEGGINGS = 5; +// private static final int PROTECTION_CHESTPLATE = 6; +private static final int PROTECTION_HELMET = 1; +``` + +```java +/* +ModItems.initialize(); +ModSounds.initializeSounds(); +ModParticles.initialize(); +*/ + +private static int secondsToTicks(float seconds) { + return (int) (seconds * 20 /*+ 69*/); +} +``` + +### Code Folding {#code-folding} + +In IntelliJ, next to the line numbers, you may see small arrow icons. +They can be used to temporarily collapse methods, if-statements, classes and many other things if you are not actively working on them. +To create a custom block which can be collapsed, use the `region` and `endregion` comments. + +```java +// region collapse block name + ModBlocks.initialize(); + ModBlockEntities.registerBlockEntityTypes(); + ModItems.initialize(); + ModSounds.initializeSounds(); + ModParticles.initialize(); +// endregion +``` + +![Region collapse](/assets/develop/misc/using-the-ide/comments_02.png) + +::: warning +If you notice that you are using too many of them, consider refactoring your code to make it more readable! +::: + +### Disabling the Formatter {#disabling-formatter} + +Comments can also disable the formatter during code refactoring mentioned above by surrounding a piece of code like so: + +```java +//formatter:off (disable formatter) + public static void disgustingMethod() { /* ew this code sucks */ } +//formatter:on (re-enable the formatter) +``` + +### Suppressing Inspections {#noinspection} + +`//noinspection` comments can be used to suppress inspections and warnings. +They are functionally identical to the `@SuppressWarnings` annotation, but without the limitation of being an annotation and can be used on statements. + +```java +// below is bad code and IntelliJ knows that + +@SuppressWarnings("rawtypes") // annotations can be used here +List list = new ArrayList(); + +//noinspection unchecked (annotations cannot be here so we use the comment) +this.processList((List)list); + +//noinspection rawtypes,unchecked,WriteOnlyObject (you can even suppress multiple!) +new ArrayList().add("bananas"); +``` + +::: warning +If you notice that you are suppressing too many warnings, consider rewriting your code to not produce so many warnings! +::: + +### TODO and FIXME Notes {#todo-and-fixme-notes} + +When working on code, it can come in handy to leave notes, on what still needs to be taken care of. Sometimes you may also spot +a potential issue in the code, but you don't want to stop focusing on the current problem. In this case, use the +`TODO` or `FIXME` comments. + +![TODO and FIXME comments](/assets/develop/misc/using-the-ide/comments_03.png) + +IntelliJ will keep track of them in the `TODO` window and may notify you, if you commit code, +which uses those type of comments. + +![TODO and FIXME comments](/assets/develop/misc/using-the-ide/comments_04.png) + +![Commit with TODO](/assets/develop/misc/using-the-ide/comments_05.png) + +### Javadocs {#javadocs} + +A great way of documenting your code is the usage of JavaDoc. +JavaDocs not only provide useful information for implementation of methods and classes, but are also deeply integrated into IntelliJ. + +When hovering over method or class names, which have JavaDoc comments added to them, they will display this information in their information window. + +![JavaDoc](/assets/develop/misc/using-the-ide/comments_06.png) + +To get started, simply write `/**` above the method or class definition and press enter. IntelliJ will automatically generate lines for the return value +and the parameters but you can change them however you want. There are many custom functionalities available and you can also use HTML if needed. + +Minecraft's `ScreenHandler` class has some examples. To toggle the render view, use the pen button near the line numbers. + +![JavaDoc editing](/assets/develop/misc/using-the-ide/comments_07.png) + +## Optimizing IntelliJ Further {#optimizing-intellij-further} + +There are many more shortcuts and handy little tricks, which would go above the scope of this page. +Jetbrains has many good talks, videos and documentation pages about how to further customize your workspace. + +### PostFix Completion {#postfix-completion} + +Use PostFix Completion to alter code after writing it quickly. Often used examples contain `.not`, `.if`, `.var`, `.null`, `.nn`, `.for`, `.fori`, `.return` and `.new`. +Besides the existing ones, you can also create your own in IntelliJ's Settings. + + + +### Live Templates {#live-templates} + +Use Live Templates to generate your custom boilerplate code faster. + + + +### More Tips and Tricks {#more-tips} + +Anton Arhipov from Jetbrains also had an in depth talk about Regex Matching, Code Completion, Debugging and many other topics in IntelliJ. + + + +For even more information, check out [Jetbrains' Tips & Tricks site](https://blog.jetbrains.com/idea/category/tips-tricks) and [IntelliJ's documentation](https://www.jetbrains.com/help/idea/getting-started). +Most of their posts are also applicable to Fabric's ecosystem. diff --git a/versions/1.21/develop/index.md b/versions/1.21/develop/index.md new file mode 100644 index 000000000..a2bc96ab4 --- /dev/null +++ b/versions/1.21/develop/index.md @@ -0,0 +1,16 @@ +--- +title: Developer Guides +description: Our community-written developer guides cover everything from setting up your development environment to advanced topics like rendering and networking. + +search: false +--- + +# Developer Guides {#developer-guides} + +Written by the community, these guides cover a wide range of topics, from setting up your development environment to more advanced areas like rendering and networking. + +Check out the sidebar for a list of all available guides. If you're searching for something specific, the search bar at the top of the page is your best friend. + +Remember: a fully-working mod with all the code for this documentation is available in the [`/reference` folder on GitHub](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21). + +If you want to contribute to the Fabric Documentation, you can find the source code on [GitHub](https://github.com/FabricMC/fabric-docs), and the relevant [contribution guidelines](../contributing). diff --git a/versions/1.21/develop/items/custom-armor.md b/versions/1.21/develop/items/custom-armor.md new file mode 100644 index 000000000..3030964c9 --- /dev/null +++ b/versions/1.21/develop/items/custom-armor.md @@ -0,0 +1,162 @@ +--- +title: Custom Armor +description: Learn how to create your own armor sets. +authors: + - IMB11 + +search: false +--- + +# Custom Armor {#custom-armor} + +Armor provides the player with increased defense against attacks from mobs and other players. + +## Creating an Armor Materials Class {#creating-an-armor-materials-class} + +Just like items and blocks, armor materials need to be registered. We will create a `ModArmorMaterials` class to store our custom armor materials for the sake of organization. + +You will need to add a static `initialize()` method to this class, and call it from your [mod's initializer](./getting-started/project-structure#entrypoints) so that the materials are registered. + +```java +// Within the ModArmorMaterials class +public static void initialize() {}; +``` + +::: warning +Make sure to call this method **before** you register your items, as the materials will need to be registered before the items can be created. +::: + +```java +@Override +public void onInitialize() { + ModArmorMaterials.initialize(); +} +``` + +--- + +Within this `ModArmorMaterials` class, you will need to create a static method which will register the armor material. This method should return a registry entry of the material, as this entry will be used by the ArmorItem constructor to create the armor items. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Armor Material Properties {#armor-material-properties} + +::: tip +If you're struggling to gauge a good value for any of these properties, consider looking at the vanilla armor materials in the `ArmorMaterials` class. +::: + +When creating an armor material, you will need to define the following properties: + +### Defense Points {#defense-points} + +::: warning +Ensure you assign a value to each type of armor piece you plan to create and register as an item. If you make an item for an armor piece without a set defense point value, the game will crash. +::: + +The `defensePoints` map is used to define the number of defense points that each armor piece will provide. The higher the number, the more protection the armor piece will provide. The map should contain an entry for each armor piece type. + +### Enchantability {#enchantability} + +The `enchantability` property defines how easily the armor can be enchanted. The higher the number, the more enchantments the armor can receive. + +### Equip Sound {#equip-sound} + +The `equipSound` property is the sound that will play when the armor is equipped. This sound should be a registry entry of a `SoundEvent`. Consider taking a look at the [Custom Sound Events](../sounds/custom) page if you are considering creating custom sounds rather than relying on vanilla sounds within the `SoundEvents` class. + +### Repair Ingredient(s) {#repair-ingredient} + +The `repairIngredientSupplier` property is a supplier of an `Ingredient` that is used to repair the armor. This ingredient can pretty much be anything, it's recommended to set it to be the same as the material's crafting ingredient used to actually craft the armor items. + +### Toughness {#toughness} + +The `toughness` property defines how much damage the armor will absorb. The higher the number, the more damage the armor will absorb. + +### Knockback Resistance {#knockback-resistance} + +The `knockbackResistance` property defines how much knockback the player will reflect when hit. The higher the number, the less knockback the player will receive. + +### Dyeable {#dyeable} + +The `dyeable` property is a boolean that defines whether the armor can be dyed. If set to `true`, the armor can be dyed using dyes in a crafting table. + +If you do choose to make your armor dyeable, your armor layer and item textures must be **designed to be dyed**, as the dye will overlay the texture, not replace it. Take a look at the vanilla leather armor for an example, the textures are grayscale and the dye is applied as an overlay, causing the armor to change color. + +## Registering the Armor Material {#registering-the-armor-material} + +Now that you've created a utility method which can be used to register armor materials, you can register your custom armor materials as a static field in the `ModArmorMaterials` class. + +For this example, we'll be creating Guidite armor, with the following properties: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Creating the Armor Items {#creating-the-armor-items} + +Now that you've registered the material, you can create the armor items in your `ModItems` class: + +Obviously, an armor set doesn't need every type to be satisfied, you can have a set with just boots, or leggings etc. - the vanilla turtle shell helmet is a good example of an armor set with missing slots. + +### Durability {#durability} + +Unlike `ToolMaterial`, `ArmorMaterial` does not store any information about the durability of items. +For this reason the durability needs to be manually added to the armor items' `Item.Settings` when registering them. + +This is achieved using the `maxDamage` method in the `Item.Settings` class. +The different armor slots have different base durabilities which are commonly multiplied by a shared armor material multiplier but hard-coded values can also be used. + +For the Guidite armor we'll be using a shared armor multiplier stored alongside the armor material: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +We can then create the armor items using the durability constant: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +You will also need to **add the items to an item group** if you want them to be accessible from the creative inventory. + +As with all items, you should create translation keys for them as well. + +## Texturing and Modelling {#texturing-and-modelling} + +You will need to create two sets of textures: + +- Textures and models for the items themselves. +- The actual armor texture that is visible when an entity wears the armor. + +### Item Textures and Model {#item-textures-and-model} + +These textures are no different to other items - you must create the textures, and create a generic generated item model - which was covered in the [Creating Your First Item](./first-item#adding-a-texture-and-model) guide. + +For example purposes, you may use the following textures and model JSON as a reference. + +Item Textures + +::: info +You will need model JSON files for all the items, not just the helmet, it's the same principle as other item models. +::: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json) + +As you can see, in-game the armor items should have suitable models: + +![Armor item models](/assets/develop/items/armor_1.png) + +## Armor Textures and Model {#armor-textures-and-model} + +When an entity wears your armor, currently the missing texture will appear: + +![Broken armor model on player](/assets/develop/items/armor_2.png) + +There are two layers for the armor texture, both must be present. + +Since the armor material name in our case is `guidite`, the locations of the textures will be: + +- `assets//textures/models/armor/guidite_layer_1.png` +- `assets//textures/models/armor/guidite_layer_2.png` + +Armor Model Textures + +The first layer contains textures for the helmet and chestplate, whilst the second layer contains textures for leggings and boots. + +When these textures are present, you should be able to see your armor on entities that wear it: + +![Working armor model on player](/assets/develop/items/armor_3.png) diff --git a/versions/1.21/develop/items/custom-data-components.md b/versions/1.21/develop/items/custom-data-components.md new file mode 100644 index 000000000..f036d445e --- /dev/null +++ b/versions/1.21/develop/items/custom-data-components.md @@ -0,0 +1,273 @@ +--- +title: Custom Data Components +description: Learn how to add custom data to your items using the new 1.20.5 component system. +authors: + - Romejanic + +search: false +--- + +# Custom Data Components {#custom-data-components} + +As your items grow more complex, you may find yourself needing to store custom data associated with each item. The game allows you to store persistent data within an `ItemStack`, and as of 1.20.5 the way we do that is by using **Data Components**. + +Data Components replace NBT data from previous versions with structured data types which can be applied to an `ItemStack` to store persistent data about that stack. Data components are namespaced, meaning we can implement our own data components to store custom data about an `ItemStack` and access it later. A full list of the vanilla data components can be found on this [Minecraft wiki page](https://minecraft.wiki/w/Data_component_format#List_of_components). + +Along with registering custom components, this page covers the general usage of the components API, which also applies to vanilla components. You can see and access the definitions of all vanilla components in the `DataComponentTypes` class. + +## Registering a Component {#registering-a-component} + +As with anything else in your mod you will need to register your custom component using a `ComponentType`. This component type takes a generic argument containing the type of your component's value. We will be focusing on this in more detail further down when covering [basic](#basic-data-components) and [advanced](#advanced-data-components) components. + +Choose a sensible class to place this in. For this example we're going to make a new package called `component` and a class to contain all of our component types called `ModComponents`. Make sure you call `ModComponents.initialize()` in your [mod's initializer](./getting-started/project-structure#entrypoints). + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +This is the basic template to register a component type: + +```java +public static final ComponentType MY_COMPONENT_TYPE = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "my_component"), + ComponentType.builder().codec(null).build() +); +``` + +There are a few things here worth noting. On the first and fourth lines, you can see a `?`. This will be replaced with the type of your component's value. We'll fill this in soon. + +Secondly, you must provide an `Identifier` containing the intended ID of your component. This is namespaced with your mod's mod ID. + +Lastly, we have a `ComponentType.Builder` that creates the actual `ComponentType` instance that's being registered. This contains another crucial detail we will need to discuss: your component's `Codec`. This is currently `null` but we will also fill it in soon. + +## Basic Data Components {#basic-data-components} + +Basic data components (like `minecraft:damage`) consist of a single data value, such as an `int`, `float`, `boolean` or `String`. + +As an example, let's create an `Integer` value that will track how many times the player has right-clicked while holding our item. Let's update our component registration to the following: + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +You can see that we're now passing `` as our generic type, indicating that this component will be stored as a single `int` value. For our codec, we are using the provided `Codec.INT` codec. We can get away with using basic codecs for simple components like this, but more complex scenarios might require a custom codec (this will be covered briefly later on). + +If you start the game, you should be able to enter a command like this: + +![`/give` command showing the custom component](/assets/develop/items/custom_component_0.png) + +When you run the command, you should receive the item containing the component. However, we are not currently using our component to do anything useful. Let's start by reading the value of the component in a way we can see. + +## Reading Component Value {#reading-component-value} + +Let's add a new item which will increase the counter each time it is right clicked. You should read the [Custom Item Interactions](./custom-item-interactions) page which will cover the techniques we will use in this guide. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Remember as usual to register the item in your `ModItems` class. + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings() +), "counter"); +``` + +We're going to add some tooltip code to display the current value of the click count when we hover over our item in the inventory. We can use the `get()` method on our `ItemStack` to get our component value like so: + +```java +int clickCount = stack.get(ModComponents.CLICK_COUNT_COMPONENT); +``` + +This will return the current component value as the type we defined when we registered our component. We can then use this value to add a tooltip entry. Add this line to the `appendTooltip` method in the `CounterItem` class: + +```java +public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + int count = stack.get(ModComponents.CLICK_COUNT_COMPONENT); + tooltip.add(Text.translatable("item.fabric-docs-reference.counter.info", count).formatted(Formatting.GOLD)); +} +``` + +Don't forget to update your lang file (`/assets//lang/en_us.json`) and add these two lines: + +```json +{ + "item.fabric-docs-reference.counter": "Counter", + "item.fabric-docs-reference.counter.info": "Used %1$s times" +} +``` + +Start up the game and run this command to give yourself a new Counter item with a count of 5. + +```mcfunction +/give @p fabric-docs-reference:counter[fabric-docs-reference:click_count=5] +``` + +When you hover over this item in your inventory, you should see the count displayed in the tooltip! + +![Tooltip showing "Used 5 times"](/assets/develop/items/custom_component_1.png) + +However, if you give yourself a new Counter item _without_ the custom component, the game will crash when you hover over the item in your inventory. You should see an error like this in the crash report: + +```log +java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "net.minecraft.item.ItemStack.get(net.minecraft.component.ComponentType)" is null + at com.example.docs.item.custom.CounterItem.appendTooltip(LightningStick.java:45) + at net.minecraft.item.ItemStack.getTooltip(ItemStack.java:767) +``` + +As expected, since the `ItemStack` doesn't currently contain an instance of our custom component, calling `stack.get()` with our component type will return `null`. + +There are three solutions we can use to address this problem. + +### Setting a Default Component Value {#setting-default-value} + +When you register your item and pass a `Item.Settings` object to your item constructor, you can also provide a list of default components that are applied to all new items. If we go back to our `ModItems` class, where we register the `CounterItem`, we can add a default value for our custom component. Add this so that new items display a count of `0`. + +@[code transcludeWith=::_13](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +When a new item is created, it will automatically apply our custom component with the given value. + +::: warning +Using commands, it is possible to remove a default component from an `ItemStack`. You should refer to the next two sections to properly handle a scenario where the component is not present on your item. +::: + +### Reading with a Default Value {#reading-default-value} + +In addition, when reading the component value, we can use the `getOrDefault()` method on our `ItemStack` object to return a specified default value if the component is not present on the stack. This will safeguard against any errors resulting from a missing component. We can adjust our tooltip code like so: + +```java +int clickCount = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); +``` + +As you can see, this method takes two arguments: our component type like before, and a default value to return if the component is not present. + +### Checking if a Component Exists {#checking-if-component-exists} + +You can also check for the existence of a specific component on an `ItemStack` using the `contains()` method. This takes the component type as an argument and returns `true` or `false` depending on whether the stack contains that component. + +```java +boolean exists = stack.contains(ModComponents.CLICK_COUNT_COMPONENT); +``` + +### Fixing the Error {#fixing-the-error} + +We're going to go with the third option. So along with adding a default component value, we'll also check if the component is present on the stack and only show the tooltip if it is. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Start the game again and hover over the item without the component, you should see that it displays "Used 0 times" and no longer crashes the game. + +![Tooltip showing "Used 0 times"](/assets/develop/items/custom_component_2.png) + +Try giving yourself a Counter with our custom component removed. You can use this command to do so: + +```mcfunction +/give @p fabric-docs-reference:counter[!fabric-docs-reference:click_count] +``` + +When hovering over this item, the tooltip should be missing. + +![Counter item with no tooltip](/assets/develop/items/custom_component_7.png) + +## Updating Component Value {#setting-component-value} + +Now let's try updating our component value. We're going to increase the click count each time we use our Counter item. To change the value of a component on an `ItemStack` we use the `set()` method like so: + +```java +stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +This takes our component type and the value we want to set it to. In this case it will be our new click count. This method also returns the old value of the component (if one is present) which may be useful in some situations. For example: + +```java +int oldValue = stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Let's set up a new `use()` method to read the old click count, increase it by one, and then set the updated click count. + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Now try starting the game and right-clicking with the Counter item in your hand. If you open up your inventory and look at the item again you should see that the usage number has gone up by the amount of times you've clicked it. + +![Tooltip showing "Used 8 times"](/assets/develop/items/custom_component_3.png) + +## Removing Component Value {#removing-component-value} + +You can also remove a component from your `ItemStack` if it is no longer needed. This is done by using the `remove()` method, which takes in your component type. + +```java +stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +This method also returns the value of the component before being removed, so you can also use it as follows: + +```java +int oldCount = stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +## Advanced Data Components {#advanced-data-components} + +You may need to store multiple attributes in a single component. As a vanilla example, the `minecraft:food` component stores several values related to food, such as `nutrition`, `saturation`, `eat_seconds` and more. In this guide we'll refer to them as "composite" components. + +For composite components, you must create a `record` class to store the data. This is the type we'll register in our component type and what we'll read and write when interacting with an `ItemStack`. Start by making a new record class in the `component` package we made earlier. + +```java +public record MyCustomComponent() { +} +``` + +Notice that there's a set of brackets after the class name. This is where we define the list of properties we want our component to have. Let's add a float and a boolean called `temperature` and `burnt` respectively. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Since we are defining a custom data structure, there won't be a pre-existing `Codec` for our use case like with the [basic component](#basic-data-components). This means we're going to have to construct our own codec. Let's define one in our record class using a `RecordCodecBuilder` which we can reference once we register the component. For more details on using a `RecordCodecBuilder` you can refer to [this section of the Codecs page](../codecs#merging-codecs-for-record-like-classes). + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +You can see that we are defining a list of custom fields based on the primitive `Codec` types. However, we are also telling it what our fields are called using `fieldOf()`, and then using `forGetter()` to tell the game which attribute of our record to populate. + +You can also define optional fields by using `optionalFieldOf()` and passing a default value as the second argument. Any fields not marked optional will be required when setting the component using `/give` so make sure you mark any optional arguments as such when creating your codec. + +Finally, we call `apply()` and pass our record's constructor. For more details on how to construct codecs and more advanced use cases, be sure to read the [Codecs](../codecs) page. + +Registering a composite component is similar to before. We just pass our record class as the generic type, and our custom `Codec` to the `codec()` method. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Now start the game. Using the `/give` command, try applying the component. Composite component values are passed as an object enclosed with `{}`. If you put blank curly brackets, you'll see an error telling you that the required key `temperature` is missing. + +![Give command showing missing key "temperature"](/assets/develop/items/custom_component_4.png) + +Add a temperature value to the object using the syntax `temperature:8.2`. You can also optionally pass a value for `burnt` using the same syntax but either `true` or `false`. You should now see that the command is valid, and can give you an item containing the component. + +![Valid give command showing both properties](/assets/develop/items/custom_component_5.png) + +### Getting, Setting and Removing Advanced Components {#getting-setting-removing-advanced-comps} + +Using the component in code is the same as before. Using `stack.get()` will return an instance of your `record` class, which you can then use to read the values. Since records are read-only, you will need to create a new instance of your record to update the values. + +```java +// read values of component +MyCustomComponent comp = stack.get(ModComponents.MY_CUSTOM_COMPONENT); +float temp = comp.temperature(); +boolean burnt = comp.burnt(); + +// set new component values +stack.set(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(8.4f, true)); + +// check for component +if (stack.contains(ModComponents.MY_CUSTOM_COMPONENT)) { + // do something +} + +// remove component +stack.remove(ModComponents.MY_CUSTOM_COMPONENT); +``` + +You can also set a default value for a composite component by passing a component object to your `Item.Settings`. For example: + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings().component(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(0.0f, false)) +), "counter"); +``` + +Now you can store custom data on an `ItemStack`. Use responsibly! + +![Item showing tooltips for click count, temperature and burnt](/assets/develop/items/custom_component_6.png) diff --git a/versions/1.21/develop/items/custom-enchantment-effects.md b/versions/1.21/develop/items/custom-enchantment-effects.md new file mode 100644 index 000000000..72758330d --- /dev/null +++ b/versions/1.21/develop/items/custom-enchantment-effects.md @@ -0,0 +1,64 @@ +--- +title: Custom Enchantment Effects +description: Learn how to create your enchantment effects. +authors: + - krizh-p + +search: false +--- + +# Custom Enchantments {#custom-enchantments} + +Starting from version 1.21, custom enchantments in Minecraft use a "data-driven" approach. This makes it easier to add simple enchantments, like increasing attack damage, but more challenging to create complex ones. The process involves breaking down enchantments into _effect components_. + +An effect component contains the code that defines the special effects of an enchantment. Minecraft supports various default effects, such as item damage, knockback, and experience. + +::: tip +Be sure to check if the default Minecraft effects satisfy your needs by visiting [the Minecraft Wiki's Enchantment Effect Components page](https://minecraft.wiki/w/Enchantment_definition#Effect_components). This guide assumes you understand how to configure "simple" data-driven enchantments and focuses on creating custom enchantment effects that aren't supported by default. +::: + +## Custom Enchantment Effects {#custom-enchantment-effects} + +Start by creating an `enchantment` folder, and within it, create an `effect` folder. Within that, we'll create the `LightningEnchantmentEffect` record. + +Next, we can create a constructor and override the `EnchantmentEntityEffect` interface methods. We'll also create a `CODEC` variable to encode and decode our effect; you can read more about [Codecs here](../codecs). + +The bulk of our code will go into the `apply()` event, which is called when the criteria for your enchantment to work is met. We'll later configure this `Effect` to be called when an entity is hit, but for now, let's write simple code to strike the target with lightning. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/enchantment/effect/LightningEnchantmentEffect.java) + +Here, the `amount` variable indicates a value scaled to the level of the enchantment. We can use this to modify how effective the enchantment is based on level. In the code above, we are using the level of the enchantment to determine how many lightning strikes are spawned. + +## Registering the Enchantment Effect {#registering-the-enchantment-effect} + +Like every other component of your mod, we'll have to add this `EnchantmentEffect` to Minecraft's registry. To do so, add a class `ModEnchantmentEffects` (or whatever you want to name it) and a helper method to register the enchantment. Be sure to call the `registerModEnchantmentEffects()` in your main class, which contains the `onInitialize()` method. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/enchantment/ModEnchantmentEffects.java) + +## Creating the Enchantment {#creating-the-enchantment} + +Now we have an enchantment effect! The final step is to create an enchantment that applies our custom effect. While this can be done by creating a JSON file similar to those in datapacks, this guide will show you how to generate the JSON dynamically using Fabric's data generation tools. To begin, create an `EnchantmentGenerator` class. + +Within this class, we'll first register a new enchantment, and then use the `configure()` method to create our JSON programmatically. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java) + +Before proceeding, you should ensure your project is configured for data generation; if you are unsure, [view the respective docs page](../data-generation/setup). + +Lastly, we must tell our mod to add our `EnchantmentGenerator` to the list of data generation tasks. To do so, simply add the `EnchantmentGenerator` to this inside of the `onInitializeDataGenerator` method. + +@[code transclude={22-22}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +Now, when you run your mod's data generation task, enchantment JSONs will be generated inside the `generated` folder. An example can be seen below: + +@[code](@/reference/1.21/src/main/generated/data/fabric-docs-reference/enchantment/thundering.json) + +You should also add translations to your `en_us.json` file to give your enchantment a readable name: + +```json +"enchantment.FabricDocsReference.thundering": "Thundering", +``` + +You should now have a working custom enchantment effect! Test it by enchanting a weapon with the enchantment and hitting a mob. An example is given in the following video: + + diff --git a/versions/1.21/develop/items/custom-item-groups.md b/versions/1.21/develop/items/custom-item-groups.md new file mode 100644 index 000000000..9188d8a09 --- /dev/null +++ b/versions/1.21/develop/items/custom-item-groups.md @@ -0,0 +1,40 @@ +--- +title: Custom Item Groups +description: Learn how to create your own item group and add items to it. +authors: + - IMB11 + +search: false +--- + +# Custom Item Groups {#custom-item-groups} + +Item groups are the tabs in the creative inventory that store items. You can create your own item group to store your items in a separate tab. This is pretty useful if your mod adds a lot of items and you want to keep them organized in one location for your players to easily access. + +## Creating the Item Group {#creating-the-item-group} + +It's surprisingly easy to create an item group. Simply create a new static final field in your items class to store the item group and a registry key for it, you can then use the item group event similarly to how you added your items to the vanilla item groups: + +@[code transcludeWith=:::9](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::_12](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +
+ +You should see the item group is now in the creative inventory menu. However, it is untranslated - you must add a translation key to your translations file - similarly to how you translated your first item. + +![Item group without translation in creative menu](/assets/develop/items/itemgroups_0.png) + +## Adding a Translation Key {#adding-a-translation-key} + +If you used `Text.translatable` for the `displayName` method of the item group builder, you will need to add the translation to your language file. + +```json +{ + "itemGroup.fabric_docs_reference": "Fabric Docs Reference" +} +``` + +Now, as you can see, the item group should be correctly named: + +![Fully completed item group with translation and items](/assets/develop/items/itemgroups_1.png) diff --git a/versions/1.21/develop/items/custom-item-interactions.md b/versions/1.21/develop/items/custom-item-interactions.md new file mode 100644 index 000000000..0a5546340 --- /dev/null +++ b/versions/1.21/develop/items/custom-item-interactions.md @@ -0,0 +1,73 @@ +--- +title: Custom Item Interactions +description: Learn how to create an item that uses built-in vanilla events. +authors: + - IMB11 + +search: false +--- + +# Custom Item Interactions {#custom-item-interactions} + +Basic items can only go so far - eventually you will need an item that interacts with the world when it is used. + +There are some key classes you must understand before taking a look at the vanilla item events. + +## TypedActionResult {#typedactionresult} + +For items, the most common `TypedActionResult` you'll see is for `ItemStacks` - this class tells the game what to replace the item stack (or not to replace) after the event has occured. + +If nothing has occured in the event, you should use the `TypedActionResult#pass(stack)` method where `stack` is the current item stack. + +You can get the current item stack by getting the stack in the player's hand. Usually events that require a `TypedActionResult` pass the hand to the event method. + +```java +TypedActionResult.pass(user.getStackInHand(hand)) +``` + +If you pass the current stack - nothing will change, regardless of if you declare the event as failed, passed/ignored or successful. + +If you want to delete the current stack, you should pass an empty one. The same can be said about decrementing, you fetch the current stack and decrement it by the amount you want: + +```java +ItemStack heldStack = user.getStackInHand(hand); +heldStack.decrement(1); +TypedActionResult.success(heldStack); +``` + +## ActionResult {#actionresult} + +Similarly, an `ActionResult` tells the game the status of the event, whether it was passed/ignored, failed or successful. + +## Overridable Events {#overridable-events} + +Luckily, the Item class has many methods that can be overriden to add extra functionality to your items. + +::: info +A great example of these events being used can be found in the [Playing SoundEvents](../sounds/using-sounds) page, which uses the `useOnBlock` event to play a sound when the player right clicks a block. +::: + +| Method | Information | +| --------------- | ------------------------------------------------------- | +| `postHit` | Ran when the player hits an entity. | +| `postMine` | Ran when the player mines a block. | +| `inventoryTick` | Ran every tick whilst the item is in an inventory. | +| `onCraft` | Ran when the item is crafted. | +| `useOnBlock` | Ran when the player right clicks a block with the item. | +| `use` | Ran when the player right clicks the item. | + +## The `use()` Event {#use-event} + +Let's say you want to make an item that summons a lightning bolt infront of the player - you would need to create a custom class. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +The `use` event is probably the most useful out of them all - you can use this event to spawn our lightning bolt, you should spawn it 10 blocks in front of the players facing direction. + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +As usual, you should register your item, add a model and texture. + +As you can see, the lightning bolt should spawn 10 blocks infront of you - the player. + + diff --git a/versions/1.21/develop/items/custom-tools.md b/versions/1.21/develop/items/custom-tools.md new file mode 100644 index 000000000..9d22ca1ad --- /dev/null +++ b/versions/1.21/develop/items/custom-tools.md @@ -0,0 +1,106 @@ +--- +title: Tools and Weapons +description: Learn how to create your own tools and configure their properties. +authors: + - IMB11 + +search: false +--- + +# Tools {#tools} + +Tools are essential for survival and progression, allowing players to gather resources, construct buildings, and defend themselves. + +## Creating a Tool Material {#creating-a-tool-material} + +::: info +If you're creating multiple tool materials, consider using an `Enum` to store them. Vanilla does this in the `ToolMaterials` class, which stores all the tool materials that are used in the game. + +This class can also be used to determine your tool material's properties in relation to vanilla tool materials. +::: + +You can create a tool material by creating a new class that inherits it - in this example, I'll be creating "Guidite" tools: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Once you have created your tool material and tweaked it to your likings, you can create an instance of it to be used in the tool item constructors. + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +The tool material tells the game the following information: + +### Durability - `getDurability()` {#durability} + +How many times the tool can be used before breaking: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Mining Speed - `getMiningSpeedMultiplier()` {#mining-speed} + +If the tool is used to break blocks, how fast should it break the blocks? + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +For reference purposes, the diamond tool material has a mining speed of `8.0F` whilst the stone tool material has a mining speed of `4.0F`. + +### Attack Damage - `getAttackDamage()` {#attack-damage} + +How many points of damage should the tool do when used as a weapon against another entity? + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Inverse Tag - `getMiningLevel()` {#inverse-tag} + +The inverse tag shows what the tool _**cannot**_ mine. For instance, using the `BlockTags.INCORRECT_FOR_WOODEN_TOOL` tag stops the tool from mining certain blocks: + +```json +{ + "values": [ + "#minecraft:needs_diamond_tool", + "#minecraft:needs_iron_tool", + "#minecraft:needs_stone_tool" + ] +} +``` + +This means the tool can't mine blocks that need a diamond, iron, or stone tool. + +Let's use the iron tool tag. This stops Guidite tools from mining blocks that require a stronger tool than iron. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +You can use `TagKey.of(...)` to create a custom tag key if you want to use a custom tag. + +### Enchantability - `getEnchantability()` {#enchantability} + +How easy is it to get better and higher level enchantments with this item? For reference, Gold has an enchantability of 22 whilst Netherite has an enchantability of 15. + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Repair Ingredient(s) - `getRepairIngredient()` {#repair-ingredient} + +What item or items are used to repair the tool? + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +## Creating Tool Items {#creating-tool-items} + +Using the same utility function as in the [Creating Your First Item](./first-item) guide, you can create your tool items: + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Remember to add them to an item group if you want to access them from the creative inventory! + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +You will also have to add a texture, item translation and item model. However, for the item model, you'll want to use the `item/handheld` model as your parent. + +For this example, I will be using the following model and texture for the "Guidite Sword" item: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json) + +Texture + +That's pretty much it! If you go in-game you should see your tool item(s) in the tools tab of the creative inventory menu. + +![Finished tools in inventory](/assets/develop/items/tools_1.png) diff --git a/versions/1.21/develop/items/first-item.md b/versions/1.21/develop/items/first-item.md new file mode 100644 index 000000000..465fbed2b --- /dev/null +++ b/versions/1.21/develop/items/first-item.md @@ -0,0 +1,153 @@ +--- +title: Creating Your First Item +description: Learn how to register a simple item and how to texture, model and name it. +authors: + - IMB11 + - dicedpixels + +search: false +--- + +# Creating Your First Item {#creating-your-first-item} + +This page will introduce you into some key concepts relating to items, and how you can register, texture, model and name them. + +If you aren't aware, everything in Minecraft is stored in registries, and items are no exception to that. + +## Preparing Your Items Class {#preparing-your-items-class} + +To simplify the registering of items, you can create a method that accepts an instance of an item and a string identifier. + +This method will create an item with the provided identifier and register it with the game's item registry. + +You can put this method in a class called `ModItems` (or whatever you want to name the class). + +Mojang does this with their items as well! Check out the `Items` class for inspiration. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Registering an Item {#registering-an-item} + +You can now register an item using the method now. + +The item constructor takes in an instance of the `Items.Settings` class as a parameter. This class allows you to configure the item's properties through various builder methods. + +::: tip +If you want to change your item's stack size, you can use the `maxCount` method in the `Items.Settings`/`FabricItemSettings` class. + +This will not work if you've marked the item as damageable, as the stack size is always 1 for damageable items to prevent duplication exploits. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +However, if you now try to run the modified client, you can see that our item doesn't exist in-game yet! This is because you didn't statically initialize the class. + +To do this, you can add a public static initialize method to your class and call it from your [mod's initializer](./getting-started/project-structure#entrypoints) class. Currently, this method doesn't need anything inside it. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java) + +Calling a method on a class statically initializes it if it hasn't been previously loaded - this means that all `static` fields are evaluated. This is what this dummy `initialize` method is for. + +## Adding the Item to an Item Group {#adding-the-item-to-an-item-group} + +::: info +If you want to add the item to a custom `ItemGroup`, check out the [Custom Item Groups](./custom-item-groups) page for more information. +::: + +For example purposes, we will add this item to the ingredients `ItemGroup`, you will need to use Fabric API's item group events - specifically `ItemGroupEvents.modifyEntriesEvent` + +This can be done in the `initialize` method of your items class. + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Loading into the game, you can see that our item has been registered, and is in the Ingredients item group: + +![Item in the ingredients group](/assets/develop/items/first_item_0.png) + +However, it's missing the following: + +- Item Model +- Texture +- Translation (name) + +## Naming The Item {#naming-the-item} + +The item currently doesn't have a translation, so you will need to add one. The translation key has already been provided by Minecraft: `item.mod_id.suspicious_substance`. + +Create a new JSON file at: `src/main/resources/assets//lang/en_us.json` and put in the translation key, and its value: + +```json +{ + "item.mod_id.suspicious_substance": "Suspicious Substance" +} +``` + +You can either restart the game or build your mod and press F3+T to apply changes. + +## Adding a Texture and Model {#adding-a-texture-and-model} + +To give your item a texture and model, simply create a 16x16 texture image for your item and save it in the `assets//textures/item` folder. Name the texture file the same as the item's identifier, but with a `.png` extension. + +For example purposes, you can use this example texture for `suspicious_substance.png` + +Texture + +When restarting/reloading the game - you should see that the item still has no texture, that's because you will need to add a model that uses this texture. + +You're going to create a simple `item/generated` model, which takes in an input texture and nothing else. + +Create the model JSON in the `assets//models/item` folder, with the same name as the item; `suspicious_substance.json` + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) + +### Breaking Down the Model JSON {#breaking-down-the-model-json} + +- `parent`: This is the parent model that this model will inherit from. In this case, it's the `item/generated` model. +- `textures`: This is where you define the textures for the model. The `layer0` key is the texture that the model will use. + +Most items will use the `item/generated` model as their parent, as it's a simple model that just displays the texture. + +There are alternatives, such as `item/handheld` which is used for items that are held in the player's hand, such as tools. + +Your item should now look like this in-game: + +![Item with correct model](/assets/develop/items/first_item_2.png) + +## Making the Item Compostable or a Fuel {#making-the-item-compostable-or-a-fuel} + +Fabric API provides various registries that can be used to add additional properties to your item. + +For example, if you want to make your item compostable, you can use the `CompostableItemRegistry`: + +@[code transcludeWith=:::_10](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Alternatively, if you want to make your item a fuel, you can use the `FuelRegistry` class: + +@[code transcludeWith=:::_11](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Adding a Basic Crafting Recipe {#adding-a-basic-crafting-recipe} + + + +If you want to add a crafting recipe for your item, you will need to place a recipe JSON file in the `data//recipe` folder. + +For more information on the recipe format, check out these resources: + +- [Recipe JSON Generator](https://crafting.thedestruc7i0n.ca/) +- [Minecraft Wiki - Recipe JSON](https://minecraft.wiki/w/Recipe#JSON_Format) + +## Custom Tooltips {#custom-tooltips} + +If you want your item to have a custom tooltip, you will need to create a class that extends `Item` and override the `appendTooltip` method. + +::: info +This example uses the `LightningStick` class created in the [Custom Item Interactions](./custom-item-interactions) page. +::: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Each call to `add()` will add one line to the tooltip. + +![Tooltip Showcase](/assets/develop/items/first_item_3.png) diff --git a/versions/1.21/develop/items/food.md b/versions/1.21/develop/items/food.md new file mode 100644 index 000000000..80a955c65 --- /dev/null +++ b/versions/1.21/develop/items/food.md @@ -0,0 +1,54 @@ +--- +title: Food Items +description: Learn how to add a FoodComponent to an item to make it edible, and configure it. +authors: + - IMB11 + +search: false +--- + +# Food Items {#food-items} + +Food is a core aspect of survival Minecraft, so when creating edible items you have to consider the food's usage with other edible items. + +Unless you're making a mod with overpowered items, you should consider: + +- How much hunger your edible item adds or removes. +- What potion effect(s) does it grant? +- Is it early-game or endgame accessible? + +## Adding the Food Component {#adding-the-food-component} + +To add a food component to an item, we can pass it to the `Item.Settings` instance: + +```java +new Item.Settings().food(new FoodComponent.Builder().build()) +``` + +Right now, this just makes the item edible and nothing more. + +The `FoodComponent.Builder` class has many methods that allow you to modify what happens when a player eats your item: + +| Method | Description | +| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `nutrition` | Sets the amount of hunger points your item will replenish. | +| `saturationModifier` | Sets the amount of saturation points your item will add. | +| `alwaysEdible` | Allows your item to be eaten regardless of hunger level. | +| `snack` | Declares your item as a snack. | +| `statusEffect` | Adds a status effect when you eat your item. Usually a status effect instance and chance is passed to this method, where chance is a decimal percentage (`1f = 100%`) | + +When you've modified the builder to your liking, you can call the `build()` method to get the `FoodComponent`. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Similar to the example in the [Creating Your First Item](./first-item) page, I'll be using the above component: + +@[code transcludeWith=:::poisonous_apple](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +This makes the item: + +- Always edible, it can be eaten regardless of hunger level. +- A "snack". +- Always give Poison II for 6 seconds when eaten. + + diff --git a/versions/1.21/develop/items/potions.md b/versions/1.21/develop/items/potions.md new file mode 100644 index 000000000..4befc086e --- /dev/null +++ b/versions/1.21/develop/items/potions.md @@ -0,0 +1,54 @@ +--- +title: Potions +description: Learn how to add a custom potion for various status effects. +authors: + - dicedpixels + - PandoricaVi + - Drakonkinst + - JaaiDead + +search: false +--- + +# Potions {#potions} + +Potions are consumables that grants an entity an effect. A player can brew potions using a Brewing Stand or obtain them +as items through various other game mechanics. + +## Custom Potions {#custom-potions} + +Just like items and blocks, potions need to be registered. + +### Creating the Potion {#creating-the-potion} + +Let's start by declaring a field to store your `Potion` instance. We will be directly using a `ModInitializer`-implementing class to +hold this. + +@[code lang=java transclude={18-27}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +We pass an instance of `StatusEffectInstance`, which takes 3 parameters: + +- `RegistryEntry type` - An effect. We use our custom effect here. Alternatively you can access vanilla effects + through vanilla's `StatusEffects` class. +- `int duration` - Duration of the effect in game ticks. +- `int amplifier` - An amplifier for the effect. For example, Haste II would have an amplifier of 1. + +::: info +To create your own potion effect, please see the [Effects](../entities/effects) guide. +::: + +### Registering the Potion {#registering-the-potion} + +In our initializer, we will use the `FabricBrewingRecipeRegistryBuilder.BUILD` event to register our potion using the `BrewingRecipeRegistry.registerPotionRecipe` method. + +@[code lang=java transclude={29-42}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +`registerPotionRecipe` takes 3 parameters: + +- `RegistryEntry input` - The starting potion's registry entry. Usually this can be a Water Bottle or an Awkward Potion. +- `Item item` - The item which is the main ingredient of the potion. +- `RegistryEntry output` - The resultant potion's registry entry. + +Once registered, you can brew a Tater potion using a potato. + +![Effect in player inventory](/assets/develop/tater-potion.png) diff --git a/versions/1.21/develop/rendering/basic-concepts.md b/versions/1.21/develop/rendering/basic-concepts.md new file mode 100644 index 000000000..29998d935 --- /dev/null +++ b/versions/1.21/develop/rendering/basic-concepts.md @@ -0,0 +1,164 @@ +--- +title: Basic Rendering Concepts +description: Learn about the basic concepts of rendering using Minecraft's rendering engine. +authors: + - IMB11 + - "0x3C50" + +search: false +--- + +# Basic Rendering Concepts {#basic-rendering-concepts} + +::: warning +Although Minecraft is built using OpenGL, as of version 1.17+ you cannot use legacy OpenGL methods to render your own things. Instead, you must use the new `BufferBuilder` system, which formats rendering data and uploads it to OpenGL to draw. + +To summarize, you have to use Minecraft's rendering system, or build your own that utilizes `GL.glDrawElements()`. +::: + +This page will cover the basics of rendering using the new system, going over key terminology and concepts. + +Although much of rendering in Minecraft is abstracted through the various `DrawContext` methods, and you'll likely not need to touch anything mentioned here, it's still important to understand the basics of how rendering works. + +## The `Tessellator` {#the-tessellator} + +The `Tessellator` is the main class used to render things in Minecraft. It is a singleton, meaning that there is only one instance of it in the game. You can get the instance using `Tessellator.getInstance()`. + +## The `BufferBuilder` {#the-bufferbuilder} + +The `BufferBuilder` is the class used to format and upload rendering data to OpenGL. It is used to create a buffer, which is then uploaded to OpenGL to draw. + +The `Tessellator` is used to create a `BufferBuilder`, which is used to format and upload rendering data to OpenGL. + +### Initializing the `BufferBuilder` {#initializing-the-bufferbuilder} + +Before you can write anything to the `BufferBuilder`, you must initialize it. This is done using `Tessellator#begin(...)` method, which takes in a `VertexFormat` and a draw mode and returns a `BufferBuilder`. + +#### Vertex Formats {#vertex-formats} + +The `VertexFormat` defines the elements that we include in our data buffer and outlines how these elements should be transmitted to OpenGL. + +The following `VertexFormat` elements are available: + +| Element | Format | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | +| `BLIT_SCREEN` | `{ position (3 floats: x, y and z), uv (2 floats), color (4 ubytes) }` | +| `POSITION_COLOR_TEXTURE_LIGHT_NORMAL` | `{ position, color, texture uv, texture light (2 shorts), texture normal (3 sbytes) }` | +| `POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL` | `{ position, color, texture uv, overlay (2 shorts), texture light, normal (3 sbytes) }` | +| `POSITION_TEXTURE_COLOR_LIGHT` | `{ position, texture uv, color, texture light }` | +| `POSITION` | `{ position }` | +| `POSITION_COLOR` | `{ position, color }` | +| `LINES` | `{ position, color, normal }` | +| `POSITION_COLOR_LIGHT` | `{ position, color, light }` | +| `POSITION_TEXTURE` | `{ position, uv }` | +| `POSITION_COLOR_TEXTURE` | `{ position, color, uv }` | +| `POSITION_TEXTURE_COLOR` | `{ position, uv, color }` | +| `POSITION_COLOR_TEXTURE_LIGHT` | `{ position, color, uv, light }` | +| `POSITION_TEXTURE_LIGHT_COLOR` | `{ position, uv, light, color }` | +| `POSITION_TEXTURE_COLOR_NORMAL` | `{ position, uv, color, normal }` | + +#### Draw Modes {#draw-modes} + +The draw mode defines how the data is drawn. The following draw modes are available: + +| Draw Mode | Description | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `DrawMode.LINES` | Each element is made up of 2 vertices and is represented as a single line. | +| `DrawMode.LINE_STRIP` | The first element requires 2 vertices. Additional elements are drawn with just 1 new vertex, creating a continuous line. | +| `DrawMode.DEBUG_LINES` | Similar to `DrawMode.LINES`, but the line is always exactly one pixel wide on the screen. | +| `DrawMode.DEBUG_LINE_STRIP` | Same as `DrawMode.LINE_STRIP`, but lines are always one pixel wide. | +| `DrawMode.TRIANGLES` | Each element is made up of 3 vertices, forming a triangle. | +| `DrawMode.TRIANGLE_STRIP` | Starts with 3 vertices for the first triangle. Each additional vertex forms a new triangle with the last two vertices. | +| `DrawMode.TRIANGLE_FAN` | Starts with 3 vertices for the first triangle. Each additional vertex forms a new triangle with the first vertex and the last vertex. | +| `DrawMode.QUADS` | Each element is made up of 4 vertices, forming a quadrilateral. | + +### Writing to the `BufferBuilder` {#writing-to-the-bufferbuilder} + +Once the `BufferBuilder` is initialized, you can write data to it. + +The `BufferBuilder` allows us to construct our buffer, vertex by vertex. To add a vertex, we use the `buffer.vertex(matrix, float, float, float)` method. The `matrix` parameter is the transformation matrix, which we'll discuss in more detail later. The three float parameters represent the (x, y, z) coordinates of the vertex position. + +This method returns a vertex builder, which we can use to specify additional information for the vertex. It's crucial to follow the order of our defined `VertexFormat` when adding this information. If we don't, OpenGL might not interpret our data correctly. After we've finished building a vertex, just continue adding more vertices and data to the buffer until you're done. + +It's also worth understanding the concept of culling. Culling is the process of removing faces of a 3D shape that aren't visible from the viewer's perspective. If the vertices for a face are specified in the wrong order, the face might not render correctly due to culling. + +#### What Is a Transformation Matrix? {#what-is-a-transformation-matrix} + +A transformation matrix is a 4x4 matrix that is used to transform a vector. In Minecraft, the transformation matrix is just transforming the coordinates we give into the vertex call. The transformations can scale our model, move it around and rotate it. + +It's sometimes referred to as a position matrix, or a model matrix. + +It's usually obtained via the `MatrixStack` class, which can be obtained via the `DrawContext` object: + +```java +drawContext.getMatrices().peek().getPositionMatrix(); +``` + +#### Rendering a Triangle Strip {#rendering-a-triangle-strip} + +It's easier to explain how to write to the `BufferBuilder` using a practical example. Let's say we want to render something using the `DrawMode.TRIANGLE_STRIP` draw mode and the `POSITION_COLOR` vertex format. + +We're going to draw vertices at the following points on the HUD (in order): + +```txt +(20, 20) +(5, 40) +(35, 40) +(20, 60) +``` + +This should give us a lovely diamond - since we're using the `TRIANGLE_STRIP` draw mode, the renderer will perform the following steps: + +![Four steps that show the placement of the vertices on the screen to form two triangles](/assets/develop/rendering/concepts-practical-example-draw-process.png) + +Since we're drawing on the HUD in this example, we'll use the `HudRenderCallback` event: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +This results in the following being drawn on the HUD: + +![Final Result](/assets/develop/rendering/concepts-practical-example-final-result.png) + +::: tip +Try mess around with the colors and positions of the vertices to see what happens! You can also try using different draw modes and vertex formats. +::: + +## The `MatrixStack` {#the-matrixstack} + +After learning how to write to the `BufferBuilder`, you might be wondering how to transform your model - or even animate it. This is where the `MatrixStack` class comes in. + +The `MatrixStack` class has the following methods: + +- `push()` - Pushes a new matrix onto the stack. +- `pop()` - Pops the top matrix off the stack. +- `peek()` - Returns the top matrix on the stack. +- `translate(x, y, z)` - Translates the top matrix on the stack. +- `scale(x, y, z)` - Scales the top matrix on the stack. + +You can also multiply the top matrix on the stack using quaternions, which we will cover in the next section. + +Taking from our example above, we can make our diamond scale up and down by using the `MatrixStack` and the `tickDelta` - which is the time that has passed since the last frame. + +::: warning +You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. + +Make sure to push the matrix stack before you get a transformation matrix! +::: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +![A video showing the diamond scaling up and down](/assets/develop/rendering/concepts-matrix-stack.webp) + +## Quaternions (Rotating Things) {#quaternions-rotating-things} + +Quaternions are a way of representing rotations in 3D space. They are used to rotate the top matrix on the `MatrixStack` via the `multiply(Quaternion, x, y, z)` method. + +It's highly unlikely you'll need to ever use a Quaternion class directly, since Minecraft provides various pre-built Quaternion instances in it's `RotationAxis` utility class. + +Let's say we want to rotate our diamond around the z-axis. We can do this by using the `MatrixStack` and the `multiply(Quaternion, x, y, z)` method. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +The result of this is the following: + +![A video showing the diamond rotating around the z-axis](/assets/develop/rendering/concepts-quaternions.webp) diff --git a/versions/1.21/develop/rendering/draw-context.md b/versions/1.21/develop/rendering/draw-context.md new file mode 100644 index 000000000..4f2ceeac3 --- /dev/null +++ b/versions/1.21/develop/rendering/draw-context.md @@ -0,0 +1,96 @@ +--- +title: Using the Drawing Context +description: Learn how to use the DrawContext class to render various shapes, text and textures. +authors: + - IMB11 + +search: false +--- + +# Using the Drawing Context {#using-the-drawing-context} + +This page assumes you've taken a look at the [Basic Rendering Concepts](./basic-concepts) page. + +The `DrawContext` class is the main class used for rendering in the game. It is used for rendering shapes, text and textures, and as previously seen, used to manipulate `MatrixStack`s and use `BufferBuilder`s. + +## Drawing Shapes {#drawing-shapes} + +The `DrawContext` class can be used to easily draw **square-based** shapes. If you want to draw triangles, or any non-square based shape, you will need to use a `BufferBuilder`. + +### Drawing Rectangles {#drawing-rectangles} + +You can use the `DrawContext.fill(...)` method to draw a filled rectangle. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![A rectangle](/assets/develop/rendering/draw-context-rectangle.png) + +### Drawing Outlines/Borders {#drawing-outlines-borders} + +Let's say we want to outline the rectangle we just drew. We can use the `DrawContext.drawBorder(...)` method to draw an outline. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Rectangle with border](/assets/develop/rendering/draw-context-rectangle-border.png) + +### Drawing Individual Lines {#drawing-individual-lines} + +We can use the `DrawContext.drawHorizontalLine(...)` and `DrawContext.drawVerticalLine(...)` methods to draw lines. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Lines](/assets/develop/rendering/draw-context-lines.png) + +## The Scissor Manager {#the-scissor-manager} + +The `DrawContext` class has a built-in scissor manager. This allows you to easily clip your rendering to a specific area. This is useful for rendering things like tooltips, or other elements that should not be rendered outside of a specific area. + +### Using the Scissor Manager {#using-the-scissor-manager} + +::: tip +Scissor regions can be nested! But make sure that you disable the scissor manager the same amount of times as you enabled it. +::: + +To enable the scissor manager, simply use the `DrawContext.enableScissor(...)` method. Likewise, to disable the scissor manager, use the `DrawContext.disableScissor()` method. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Scissor region in action](/assets/develop/rendering/draw-context-scissor.png) + +As you can see, even though we tell the game to render the gradient across the entire screen, it only renders within the scissor region. + +## Drawing Textures {#drawing-textures} + +There is no one "correct" way to draw textures onto a screen, as the `drawTexture(...)` method has many different overloads. This section will go over the most common use cases. + +### Drawing an Entire Texture {#drawing-an-entire-texture} + +Generally, it's recommended that you use the overload that specifies the `textureWidth` and `textureHeight` parameters. This is because the `DrawContext` class will assume these values if you don't provide them, which can sometimes be wrong. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Drawing whole texture example](/assets/develop/rendering/draw-context-whole-texture.png) + +### Drawing a Portion of a Texture {#drawing-a-portion-of-a-texture} + +This is where `u` and `v` come in. These parameters specify the top-left corner of the texture to draw, and the `regionWidth` and `regionHeight` parameters specify the size of the portion of the texture to draw. + +Let's take this texture as an example. + +![Recipe Book Texture](/assets/develop/rendering/draw-context-recipe-book-background.png) + +If we want to only draw a region that contains the magnifying glass, we can use the following `u`, `v`, `regionWidth` and `regionHeight` values: + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Region Texture](/assets/develop/rendering/draw-context-region-texture.png) + +## Drawing Text {#drawing-text} + +The `DrawContext` class has various self-explanatory text rendering methods - for the sake of brevity, they will not be covered here. + +Let's say we want to draw "Hello World" onto the screen. We can use the `DrawContext.drawText(...)` method to do this. + +@[code lang=java transcludeWith=:::7](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Drawing text](/assets/develop/rendering/draw-context-text.png) diff --git a/versions/1.21/develop/rendering/gui/custom-screens.md b/versions/1.21/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..b5a017015 --- /dev/null +++ b/versions/1.21/develop/rendering/gui/custom-screens.md @@ -0,0 +1,66 @@ +--- +title: Custom Screens +description: Learn how to create custom screens for your mod. +authors: + - IMB11 + +search: false +--- + +# Custom Screens {#custom-screens} + +::: info +This page refers to normal screens, not handled ones - these screens are the ones that are opened by the player on the client, not the ones that are handled by the server. +::: + +Screens are essentially the GUIs that the player interacts with, such as the title screen, pause screen etc. + +You can create your own screens to display custom content, a custom settings menu, or more. + +## Creating a Screen {#creating-a-screen} + +To create a screen, you need to extend the `Screen` class and override the `init` method - you may optionally override the `render` method as well - but make sure to call it's super method or it wont render the background, widgets etc. + +You should take note that: + +- Widgets are not being created in the constructor because the screen is not yet initialized at that point - and certain variables, such as `width` and `height`, are not yet available or not yet accurate. +- The `init` method is called when the screen is being initialized, and it is the best place to create widgets. + - You add widgets using the `addDrawableChild` method, which accepts any drawable widget. +- The `render` method is called every frame - you can access the draw context, and the mouse position from this method. + +As an example, we can create a simple screen that has a button and a label above it. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Custom Screen 1](/assets/develop/rendering/gui/custom-1-example.png) + +## Opening the Screen {#opening-the-screen} + +You can open the screen using the `MinecraftClient`'s `setScreen` method - you can do this from many places, such as a key binding, a command, or a client packet handler. + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## Closing the Screen {#closing-the-screen} + +If you want to close the screen, simply set the screen to `null`: + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +If you want to be fancy, and return to the previous screen, you can pass the current screen into the `CustomScreen` constructor and store it in a field, then use it to return to the previous screen when the `close` method is called. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +Now, when opening the custom screen, you can pass the current screen as the second argument - so when you call `CustomScreen#close` - it will return to the previous screen. + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/develop/rendering/gui/custom-widgets.md b/versions/1.21/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..59f2e53d9 --- /dev/null +++ b/versions/1.21/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,41 @@ +--- +title: Custom Widgets +description: Learn how to create custom widgets for your screens. +authors: + - IMB11 + +search: false +--- + +# Custom Widgets {#custom-widgets} + +Widgets are essentially containerized rendering components that can be added to a screen, and can be interacted with by the player through various events such as mouse clicks, key presses, and more. + +## Creating a Widget {#creating-a-widget} + +There are multiple ways to create a widget class, such as extending `ClickableWidget`. This class provides a lot of useful utilities, such as managing width, height, position, and handling events - it implements the `Drawable`, `Element`, `Narratable`, and `Selectable` interfaces: + +- `Drawable` - for rendering - Required to register the widget to the screen via the `addDrawableChild` method. +- `Element` - for events - Required if you want to handle events such as mouse clicks, key presses, and more. +- `Narratable` - for accessibility - Required to make your widget accessible to screen readers and other accessibility tools. +- `Selectable` - for selection - Required if you want to make your widget selectable using the Tab key - this also aids in accessibility. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## Adding the Widget to the Screen {#adding-the-widget-to-the-screen} + +Like all widgets, you need to add it to the screen using the `addDrawableChild` method, which is provided by the `Screen` class. Make sure you do this in the `init` method. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Custom widget on screen](/assets/develop/rendering/gui/custom-widget-example.png) + +## Widget Events {#widget-events} + +You can handle events such as mouse clicks, key presses, by overriding the `onMouseClicked`, `onMouseReleased`, `onKeyPressed`, and other methods. + +For example, you can make the widget change color when it's hovered over by using the `isHovered()` method provided by the `ClickableWidget` class: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![Hover Event Example](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/develop/rendering/hud.md b/versions/1.21/develop/rendering/hud.md new file mode 100644 index 000000000..1b7ee6cd2 --- /dev/null +++ b/versions/1.21/develop/rendering/hud.md @@ -0,0 +1,32 @@ +--- +title: Rendering in the Hud +description: Learn how to use the HudRenderCallback event to render to the hud. +authors: + - IMB11 + +search: false +--- + +# Rendering in the Hud {#rendering-in-the-hud} + +We already briefly touched on rendering things to the hud in the [Basic Rendering Concepts](./basic-concepts) page and [Using The Drawing Context](./draw-context), so on this page we'll stick to the `HudRenderCallback` event and the `deltaTick` parameter. + +## HudRenderCallback {#hudrendercallback} + +The `HudRenderCallback` event - provided by Fabric API - is called every frame, and is used to render things to the HUD. + +To register to this event, you can simply call `HudRenderCallback.EVENT.register` and pass in a lambda that takes a `DrawContext` and a `float` (deltaTick) as parameters. + +The draw context can be used to access the various rendering utilities provided by the game, and access the raw matrix stack. + +You should check out the [Draw Context](./draw-context) page to learn more about the draw context. + +### DeltaTick {#deltatick} + +The `deltaTick` refers to the time since the last frame, in seconds. This can be used to make animations and other time-based effects. + +For example, let's say you want to lerp a color over time. You can use the `deltaTickManager` to get the deltaTick, and store it over time to lerp the color: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java) + +![Lerping a color over time](/assets/develop/rendering/hud-rendering-deltatick.webp) diff --git a/versions/1.21/develop/rendering/particles/creating-particles.md b/versions/1.21/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..1a63a53c3 --- /dev/null +++ b/versions/1.21/develop/rendering/particles/creating-particles.md @@ -0,0 +1,74 @@ +--- +title: Creating Custom Particles +description: Learn how to create a custom particle using Fabric API. +authors: + - Superkat32 + +search: false +--- + +# Creating Custom Particles {#creating-custom-particles} + +Particles are a powerful tool. They can add ambience to a beautiful scene, or add tension to an edge of your seat boss battle. Let's add one! + +## Register a Custom Particle {#register-a-custom-particle} + +We'll be adding a new sparkle particle which will mimic the movement of an end rod particle. + +We first need to register a `ParticleType` in your [mod's initializer](./getting-started/project-structure#entrypoints) class using your mod id. + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +The "sparkle_particle" in lowercase letters is the JSON path for the particle's texture. You will be creating a new JSON file with that exact name later. + +## Client-Side Registration {#client-side-registration} + +After you have registered the particle in the mod's initializer, you will also need to register the particle in the client-side initializer. + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +In this example, we are registering our particle on the client-side. We are then giving the particle some movement using the end rod particle's factory. This means our particle will move exactly like an end rod particle. + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- IntelliJ's hotkey: Ctrl+Alt+B +- Visual Studio Code's hotkey: Ctrl+F12 +::: + +## Creating a JSON File and Adding Textures {#creating-a-json-file-and-adding-textures} + +You will need to create 2 folders in your `resources/assets//` folder. + +| Folder Path | Explanation | +| -------------------- | ------------------------------------------------------------------------------------ | +| `/textures/particle` | The `particle` folder will contain all the textures for all of your particles. | +| `/particles` | The `particles` folder will contain all of the json files for all of your particles. | + +For this example, we will have only one texture in `textures/particle` called "sparkle_particle_texture.png". + +Next, create a new JSON file in `particles` with the same name as the JSON path that you used when registering your ParticleType. For this example, we will need to create `sparkle_particle.json`. This file is important because it lets Minecraft know which textures our particle should use. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +::: tip +You can add more textures to the `textures` array to create a particle animation. The particle will cycle through the textures in the array, starting with the first texture. +::: + +## Testing the New Particle {#testing-the-new-particle} + +Once you have completed the JSON file and saved your work, you are good to load up Minecraft and test everything out! + +You can see if everything has worked by typing the following command: + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![Showcase of the particle](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +::: info +The particle will spawn inside the player with this command. You will likely need to walk backwards to actually see it. +::: + +Alternatively, you can also use a command block to summon the particle with the exact same command. diff --git a/versions/1.21/develop/sounds/custom.md b/versions/1.21/develop/sounds/custom.md new file mode 100644 index 000000000..645d93e00 --- /dev/null +++ b/versions/1.21/develop/sounds/custom.md @@ -0,0 +1,65 @@ +--- +title: Creating Custom Sounds +description: Learn how to add and use a new sound with the registry. +authors: + - JR1811 + +search: false +--- + +# Creating Custom Sounds {#creating-custom-sounds} + +## Preparing the Audio File {#preparing-the-audio-file} + +Your audio files need to be formatted in a specific way. OGG Vorbis is an open container format for multimedia data, such as audio, and is used in case of Minecraft's sound files. To avoid problems with how Minecraft handles distancing, your audio needs to have only a single channel (Mono). + +Many modern DAWs (Digital Audio Workstation) software can import and export using this file format. In the following example the free and open-source software "[Audacity](https://www.audacityteam.org/)" will be used to bring the audio file into the right format, however any other DAW should suffice as well. + +![Unprepared audio file in Audacity](/assets/develop/sounds/custom_sounds_0.png) + +In this example, a sound of a [whistle](https://freesound.org/people/strongbot/sounds/568995/) is imported into Audacity. It currently is saved as a `.wav` file and has two audio channels (Stereo). Edit the sound to your liking and make sure to delete one of the channels using the drop-down element at the top of the "track head". + +![Splitting Stereo track](/assets/develop/sounds/custom_sounds_1.png) + +![Deleting one of the channels](/assets/develop/sounds/custom_sounds_2.png) + +When exporting or rendering the audio file, make sure to choose the OGG file format. Some DAWs, like REAPER, might support multiple OGG audio layer formats. In this case OGG Vorbis should work just fine. + +![Exporting as OGG file](/assets/develop/sounds/custom_sounds_3.png) + +Also keep in mind that audio files can increase the file size of your mod drastically. If needed, compress the audio when editing and exporting the file to keep the file size of your finished product to a minimum. + +## Loading the Audio File {#loading-the-audio-file} + +Add the new `resources/assets//sounds` directory for the sounds in your mod, and put the exported audio file `metal_whistle.ogg` in there. + +Continue with creating the `resources/assets//sounds.json` file if it doesn't exist yet and add your sound to the sound entries. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json) + +The subtitle entry provides more context for the player. The subtitle name is used in the language files in the `resources/assets//lang` directory and will be displayed if the in-game subtitle setting is turned on and this custom sound is being played. + +## Registering the Custom Sound {#registering-the-custom-sound} + +To add the custom sound to the mod, register a SoundEvent in your [mod's initializer](./getting-started/project-structure#entrypoints). + +```java +Registry.register(Registries.SOUND_EVENT, Identifier.of(MOD_ID, "metal_whistle"), + SoundEvent.of(Identifier.of(MOD_ID, "metal_whistle"))); +``` + +## Cleaning up the Mess {#cleaning-up-the-mess} + +Depending on how many Registry entries there are, this can get messy quickly. To avoid that, we can make use of a new helper class. + +Add two new methods to the newly created helper class. One, which registers all the sounds and one which is used to initialize this class in the first place. After that you can comfortably add new custom `SoundEvent` static class variables as needed. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java) + +This way, the mod's initializer only needs to implement one line to register all custom SoundEvents. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java) + +## Using the Custom SoundEvent {#using-the-custom-soundevent} + +Use the helper class to access the custom SoundEvent. Check out the [Playing SoundEvents](./using-sounds) page to learn how to play sounds. diff --git a/versions/1.21/develop/sounds/dynamic-sounds.md b/versions/1.21/develop/sounds/dynamic-sounds.md new file mode 100644 index 000000000..025f9b2cf --- /dev/null +++ b/versions/1.21/develop/sounds/dynamic-sounds.md @@ -0,0 +1,376 @@ +--- +title: Dynamic Sounds +description: Create more dynamic and interactive sounds +authors: + - JR1811 + +search: false +--- + +# Create Dynamic and Interactive Sounds {#create-dynamic-and-interactive-sounds} + +::: info +This page builds on top of the [Playing Sounds](../sounds/using-sounds) and the [Creating Custom Sounds](../sounds/custom) pages! +::: + +## Problems with `SoundEvents` {#problems-with-soundevents} + +As we have learned in the [Using Sounds](../sounds/using-sounds) page, it is preferable to use `SoundEvent`s on a logical server side, even if it is a bit counterintuitive. After all, a client needs to handle the sound, which is transmitted to your headphones, right? + +This way of thinking is correct. Technically the client side needs to handle the audio. However, for simple `SoundEvent` playing, the server side prepared a big step in between which might not be obvious at first glance. Which clients should be able to hear that sound? + +Using the sound on the logical server side will solve the issue of broadcasting `SoundEvent`s. To put simple, every client (`ClientPlayerEntity`) in tracking range, gets sent a network packet to play this specific sound. The sound event is basically broadcasted from the logical server side, to every participating client, without you having to think about it at all. The sound is played once, with the specified volume and pitch values. + +But what if this is not enough? What if the sound needs to loop, change volume and pitch dynamically while playing and all that based on values which come from things like `Entities` or `BlockEntities`? + +The simple way of using the `SoundEvent` on the logical server side is not enough for this use case. + +## Preparing the Audio File {#preparing-the-audio-file} + +We are going to create a new **looping** audio for another `SoundEvent`. If you can find an audio file which is looping seamlessly already, you can just follow the steps from [Creating Custom Sounds](../sounds/custom). If the sound is not looping perfectly yet, we will have to prepare it for that. + +Again, most modern DAWs (Digital Audio Workstation Software) should be capable of this, but I like to use [Reaper](https://www.reaper.fm/) if the audio editing is a bit more involved. + +### Set Up {#set-up} + +Our [starting sound](https://freesound.org/people/el-bee/sounds/644881/) will be coming from an engine. + + + +Let's load the file into our DAW of choice. + +![Reaper loaded with the audio file](/assets/develop/sounds/dynamic-sounds/step_0.png) + +We can hear and see, that the engine gets started in the beginning and stopped at the end which is not great for looping sounds. Let's cut those out and adjust the time selection handles to match the new length. Also enable the `Toggle Repeat` mode to let the audio loop, while we adjust it. + +![Trimmed audio file](/assets/develop/sounds/dynamic-sounds/step_1.png) + +### Removing Disruptive Audio Elements {#removing-disruptive-audio-elements} + +If we listen closely, there is a beeping noise in the background, which could've come from the machine. I think, that this wouldn't sound great in-game, so lets try to remove it. + +It is a constant sound which keeps its frequency over the length of the audio. So a simple EQ filter should be enough to filter it out. + +Reaper comes with an EQ filter equipped already, called "ReaEQ". This might be located somewhere else and named differently in other DAWs but using EQ is standard in most DAWs nowadays. + +If you are sure that your DAW doesn't have an EQ filter available, check for free VST alternatives online which you may be able to install in your DAW of choice. + +In Reaper use the Effects Window to add the "ReaEQ" audio effect, or any other EQ. + +![Adding an EQ filter](/assets/develop/sounds/dynamic-sounds/step_2.png) + +If we play the audio now, while keeping the EQ filter window open, the EQ filter will show the incoming audio in its display. +We can see many bumps there. + +![Identifying the problem](/assets/develop/sounds/dynamic-sounds/step_3.png) + +If you are not a trained audio engineer, this part is mostly about experimenting and "trial and error". There is a pretty harsh bump between node 2 and 3. Let's move the nodes so, that we lower the frequency only for that part. + +![Lowered the bad frequency](/assets/develop/sounds/dynamic-sounds/step_4.png) + +Also, other effects can be achieved with a simple EQ filter. For example, cutting high and/or low frequencies can give the impression of radio transmitted sounds. + +You can also layer more audio files, change the pitch, add some reverb or use more elaborate sound effects like "bit-crusher". Sound design can be fun, especially if you find good sounding variations of your audio by accident. Experimenting is key and maybe your sound might end up even better than before. + +We will only continue with the EQ filter, which we used to cut out the problematic frequency. + +### Comparison {#comparison} + +Let's compare the original file with the cleaned up version. + +You can hear a distinct humming and beeping sound from maybe an electrical element of the engine, in the original sound. + + + +With an EQ filter we were able to remove it almost completely. It is definitely more pleasant to listen to. + + + +### Making It Loop {#making-it-loop} + +If we let the sound play to the end and let it start from the beginning again, we can clearly hear the transition happening. The goal is to get rid of this by applying a smooth transition. + +Start by cutting a piece from the end, which is as big as you want the transition to be, and place it on the beginning of a new audio track. +In Reaper, you can split the audio by simply moving the cursor to the position of the cut and pressing S. + +![Cut the end and move it to a new track](/assets/develop/sounds/dynamic-sounds/step_6.png) + +You may have to copy the EQ audio effect of the first audio track over to the second one too. + +Now let the end piece of the new track fade out and let the start of the first audio track fade in. + +![Looping with fading audio tracks](/assets/develop/sounds/dynamic-sounds/step_7.png) + +### Exporting {#exporting} + +Export the audio with the two audio tracks, but with only one audio channel (Mono) and create a new `SoundEvent` for that `.ogg` file in your mod. +If you are not sure how to do that, take a look at the [Creating Custom Sounds](../sounds/custom) page. + +This is now the finished looping engine audio for the `SoundEvent` called `ENGINE_LOOP`. + + + +## Using a `SoundInstance` {#using-a-soundinstance} + +To play sounds on the client side, a `SoundInstance` is needed. They still make use of `SoundEvent` though. + +If you only want to play something like a click on a UI element, there is already the existing `PositionedSoundInstance` class. + +Keep in mind that this will only be played on the specific client, which executed this part of the code. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java) + +::: warning +Please note that in the `AbstractSoundInstance` class, which `SoundInstance`s inherit from, has the `@Environment(EnvType.CLIENT)` annotation. + +This means that this class (and all its subclasses) will only be available to the client side. + +If you try using that in a logical server side context, you may not notice the issue in Single player at first, +but a server in a Multiplayer environment will crash, since it won't be able to find that part of the code at all. + +If you struggle with those issues, it is recommended to create your mod from the [Online template generator](https://fabricmc.net/develop/template/) +with the `Split client and common sources` option turned on. +::: + +--- + +A `SoundInstance` can be more powerful than just playing sounds once. + +Check out the `AbstractSoundInstance` class and what kind of values it can keep track of. +Besides the usual volume and pitch variables, it also holds XYZ coordinates and if it should repeat itself after finishing the `SoundEvent`. + +Then taking a look at its subclass, `MovingSoundInstance` we get the `TickableSoundInstance` interface introduced too, which adds ticking functionality to the `SoundInstance`. + +So to make use of those utilities, simply create a new class for your custom `SoundInstance` and extend from `MovingSoundInstance`. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/CustomSoundInstance.java) + +Using your custom `Entity` or `BlockEntity` instead of that basic `LivingEntity` instance can give you even more control e.g. in the `tick()` method based +on accessor methods, but you don't necessarily need a reference to a sound source like that. Instead, you could also access a `BlockPos` from somewhere else +or even set it by hand once in the constructor only. + +Just keep in mind that all the referenced objects in the `SoundInstance` are the versions from the client side. +In specific situations, a logical server side entity's properties can differ from its client side counterpart. +If you notice that your values don't line up, make sure that your values are synchronized +either with entity's `TrackedData`, `BlockEntity` S2C packets or complete custom S2C network packets. + +After you have finished creating your custom `SoundInstance` It's ready to be used anywhere as long as it's been executed on the client side using the sound manager. +In the same way, you can also stop the custom `SoundInstance` manually, if necessary. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java) + +The sound loop will be played now only for the client, which ran that SoundInstance. In this case, the sound will follow the `ClientPlayerEntity` itself. + +This concludes the explanation of creating and using a simple custom `SoundInstance`. + +## Advanced SoundInstances {#advanced-soundinstances} + +::: warning +The following content covers an advanced topic. + +At this point you should have a solid grasp on Java, object-oriented programming, generics and callback systems. + +Having knowledge on `Entities`, `BlockEntities` and custom networking will also help a lot in understanding the use case and the applications of advanced sounds. +::: + +To show an example of how more elaborate `SoundInstance` systems can be created, we will add extra functionality, abstractions +and utilities to make working with such sounds in a bigger scope, easier, more dynamic and flexible. + +### Theory {#theory} + +Let's think about what our goal with the `SoundInstance` is. + +- The sound should loop as long as the linked custom `EngineBlockEntity` is running +- The `SoundInstance` should move around, following its custom `EngineBlockEntity`'s position _(The `BlockEntity` won't move, so this might be more useful on `Entities`)_ +- We need smooth transitions. Turning it on or off should almost never be instant. +- Change volume and pitch based on external factors (e.g. from the source of the sound) + +To summarize, we need to keep track of an instance of a custom `BlockEntity`, +adjust volume and pitch values while the `SoundInstance` is running based on values from that custom `BlockEntity` and implement "Transition States". + +If you plan on making several different `SoundInstances`, which behave in different ways, I would recommend creating a new abstract `AbstractDynamicSoundInstance` class, +which implements the default behavior and let the actual custom `SoundInstance` classes extend from it. + +If you just plan on using a single one, you can skip the abstract super class, and instead implement that functionality in your custom `SoundInstance` class directly. + +In addition it will be a good idea to have a centralized place, where the `SoundInstance`'s are being tracked, played and stopped. This means that it needs to handle incoming +signals, e.g. from custom S2C Network Packets, list all currently running instances and handle special cases, for example which sounds are allowed to play at the same time and which sounds +could potentially disable other sounds upon activation. +For that a new `DynamicSoundManager` class can be created, to easily interact with this sound system. + +Overall our sound system might look like this, when we are done. + +![Structure of the custom Sound System](/assets/develop/sounds/dynamic-sounds/custom-dynamic-sound-handling.jpg) + +::: info +All of those enums, interfaces and classes will be newly created. Adjust the system and utilities to your specific use case as you see fit. +This is only an example of how you can approach such topics. +::: + +### `DynamicSoundSource` Interface {#dynamicsoundsource-interface} + +If you choose to create a new, more modular, custom `AbstractDynamicSoundInstance` class as a super class, +you may want to reference not only a single type of `Entity` but different ones, or even a `BlockEntity` too. + +In that case, making use of abstraction is the key. +Instead of referencing e.g. a custom `BlockEntity` directly, only keeping track of an Interface, which provides the data, solves that problem. + +Going forward we will make use of a custom Interface called `DynamicSoundSource`. It is implemented in all classes which want to make use of that dynamic sound functionality, +like your custom `BlockEntity`, Entities or even, using Mixins, on already existing classes, like `ZombieEntity`. It basically represents only the necessary data of the sound source. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/DynamicSoundSource.java) + +After creating this interface, make sure to implement it in the necessary classes too. + +::: info +This is a utility, which may be used on both the client and the logical server side. + +So this Interface should be stored in the common packages instead of the client only packages, if you make use of the +"split sources" option +::: + +### `TransitionState` Enum {#transitionstate-enum} + +As mentioned earlier, you could stop running `SoundInstance`s with the client's `SoundManager`, but this will cause the SoundInstance to go silent instantly. +Our goal is, when a stopping signal comes in, to not stop the sound but to execute an ending phase of its "Transition State". Only after the ending phase is finished +the custom `SoundInstance` should be stopped. + +A `TransitionState` is a newly created enum, which contains three values. They will be used to keep track on what phase the sound should be in. + +- `STARTING` Phase: sound starts silent, but slowly increases in volume +- `RUNNING` Phase: sound is running normally +- `ENDING` Phase: sound starts at the original volume and slowly decreases until it is silent + +Technically a simple enum with the phases can be enough. + +```java +public enum TransitionState { + STARTING, RUNNING, ENDING +} +``` + +But when those values are sent over the network you might want to define an `Identifier` for them or even add other custom values. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/TransitionState.java) + +::: info +Again, if you make use of "split sources" you need to think about where you will be using this enum. +Technically, only the custom `SoundInstance`s which are only available on the client side, will use those enum values. + +But if this enum is used anywhere else, e.g. in custom network packets, you may have to put this enum also into the common packages +instead of the client only packages. +::: + +### `SoundInstanceCallback` Interface {#soundinstancecallback-interface} + +This interface is used as a callback. For now, we only need a `onFinished` method, but you can add your own methods if you need to send +other signals from the `SoundInstance` object too. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/SoundInstanceCallback.java) + +Implement this interface on any class, which should be able to handle the incoming signals, for example the `AbstractDynamicSoundInstance`, which we will create soon +and create the functionality in the custom `SoundInstance` itself. + +### `AbstractDynamicSoundInstance` Class {#abstractdynamicsoundinstance-class} + +Let's finally get started on the core of the dynamic `SoundInstance`s system. The `AbstractDynamicSoundInstance` is a newly created `abstract` class. +It implements the default defining features and utilities of our custom `SoundInstances`, which will inherit from it. + +We can take the `CustomSoundInstance` from [earlier](#using-a-soundinstance) and improve on that. +Instead of the `LivingEntity` we will now reference our `DynamicSoundSource`. +In addition, we will define more properties. + +- `TransitionState` to keep track of the current phase +- tick durations of how long the start and the end phases should last +- minimum and maximum values for volume and pitch +- boolean value to notify if this instance has been finished and can get cleaned up +- tick holders to keep track of the current sound's progress. +- a callback which sends a signal back to the `DynamicSoundManager` for the final clean up, when the `SoundInstance` is actually finished + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Then set up the default starting values for the custom `SoundInstance` in the constructor of the abstract class. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +After the constructor is finished, you need to allow the `SoundInstance` to be able to play. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Now comes the important part for this dynamic `SoundInstance`. Based on the current tick of the instance, it can apply different values and behaviors. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +As you can see, we haven't applied the volume and pitch modulation here yet. We only apply the shared behavior. +So in this `AbstractDynamicSoundInstance` class we only provide the basic structure and the tools for the +subclasses, which can decide themselves, which kind of sound modulation they actually want to apply. + +So let's take a look at some examples of such sound modulation methods. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +As you can see, normalized values in combination with linear interpolation (lerp) help out to shape the values to the preferred audio limits. +Keep in mind that if you add multiple methods, which change the same value, you will need to observe and adjust how they work together with each other. + +Now we just need to add the remaining utility methods, and we are done with the `AbstractDynamicSoundInstance` class. + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +### Example `SoundInstance` Implementation {#example-soundinstance-implementation} + +If we take a look at the actual custom `SoundInstance` class, which extends from the newly created `AbstractDynamicSoundInstance`, we only need to think about +what conditions would bring the sound to a stop and what sound modulation we want to apply. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/EngineSoundInstance.java) + +### `DynamicSoundManager` Class {#dynamicsoundmanager-class} + +We discussed [earlier](#using-a-soundinstance) how to play and stop a `SoundInstance`. To clean up, centralize and manage those interactions, you can create your own +`SoundInstance` handler, which builds on top of that. + +This new `DynamicSoundManager` class will manage the custom `SoundInstances` so it will also only be available to the client side. On top of that, a client should only ever allow one instance of this class to exist. Multiple sound managers for a single client wouldn't make much sense and complicate the interactions even more. +So, let's use a ["Singleton Design Pattern"](https://refactoring.guru/design-patterns/singleton/java/example). + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java) + +After getting the basic structure right, you can add the methods, which are needed to interact with the sound system. + +- playing sounds +- stopping sounds +- checking if a sound is currently playing + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java) + +Instead of only having a list of all currently playing `SoundInstances` you could also keep track of which sound sources are playing which sounds. +For example, an engine having two engine sounds at the same time would make no sense, while multiple engines playing their respective engine sounds +is a valid edge case. For the sake of simplicity we just created a `List` but in many cases a `HashMap` of `DynamicSoundSource` and a `AbstractDynamicSoundInstance` might be a better choice. + +### Using the Advanced Sound System {#using-the-advanced-sound-system} + +To use this sound system, simply make use of either the `DynamicSoundManager` methods or the `SoundInstance` methods. Using `onStartedTrackingBy` and `onStoppedTrackingBy` +from entities or just custom S2C networking, you can now start and stop your custom dynamic `SoundInstance`s. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/network/ReceiveS2C.java) + +The final product can adjust its volume based on the sound phase to smoothen out the transitions and change the pitch based on a stress value, which is +coming from the sound source. + + + +You could add another value to your sound source, which keeps track of an "overheat" value and, in addition, let a hissing `SoundInstance` slowly fade in if the value is above 0 +or add a new interface to your custom dynamic `SoundInstance`s which assigns a priority value to the sound types, which helps out choosing which sound to play, if they +collide with each other. + +With the current system, you can easily handle multiple `SoundInstance`s at once and design the audio to your needs. diff --git a/versions/1.21/develop/sounds/using-sounds.md b/versions/1.21/develop/sounds/using-sounds.md new file mode 100644 index 000000000..259c001be --- /dev/null +++ b/versions/1.21/develop/sounds/using-sounds.md @@ -0,0 +1,36 @@ +--- +title: Playing Sounds +description: Learn how to play sound events. +authors: + - JR1811 + +search: false +--- + +# Playing Sounds {#playing-sounds} + +Minecraft has a big selection of sounds which you can choose from. Check out the `SoundEvents` class to view all the vanilla sound event instances that Mojang has provided. + +## Using Sounds in Your Mod {#using-sounds} + +Make sure to execute the `playSound()` method on the logical server side when using sounds! + +In this example, the `useOnEntity()` and `useOnBlock()` methods for a custom interactive item are used to play a "placing copper block" and a pillager sound. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java) + +The `playSound()` method is used with the `LivingEntity` object. Only the SoundEvent, the volume and the pitch need to be specified. You can also use the `playSound()` method from the world instance to have a higher level of control. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java) + +### SoundEvent and SoundCategory {#soundevent-and-soundcategory} + +The SoundEvent defines which sound will be played. You can also [register your own SoundEvents](./custom) to include your own sound. + +Minecraft has several audio sliders in the in-game settings. The `SoundCategory` enum is used to determine which slider will adjust your sound's volume. + +### Volume and Pitch {#volume-and-pitch} + +The volume parameter can be a bit misleading. In the range of `0.0f - 1.0f` the actual volume of the sound can be changed. If the number gets bigger than that, the volume of `1.0f` will be used and only the distance, in which your sound can be heard, gets adjusted. The block distance can be roughly calculated by `volume * 16`. + +The pitch parameter increases or decreases the pitch value and also changes the duration of the sound. In the range of `(0.5f - 1.0f)` the pitch and the speed gets decreased, while bigger numbers will increase the pitch and the speed. Numbers below `0.5f` will stay at the pitch value of `0.5f`. diff --git a/versions/1.21/develop/text-and-translations.md b/versions/1.21/develop/text-and-translations.md new file mode 100644 index 000000000..80dd87fa5 --- /dev/null +++ b/versions/1.21/develop/text-and-translations.md @@ -0,0 +1,146 @@ +--- +title: Text and Translations +description: Comprehensive documentation for Minecraft's handling of formatted text and translations. +authors: + - IMB11 + - LordEnder-Kitty + +search: false +--- + +# Text and Translations {#text-and-translations} + +Whenever Minecraft displays text in-game, it's probably defined using a `Text` object. +This custom type is used instead of a `String` to allow for more advanced formatting, +including colors, boldness, obfuscation, and click events. They also allow easy access +to the translation system, making it simple to translate any UI element into +different languages. + +If you've worked with datapacks or functions before, you may see parallels with the +json text format used for displayNames, books, and signs among other things. As you +can probably guess, this is just a json representation of a `Text` object, and can be +converted to and from using `Text.Serializer`. + +When making a mod, it is generally preferred to construct your `Text` objects directly +in code, making use of translations whenever possible. + +## Text Literals {#text-literals} + +The simplest way to create a `Text` object is to make a literal. This is just a string +that will be displayed as-is, by default without any formatting. + +These are created using the `Text.of` or `Text.literal` methods, which both act slightly +differently. `Text.of` accepts nulls as input, and will return a `Text` instance. In +contrast, `Text.literal` should not be given a null input, but returns a `MutableText`, +this being a subclass of `Text` that can be easily styled and concatenated. More about +this later. + +```java +Text literal = Text.of("Hello, world!"); +MutableText mutable = Text.literal("Hello, world!"); +// Keep in mind that a MutableText can be used as a Text, making this valid: +Text mutableAsText = mutable; +``` + +## Translatable Text {#translatable-text} + +When you want to provide multiple translations for the same string of text, you can use the `Text.translatable` method to reference a translation key in any language file. If the key doesn't exist, the translation key is converted to a literal. + +```java +Text translatable = Text.translatable("my_mod.text.hello"); + +// Similarly to literals, translatable text can be easily made mutable. +MutableText mutable = Text.translatable("my_mod.text.bye"); +``` + +The language file, `en_us.json`, looks like the following: + +```json +{ + "my_mod.text.hello": "Hello!", + "my_mod.text.bye": "Goodbye :(" +} +``` + +If you wish to be able to use variables in the translation, similar to how death messages allow you to use the involved players and items in the translation, you may add said variables as parameters. You may add however many parameters you like. + +```java +Text translatable = Text.translatable("my_mod.text.hello", player.getDisplayName()); +``` + +You may reference these variables in the translation like so: + +```json +{ + "my_mod.text.hello": "%1$s said hello!" +} +``` + +In the game, %1\$s will be replaced with the name of the player you referenced in the code. Using `player.getDisplayName()` will make it so that additional information about the entity will appear in a tooltip when hovering over the name in the chat message as opposed to using `player.getName()`, which will still get the name; however, it will not show the extra details. Similar can be done with itemStacks, using `stack.toHoverableText()`. + +As for what %1\$s even means, all you really need to know is that the number corresponds to which variable you are trying to use. Let's say you have three variables that you are using. + +```java +Text translatable = Text.translatable("my_mod.text.whack.item", victim.getDisplayName(), attacker.getDisplayName(), itemStack.toHoverableText()); +``` + +If you want to reference what, in our case, is the attacker, you would use %2\$s because it's the second variable that we passed in. Likewise, %3\$s refers to the itemStack. A translation with this many additional parameters might look like this: + +```json +{ + "my_mod.text.whack.item": "%1$s was whacked by %2$s using %3$s" +} +``` + +## Serializing Text {#serializing-text} + + + +As mentioned before, you can serialize text to JSON using the text codec. For more information on codecs, see the [Codec](./codecs) page. + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +This produces JSON that can be used datapacks, commands and other places that accept the JSON format of text instead of literal or translatable text. + +## Deserializing Text {#deserializing-text} + +Furthermore, to deserialize a JSON text object into an actual `Text` class, again, use the codec. + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +## Formatting Text {#formatting-text} + +You may be familiar with Minecraft's formatting standards: + +You can apply these formattings using the `Formatting` enum on the `MutableText` class: + +```java +MutableText result = Text.literal("Hello World!") + .formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE); +``` + + + + + + + + + + + + + + + + + + + + + + + + + +
ColorNameChat CodeMOTD CodeHex Code
Black (black)§0\u00A70#000000
Dark Blue (dark_blue)§1\u00A71#0000AA
Dark Green (dark_green)§2\u00A72#00AA00
Dark Aqua (dark_aqua)§3\u00A73#00AAAA
Dark Red (dark_red)§4\u00A74#AA0000
Dark Purple (dark_purple)§5\u00A75#AA00AA
Gold (gold)§6\u00A76#FFAA00
Gray (gray)§7\u00A77#AAAAAA
Dark Gray (dark_gray)§8\u00A78#555555
Blue (blue)§9\u00A79#5555FF
Green (green)§a\u00A7a#55FF55
Aqua (aqua)§b\u00A7b#55FFFF
Red (red)§c\u00A7c#FF5555
Light Purple (light_purple)§d\u00A7d#FF55FF
Yellow (yellow)§e\u00A7e#FFFF55
White (white)§f\u00A7f#FFFFFF
Reset§r
Bold§l
Strikethrough§m
Underline§n
Italic§o
Obfuscated§k
diff --git a/versions/1.21/index.md b/versions/1.21/index.md new file mode 100644 index 000000000..968f0d596 --- /dev/null +++ b/versions/1.21/index.md @@ -0,0 +1,25 @@ +--- +title: Fabric Documentation +description: The official curated documentation for Fabric, a modding toolchain for Minecraft. +layout: home + +hero: + name: Fabric Documentation + tagline: The official curated documentation for Fabric, a modding toolchain for Minecraft. + +features: + - title: Player Guides + icon: 📚 + details: Are you a player looking to use mods powered by Fabric? Our player guides have you covered. These guides will help you in downloading, installing, and troubleshooting Fabric mods. + link: /players/ + linkText: Read More + - title: Developer Guides + icon: 🛠️ + details: Our community-written developer guides cover everything from setting up your development environment to advanced topics like rendering and networking. + link: /develop/ + linkText: Get Started + +search: false +--- + +If you want to contribute to the Fabric Documentation, you can find the source code on [GitHub](https://github.com/FabricMC/fabric-docs), and the relevant [contribution guidelines](./contributing). diff --git a/versions/1.21/players/faq.md b/versions/1.21/players/faq.md new file mode 100644 index 000000000..04bb806d6 --- /dev/null +++ b/versions/1.21/players/faq.md @@ -0,0 +1,31 @@ +--- +title: Frequently Asked Questions for Players +description: Frequently asked questions for players and server administrators relating to Fabric. + +search: false +--- + +# Frequently Asked Questions {#faq} + +There are a lot of questions that are asked frequently, so we've compiled a list of them here. + +## What Minecraft Versions Does Fabric Support? {#what-minecraft-versions-does-fabric-support} + +Officially, Fabric supports all versions of Minecraft starting from snapshots `18w43b` and above, and releases `1.14` and above. + +## Where Can I Download Published Fabric Mods? {#where-can-i-download-published-fabric-mods} + +::: info +You should always check if mods are from a trustworthy source. Check out the [Finding Trustworthy Mods](./finding-mods) guide for more information. +::: + +The majority of authors publish their mods to [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) and [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods&gameVersionTypeId=4), however some may choose to upload them on their personal websites, or on other platforms, such as a GitHub repository. + +## Where Can I Find Premade Fabric Modpacks? {#where-can-i-find-premade-fabric-modpacks} + +You can find premade Fabric modpacks on a variety of platforms, such as: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/players/finding-mods.md b/versions/1.21/players/finding-mods.md new file mode 100644 index 000000000..b2e293c75 --- /dev/null +++ b/versions/1.21/players/finding-mods.md @@ -0,0 +1,36 @@ +--- +title: Finding Trustworthy Mods +description: A guide on how to find Fabric mods using trustworthy sources. +authors: + - IMB11 + +search: false +--- + +# Finding Trustworthy Mods {#finding-mods} + +Firstly, trust is subjective, and you should always use your own judgement when downloading mods. However, there are some things you can do to help you find trustworthy mods. + +## 1. Use a Source That Is Known to Be Trustworthy {#trustworthy-source} + +The majority of authors publish their mods to [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) and [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods&gameVersionTypeId=4). + +These websites check that the mods are what they say they are, and that they do not contain malicious code. You can also report malicious mods on those websites, and they will take action relatively quickly. + +## 2. Check With Others! {#with-others} + +If you are downloading a mod from a source that is not known to be trustworthy, you should check with others to see if they have downloaded the mod before from the location you're downloading from, and if they have had any issues with it. + +If in doubt, you are welcome to ask in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` channel. + +## 3. Avoid Common Malware Sites! {#avoid-malware} + +::: info +Malware sites may not be obvious to everyone. If you are unsure, you should ask for opinions from others or avoid the site altogether and rely only on trusted sources, such as Modrinth and CurseForge. +::: + +There are a lot of websites that claim to have mods for Minecraft, but are actually just malware sites. You should avoid these sites at all costs. + +You can use antivirus software and websites like [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) or [VirusTotal](https://www.virustotal.com/) to check the downloaded mods. However, do not rely entirely on those methods, because they can be sometimes incorrect. + +Again, if in doubt, you are welcome to ask for opinions in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` channel. diff --git a/versions/1.21/players/index.md b/versions/1.21/players/index.md new file mode 100644 index 000000000..ae885a580 --- /dev/null +++ b/versions/1.21/players/index.md @@ -0,0 +1,14 @@ +--- +title: Player Guides +description: A collection of guides for players and server administrators on installing and using Fabric. + +search: false +--- + +# Player Guides {#player-guides} + +This section of the Fabric Documentation is dedicated to players and server administrators who want to learn how to install, use, and troubleshoot Fabric. + +You should refer to the sidebar for a list of all the guides available. + +If you encounter any issues, please report them [on GitHub](https://github.com/FabricMC/fabric-docs) or ask for help on the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` or `#server-admin-support` channels. diff --git a/versions/1.21/players/installing-fabric.md b/versions/1.21/players/installing-fabric.md new file mode 100644 index 000000000..932c1ba12 --- /dev/null +++ b/versions/1.21/players/installing-fabric.md @@ -0,0 +1,61 @@ +--- +title: Installing Fabric +description: A step by step guide on how to install Fabric. +authors: + - IMB11 + - Benonardo + - modmuss50 + +search: false +--- + +# Installing Fabric {#installing-fabric} + + + +This guide only applies for the official Minecraft Launcher. For third party launchers, you should consult their documentation. + +## 1. Download the Fabric Installer {#1-download-the-fabric-installer} + +You can download the Fabric Installer from the [Fabric Website](https://fabricmc.net/use/). + +If you use Windows, download the `.exe` version (`Download For Windows`), because it doesn't require Java to be installed on your system. It instead uses Java that came with the official launcher. + +For macOS and Linux, you should download the `.jar` version. Sometimes, you need to install Java before this step. + +## 2. Run the Fabric Installer {#2-run-the-fabric-installer} + +::: warning +Close Minecraft and the Minecraft Launcher first before running the installer. +::: + +::: details Information for macOS users + +On macOS, you may need to right click the `.jar` file in your downloads directory and click `Open` to run it. + +![MacOS context menu on Fabric Installer](/assets/players/installing-fabric/macos-downloads.png) + +When asked "Are you sure you want to open it?", click `Open` again. +::: + +Once you've opened the installer, you should see a screen like this: + +![Fabric Installer with "Install" highlighted](/assets/players/installing-fabric/installer-screen.png) + + + +To install Fabric, simply choose your game version from the dropdown, and click `Install`. + +::: warning IMPORTANT +Make sure that 'Create Profile' is checked. +::: + +## 3. You're Done! {#3-you-re-done} + +Once the installer has finished, you can open the Minecraft Launcher and select the Fabric profile from the dropdown in the bottom left corner and press Play! + +![Minecraft Launcher with Fabric profile selected](/assets/players/installing-fabric/launcher-screen.png) + +Now that you've installed Fabric, you can add mods to your game! Check out the [Finding Trustworthy Mods](./finding-mods) guide for more information. + +If you encounter any issues while following this guide, you can ask for help in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` channel. diff --git a/versions/1.21/players/installing-java/linux.md b/versions/1.21/players/installing-java/linux.md new file mode 100644 index 000000000..7e74c917c --- /dev/null +++ b/versions/1.21/players/installing-java/linux.md @@ -0,0 +1,93 @@ +--- +title: Installing Java on Linux +description: A step by step guide on how to install Java on Linux. +authors: + - IMB11 + +search: false +--- + +# Installing Java on Linux {#installing-java-on-linux} + +This guide will walk you through installing Java 21 on Linux. + +## 1. Check if Java Is Already Installed {#1-check-if-java-is-already-installed} + +Open a terminal, type `java -version`, and press Enter. + +![Terminal with "java -version" typed in](/assets/players/installing-java/linux-java-version.png) + +::: warning +To use Minecraft 1.21, you'll need at least Java 21 installed. If this command displays any version lower than 21, you'll need to update your existing Java installation. +::: + +## 2. Downloading and Installing Java 21 {#2-downloading-and-installing-java} + +We recommend using OpenJDK 21, which is available for most Linux distributions. + +### Arch Linux {#arch-linux} + +::: info +For more information on installing Java on Arch Linux, see the [Arch Linux Wiki](https://wiki.archlinux.org/title/Java). +::: + +You can install the latest JRE from the official repositories: + +```sh +sudo pacman -S jre-openjdk +``` + +If you're running a server without the need for a graphical UI, you can install the headless version instead: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +If you plan to develop mods, you'll need the JDK instead: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu {#debian-ubuntu} + +You can install Java 21 using `apt` with the following commands: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora {#fedora} + +You can install Java 21 using `dnf` with the following commands: + +```sh +sudo dnf install java-21-openjdk +``` + +If you don't need a graphical UI, you can install the headless version instead: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +If you plan to develop mods, you'll need the JDK instead: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Other Linux Distributions {#other-linux-distributions} + +If your distribution isn't listed above, you can download the latest JRE from [Adoptium](https://adoptium.net/temurin/) + +You should refer to an alternative guide for your distribution if you plan to develop mods. + +## 3. Verify That Java 21 Is Installed {#3-verify-that-java-is-installed} + +Once the installation is complete, you can verify that Java 21 is installed by opening a terminal and typing `java -version`. + +If the command runs successfully, you will see something like shown before, where the Java version is displayed: + +![Terminal with "java -version" typed in](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/players/installing-java/windows.md b/versions/1.21/players/installing-java/windows.md new file mode 100644 index 000000000..919dac6bf --- /dev/null +++ b/versions/1.21/players/installing-java/windows.md @@ -0,0 +1,67 @@ +--- +title: Installing Java on Windows +description: A step by step guide on how to install Java on Windows. +authors: + - IMB11 + +search: false +--- + +# Installing Java on Windows {#installing-java-on-windows} + +This guide will walk you through installing Java 21 on Windows. + +The Minecraft Launcher comes with its own Java installation, so this section is only relevant if you want to use the Fabric `.jar` based installer, or if you want to use the Minecraft Server `.jar`. + +## 1. Check if Java Is Already Installed {#1-check-if-java-is-already-installed} + +To check if Java is already installed, you must first open the command prompt. + +You can do this by pressing Win R and typing `cmd.exe` into the box that appears. + +![Windows Run Dialog with "cmd.exe" in the run bar](/assets/players/installing-java/windows-run-dialog.png) + +Once you have opened the command prompt, type `java -version` and press Enter. + +If the command runs successfully, you will see something like this. If the command failed, proceed to the next step. + +![Command prompt with "java -version" typed in](/assets/players/installing-java/windows-java-version.png) + +::: warning +To use Minecraft 1.21, you'll need at least Java 21 installed. If this command displays any version lower than 21, you'll need to update your existing Java installation. +::: + +## 2. Download the Java 21 Installer {#2-download-the-java-installer} + +To install Java 21, you'll need to download the installer from [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows&package=jdk&version=21). + +You'll want to download the `Windows Installer (.msi)` version: + +![Adoptium download page with Windows Installer (.msi) highlighted](/assets/players/installing-java/windows-download-java.png) + +You should choose `x86` if you have a 32-bit operating system, or `x64` if you have a 64-bit operating system. + +The majority of modern computers will have a 64-bit operating system. If you are unsure, try using the 64-bit download. + +## 3. Run the Installer! {#3-run-the-installer} + +Follow the steps in the installer to install Java 21. When you reach this page, you should set the following features to "Entire feature will be installed on local hard drive": + +- `Set JAVA_HOME environment variable` - This will be added to your PATH. +- `JavaSoft (Oracle) registry keys` + +![Java 21 installer with "Set JAVA_HOME variable" and "JavaSoft (Oracle) registry keys" highlighted](/assets/players/installing-java/windows-wizard-screenshot.png) + +Once you've done that, you can click `Next` and continue with the installation. + +## 4. Verify That Java 21 Is Installed {#4-verify-that-java-is-installed} + +Once the installation is complete, you can verify that Java 21 is installed by opening the command prompt again and typing `java -version`. + +If the command runs successfully, you will see something like shown before, where the Java version is displayed: + +![Command prompt with "java -version" typed in](/assets/players/installing-java/windows-java-version.png) + +--- + +If you encounter any issues, feel free to ask for help in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` channel. diff --git a/versions/1.21/players/installing-mods.md b/versions/1.21/players/installing-mods.md new file mode 100644 index 000000000..f56e0b099 --- /dev/null +++ b/versions/1.21/players/installing-mods.md @@ -0,0 +1,69 @@ +--- +title: Installing Mods +description: A step by step guide on how to install mods for Fabric. +authors: + - IMB11 + +search: false +--- + +# Installing Mods {#installing-mods} + +This guide will walk you through installing mods for Fabric using the Minecraft Launcher. + +For third party launchers, you should consult their documentation. + +## 1. Download the Mod {#1-download-the-mod} + +::: warning +You should only download mods from sources you trust. For more information on finding mods, see the [Finding Trustworthy Mods](./finding-mods) guide. +::: + +The majority of mods require Fabric API as well, which can be downloaded from [Modrinth](https://modrinth.com/mod/fabric-api) or [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +When downloading mods, ensure that: + +- They work on the version of Minecraft you want to play on. A mod that works on version 1.20, for example, might not work on version 1.20.2. +- They are for Fabric and not another mod loader. +- Furthermore, they are for the correct edition of Minecraft (Java Edition). + +## 2. Move the Mod to the `mods` Folder {#2-move-the-mod-to-the-mods-folder} + +The mods folder can be found in the following locations for each operating system. + +You can usually paste these paths into the address bar of your file explorer to quickly navigate to the folder. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Once you've found the `mods` folder, you can move the mod `.jar` files into it. + +![Installed mods in the mods folder](/assets/players/installing-mods.png) + +## 3. You're Done! {#3-you-re-done} + +Once you've moved the mods into the `mods` folder, you can open the Minecraft Launcher and select the Fabric profile from the dropdown in the bottom left corner and press play! + +![Minecraft Launcher with Fabric profile selected](/assets/players/installing-fabric/launcher-screen.png) + +## Troubleshooting {#troubleshooting} + +If you encounter any issues whilst following this guide, you can ask for help in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` channel. + +You can also attempt to troubleshoot the issue yourself by reading the troubleshooting pages: + +- [Crash Reports](./troubleshooting/crash-reports) +- [Uploading Logs](./troubleshooting/uploading-logs) diff --git a/versions/1.21/players/troubleshooting/crash-reports.md b/versions/1.21/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..f462cc9f8 --- /dev/null +++ b/versions/1.21/players/troubleshooting/crash-reports.md @@ -0,0 +1,109 @@ +--- +title: Crash Reports +description: Learn what to do with crash reports, and how to read them. +authors: + - IMB11 + +search: false +--- + +# Crash Reports {#crash-reports} + +::: tip +If you're having any difficulty with finding the cause of the crash, you can ask for help in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` or `#server-admin-support` channel. +::: + +Crash reports are a very important part of troubleshooting issues with your game or server. They contain a lot of information about the crash, and can help you find the cause of the crash. + +## Finding Crash Reports {#finding-crash-reports} + +Crash reports are stored in the `crash-reports` folder in your game directory. If you are using a server, they are stored in the `crash-reports` folder in the server directory. + +For third party launchers, you should refer to their documentation on where to find crash reports. + +Crash reports can be found in the following locations: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Reading Crash Reports {#reading-crash-reports} + +Crash reports are very long, and can be very confusing to read. However, they contain a lot of information about the crash, and can help you find the cause of the crash. + +For this guide, we will be using [this crash report](/assets/players/crash-report-example.txt). + +::: details Show Crash Report + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Crash Report Sections {#crash-report-sections} + +Crash reports consist of several sections, each separated using a header: + +- `---- Minecraft Crash Report ----`, the summary of the report. This section will contain the main error that caused the crash, the time it occurred, and the relevant stack trace. This is the most important section of the crash report as the stack trace can usually contain references to the mod that caused the crash. +- `-- Last Reload --`, this section isn't really useful unless the crash occurred during a resource reload (F3 T). This section will contain the time of the last reload, and the relevant stack trace of any errors that occurred during the reload process. These errors are usually caused by resource packs, and can be ignored unless they are causing issues with the game. +- `-- System Details --`, this section contains information about your system, such as the operating system, Java version, and the amount of memory allocated to the game. This section is useful for determining if you are using the correct version of Java, and if you have allocated enough memory to the game. + - In this section, Fabric will have included a custom line that says `Fabric Mods:`, followed by a list of all the mods you have installed. This section is useful for determining if any conflicts could have occurred between mods. + +### Breaking Down the Crash Report {#breaking-down-the-crash-report} + +Now that we know what each section of the crash report is, we can start to break down the crash report and find the cause of the crash. + +Using the example linked above, we can analyze the crash report and find the cause of the crash, including the mods that caused the crash. + +The stack trace in the `---- Minecraft Crash Report ----` section is the most important in this case, as it contains the main error that caused the crash. + +::: details Show Error + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +With the amount of mods mentioned in the stack trace, it can be difficult to point fingers, but the first thing to do is to look for the mod that caused the crash. + +In this case, the mod that caused the crash is `snownee`, as it is the first mod mentioned in the stack trace. + +However, with the amount of mods mentioned, it could mean there are some compatibility issues between the mods, and the mod that caused the crash may not be the mod that is at fault. In this case, it is best to report the crash to the mod author, and let them investigate the crash. + +## Mixin Crashes {#mixin-crashes} + +::: info +Mixins are a way for mods to modify the game without having to modify the game's source code. They are used by many mods, and are a very powerful tool for mod developers. +::: + +When a mixin crashes, it will usually mention the mixin in the stack trace, and the class that the mixin is modifying. + +Method mixins will contain `modid$handlerName` in the stack trace, where `modid` is the mod's ID, and `handlerName` is the name of the mixin handler. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +You can use this information to find the mod that caused the crash, and report the crash to the mod author. + +## What to Do with Crash Reports {#what-to-do-with-crash-reports} + +The best thing to do with crash reports is to upload them to a paste site, and then share the link with the mod author, either on their issue trackers or through some form of communication (Discord etc.). + +This will allow the mod author to investigate the crash, potentially reproduce it, and solve the problem that caused it. + +Common paste sites that are used frequently for crash reports are: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/players/troubleshooting/uploading-logs.md b/versions/1.21/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..4f4f7c06a --- /dev/null +++ b/versions/1.21/players/troubleshooting/uploading-logs.md @@ -0,0 +1,56 @@ +--- +title: Uploading Logs +description: How to upload logs for troubleshooting. +authors: + - IMB11 + +search: false +--- + +# Uploading Logs {#uploading-logs} + +When troubleshooting issues, it is often necessary to provide logs to help identify the cause of the issue. + +## Why Should I Upload Logs? {#why-should-i-upload-logs} + +Uploading logs allows others to help you troubleshoot your issues much quicker than simply pasting the logs into a chat or forum post. It also allows you to share your logs with others without having to copy and paste them. + +Some paste sites also provide syntax highlighting for logs, which makes them easier to read, and may censor sensitive information, such as your username, or system information. + +## Crash Reports {#crash-reports} + +Crash reports are automatically generated when the game crashes. They only contain crash information and not the actual logs of the game. They are located in the `crash-reports` folder in the game directory. + +For more information on crash reports, see [Crash Reports](./crash-reports). + +## Locating Logs {#locating-logs} + +This guide covers the official Minecraft Launcher (commonly referred to as the "vanilla launcher") - for third party launchers, you should consult their documentation. + +Logs are located in the `logs` folder in the game directory, the game directory can be found in the following locations depending on your operating system: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +The latest log is called `latest.log`, and previous logs use the naming pattern `yyyy-mm-dd_number.log.gz`. + +## Uploading Logs Online {#uploading-logs-online} + +Logs can be uploaded to a variety of services, such as: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/players/updating-fabric.md b/versions/1.21/players/updating-fabric.md new file mode 100644 index 000000000..25cee75c2 --- /dev/null +++ b/versions/1.21/players/updating-fabric.md @@ -0,0 +1,43 @@ +--- +title: Updating Fabric +description: A step by step guide on how to update Fabric. +authors: + - IMB11 + - modmuss50 + +search: false +--- + +# Updating Fabric {#updating-fabric} + +This guide will walk you through updating Fabric for the Minecraft Launcher. + +For third party launchers, you should consult their documentation. + +Updating Fabric is a very similar process to installing Fabric, so parts of this guide will be the same as the [Installing Fabric](./installing-fabric) guide. + +## Why Should I Update Fabric Loader? {#why-should-i-update-fabric-loader} + +Newer mods may require a newer version of Fabric Loader to work, so it's important to keep it up to date to ensure you can use the latest mods. + + + +To update Fabric, simply ensure the game version and Loader version is correct then click `Install`. + +::: warning IMPORTANT +Make sure to uncheck 'Create Profile' when running the installer, otherwise it will create a new profile, which in this case we don't need. +::: + +## 3. Open the Profile in the Minecraft Launcher {#3-open-the-profile-in-the-minecraft-launcher} + +Once the installer has finished, you can open the Minecraft Launcher and go to the `Installations` tab. You should go to your Fabric profile and open the edit screen. + +Replace the version with the new version of Fabric Loader you just installed, and press `Save`. + +![Updating Fabric Loader version in the Minecraft Launcher](/assets/players/updating-fabric.png) + +## 4. You're Done! {#4-you-re-done} + +Once you've completed the steps you can go back to the `Play` tab, select the Fabric profile from the dropdown in the bottom left corner and press play! + +If you encounter any issues whilst following this guide, you can ask for help in the [Fabric Discord](https://discord.gg/v6v4pMv) in the `#player-support` channel. diff --git a/versions/1.21/translated/.gitkeep b/versions/1.21/translated/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/versions/1.21/translated/cs_cz/index.md b/versions/1.21/translated/cs_cz/index.md new file mode 100644 index 000000000..c8e0e3e8d --- /dev/null +++ b/versions/1.21/translated/cs_cz/index.md @@ -0,0 +1,27 @@ +--- +title: Fabric Dokumentace +description: Oficiální dokumentace pro Fabric, modovací toolchain pro Minecraft. +layout: home +hero: + name: Fabric Dokumentace + tagline: Oficiální dokumentace pro Fabric, modovací toolchain pro Minecraft. +features: + - title: Developer Guides + icon: 🛠️ + details: Our curated developer guides, written by the community, span a wide range of topics from setting up a development environment to more advanced topics, such as rendering and networking. + link: /develop/ + linkText: Začít + - title: Hráčské Návody + icon: 📚 + details: Jste hráč snícím o používání Fabric modů? Naše hráčské návody vám mohou pomoct. Tyto návody pomůžou se stahování, instalací a spravení Fabric modů. + link: /players/ + linkText: Zjistit více +--- + +
+ +## Chcete nám pomoct? + +If you want to contribute to the Fabric Documentation, you can find the source code on [GitHub](https://github.com/FabricMC/fabric-docs), and the relevant [contribution guidelines](./contributing). + +
diff --git a/versions/1.21/translated/cs_cz/players/faq.md b/versions/1.21/translated/cs_cz/players/faq.md new file mode 100644 index 000000000..ddb72b601 --- /dev/null +++ b/versions/1.21/translated/cs_cz/players/faq.md @@ -0,0 +1,31 @@ +--- +title: Často kladené otázky hráčů +description: Často kladené otázky hráčů a administrátorů ohledně Fabricu. +--- + +# Často kladené dotazy + +Je hodně otázek, které jsou často kladeny, proto jsme je shromáždili sem do listu. + +## Všeobecné otázky + +### Jaké verze Minecraftu Fabric podporuje? + +Fabric oficiálně podporuje všechny verze hry od snapshotu `18w34b`, a vydání `1.14`. + +### Kam mohu nahrát módy vytvořené přes Fabric? + +:::info +Vždy byste měli zkontrolovat, zda jsou módy z důvěryhodného zdroje. Podívejte se na [Hledání důvěryhodných módů](./finding-mods) pro více informací. +::: + +Většina autorů módů publikuje své módy na [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) a [CurseForge](https://www.curseforge.com/minecraft/search?page=1&pageSize=20&sortType=1&class=mc-mods&gameFlavorsIds=4), avšak někteří mohou preferovat nahrávání na své stránky nebo na GitHub. + +### Kde mohu nalézt předvytvořené Fabric modpacky? + +Můžete je nalézt na vícero platformách, např: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?page=1&pageSize=20&sortType=1&class=modpacks&gameFlavorsIds=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/de_de/contributing.md b/versions/1.21/translated/de_de/contributing.md new file mode 100644 index 000000000..d4ddb23cf --- /dev/null +++ b/versions/1.21/translated/de_de/contributing.md @@ -0,0 +1,253 @@ +--- +title: Beitragsrichtlinen +description: Richtlinien zur Beitragserstellung für die Fabric-Dokumentation +--- + +# Wie man beiträgt {#contributing} + +Diese Website nutzt [VitePress](https://vitepress.dev/) um statisches HTML von den verschiedenen Markdown-Dateien zu generrieren. Du solltest dich mit den Markdown-Erweiterungen vertraut machen, die VitePress [hier](https://vitepress.dev/guide/markdown#features) unterstützt. + +Du hast drei Möglichkeiten, zu dieser Website beizutragen: + +- [Übersetzen der Dokumentation](#translating-documentation) +- [Inhalte beitragen](#contributing-content) +- [Zum Framework beitragen](#contributing-framework) + +Alle Beiträge müssen unseren [Stilrichtlinien](#stilrichtlinien) entsprechen. + +## Übersetzen der Dokumentation {#translating-documentation} + +Falls du die Dokumentation in deine Sprache übersetzen möchtest, kannst du dies auf der [Fabric Crowdin-Seite](https://crowdin.com/project/fabricmc) tun. + + + +## new-content Inhalt beitragen {#contributing-content} + +Inhaltliche Beiträge sind die wichtigste Möglichkeit, zur Fabric-Dokumentation beizutragen. + +Alle Inhaltsbeiträge durchlaufen die folgenden Stufen, die jeweils mit einem Label versehen sind: + +1. locally Änderungen vorbereiten und einen Pull Request pushen +2. stage:expansion: Anleitung zur Erweiterung, falls erforderlich +3. stage:verification: Verifikation des Inhalts +4. stage:cleanup: Grammatik, Linting... +5. stage:ready: Bereit zum mergen! + +Alle Inhalte sollten unseren [Stilrichtlinien](#style-guidelines) entsprechen. + +### 1. Deine Änderungen vorbereiten {#1-prepare-your-changes} + +Diese Website ist OpenSource und wird in einem GitHub-Repository entwickelt, was bedeutet, dass wir uns auf den GitHub-Ablauf verlassen: + +1. eine Seite im Ordner `/players` mit der Seite `installing-fabric` aus `/players/installing-fabric.md` zu verknüpfen, musst du Folgendes tun: +2. Erstelle bei deinem Fork ein neues Branch +3. Mache deine Änderung bei diesem Branch +4. Öffne einen Pull Request bei dem ursprünglichen Repository + +Du kannst [hier](https://docs.github.com/en/get-started/using-github/github-flow) mehr über den GitHub-Ablauf lesen. + +Du kannst Änderungen entweder durch die Weboberfläche von GitHub machen oder du kannst die Website lokal entwickeln und die Vorschau ansehen. + +#### Deinen Fork klonen {#clone-your-fork} + +Wenn du lokal entwickeln willst, musst du [Git](https://git-scm.com/) installieren. + +Danach klone deinen Fork des Repository mit: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### Abhängigkeiten installieren {#install-dependencies} + +**Wenn du deine Änderungen lokal ansehen möchtest, musst du [Node.js 18+](https://nodejs.org/en/) installieren.** + +Danach stelle sicher, dass du alle Abhängigkeiten installierst: + +```sh +npm install +``` + +#### Den Developmentserver ausführen {#run-the-development-server} + +Damit kannst du deine Änderungen lokal auf `localhost:3000` ansehen und die Seite wird automatisch neu geladen, wenn du Änderungen vornimmst. + +```sh +npm run dev +``` + +Jetzt kannst du die Website über den Browser öffnen und durchsuchen, indem du `http://localhost:5173` aufrufst. + +#### Die Website bauen {#building-the-website} + +Dies wird alle Markdown-Dateien in statische HTML-Dateien kompilieren und diese in `.vitepress/dist` ablegen + +```sh +npm run build +``` + +#### Vorschau der gebauten Website {#previewing-the-built-website} + +Dies wird einen lokalen Server auf Port 3000 starten, der den Inhalt in `.vitepress/dist` bereitstellt. + +```sh +npm run preview +``` + +#### Einen Pull Request öffnen {#opening-a-pull-request} + +Wenn du mit deinen Änderungen zufrieden bist, kannst du sie \`push´en: + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +Folge dann dem Link in der Ausgabe von `git push`, um einen PR zu öffnen. + +### 2. stage:expansion Anleitung zur Erweiterung, falls erforderlich {#2-guidance-for-expansion-if-needed} + +Wenn das Dokumentationsteam der Meinung ist, dass du deinen Pull Request erweitern könntest, wird ein Mitglied des Teams das Label stage:expansion zu deinem Pull Request hinzufügen, zusammen mit einem Kommentar, der erklärt, was du deren Meinung nach erweitern könnten. Wenn du mit dem Vorschlag einverstanden bist, kannst du deinen Pull-Request erweitern. + +Wenn du deinen Pull Request nicht erweitern willst, aber gerne möchtest, dass jemand anderes ihn zu einem späteren Zeitpunkt erweitert, solltest du ein Issue auf der [Issues Seite](https://github.com/FabricMC/fabric-docs/issues) erstellen und erklären, was deiner Meinung nach erweitert werden könnte. Das Dokumentationsteam fügt dann das Label help-wanted zu deinem PR hinzu. + +### 3. stage:verification Verifikation des Inhalts {#3-content-verification} + +Dies ist die wichtigste Phase, da sie sicherstellt, dass der Inhalt korrekt ist und den Stilrichtlinien der Fabric Documentation entspricht. + +In dieser Phase sollten die folgenden Fragen beantwortet werden: + +- Ist der ganze Inhalt korrekt? +- Ist der ganze Inhalt aktuell? +- Deckt der Inhalt alle Fälle ab, z. B. verschiedene Betriebssysteme? + +### 4. stage:cleanup Aufräumen {#4-cleanup} + +In dieser Phase passiert folgendes: + +- Beheben aller Grammatikfehler mit [LanguageTool](https://languagetool.org/) +- Linten alle Markdown-Dateien mit [`markdownlint`](https://github.com/DavidAnson/markdownlint) +- Formatierung des ganzen Java-Code mit [Checkstyle](https://checkstyle.sourceforge.io/) +- Andere verschiedene Korrekturen oder Verbesserungen + +## framework Zum Framework beitragen {#contributing-framework} + +Framework bezieht sich auf die interne Struktur der Website. Alle Pull Requests, die das Framework der Website verändern, werden mit dem Label framework gekennzeichnet. + +Du solltest wirklich nur Pull-Requests für das Framework eröffnen, nachdem du dich mit dem Dokumentationsteam im [Fabric Discord](https://discord.gg/v6v4pMv) oder über ein Issue beraten hast. + +:::info +**Hinweis: Das Ändern von Seitenleistendateien und der Konfiguration der Navigationsleiste zählt nicht als Pull-Request für das Framework.** +::: + +## Stilrichtlinien {#style-guidelines} + +Wenn du unsicher bist, kannst du im [Fabric Discord](https://discord.gg/v6v4pMv) oder über GitHub Diskussionen nachfragen. + +### Schreibe das Original in amerikanischem Englisch {#write-the-original-in-american-english} + +Die ganze originale Dokumentation ist in englischer Sprache verfasst und folgt den amerikanischen Grammatikregeln. + +### Daten zum Frontmatter hinzufügen {#add-data-to-the-frontmatter} + +Alle Seiten müssen einen Titel und eine Beschreibung im Frontmatter haben. + +Vergiss nicht, auch deinen GitHub-Benutzernamen zu `authors` im Frontmatter der Markdown-Datei hinzuzufügen! Auf diese Weise können wir dir angemessene Anerkennung geben. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### Füge Anker zu den Überschriften hinzu {#add-anchors-to-headings} + +Jede Überschrift muss einen Anker haben, der als Link zu dieser Überschrift dient: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +Der Anker muss Kleinbuchstaben, Zahlen und Bindestriche enthalten. + +### Code innerhalb des `/reference` Mods platzieren {#place-code-within-the-reference-mod} + +Wenn du Seiten erstellst oder änderst, die Code enthalten, platziere den Code an einer geeigneten Stelle innerhalb des Referenz-Mod (im Ordner `/reference` des Repository). Verwende dann die [Code-Snippet-Funktion, die von VitePress angeboten wird](https://vitepress.dev/guide/markdown#import-code-snippets), um den Code einzubetten, oder wenn du eine größere Kontrollspanne benötigst, kannst du die [transclude-Funktion von `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced) verwenden. + +Dies wird die Zeilen 15-21 der Datei `FabricDocsReference.java` des Referenz-Mod einbetten. + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +Nur der Code zwischen den `#test_transclude`-Tags wird eingebettet. + +So werden beispielsweise die Abschnitte der obigen Datei eingebettet, die mit dem Tag `#entrypoint` gekennzeichnet sind: + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### Erstelle eine Seitenleiste für jeden neuen Abschnitt {#create-a-sidebar-for-each-new-section} + +Wenn du einen neuen Abschnitt erstellst, solltest du eine neue Seitenleiste im Ordner `.vitepress/sidebars` anlegen und sie zur Datei `config.mts` hinzufügen. + +Wenn du dabei Hilfe benötigst, frage bitte auf dem [Fabric Discord](https://discord.gg/v6v4pMv) im Kanal `#docs` nach. + +### Anleitung zur Erweiterung {#add-new-pages-to-the-relevant-sidebars} + +Wenn du eine neue Seite erstellst, solltest du sie der entsprechenden Seitenleiste im Ordner `.vitepress/sidebars` hinzufügen. + +Auch hier gilt: Wenn du Hilfe benötigst, frage auf dem Fabric Discord im Kanal `#docs` nach. + +### Platziere Medien in `/assets` {#place-media-in-assets} + +Alle Bilder sollten an einem geeigneten Ort im Ordner `/assets` abgelegt werden. + +### Nutze relative Links! {#use-relative-links} + +Der Grund dafür ist das vorhandene Versionssystem, das die Links verarbeitet, um die Version vorher hinzuzufügen. Wenn du absolute Links verwendest, wird die Versionsnummer nicht zum Link hinzugefügt. + +Du darfst auch nicht die Dateierweiterung zu dem Link hinzufügen. + +Um zum Beispiel von der Seite `/players/index.md` auf die Seite `/develop/index.md` zu verlinken, musst du folgendes tun: + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/de_de/develop/automatic-testing.md b/versions/1.21/translated/de_de/develop/automatic-testing.md new file mode 100644 index 000000000..4cf0fe53b --- /dev/null +++ b/versions/1.21/translated/de_de/develop/automatic-testing.md @@ -0,0 +1,91 @@ +--- +title: Automatisiertes Testen +description: Ein Leitfaden zum Schreiben von automatisierten Tests mit Fabric Loader JUnit. +authors: + - kevinthegreat1 +--- + +# Automatisiertes Testen {#automated-testing} + +Diese Seite erklärt, wie man Code schreibt, um Teile des Mods automatisch zu testen. Es gibt zwei Möglichkeiten, deinen Mod automatisch zu testen: Unit Tests mit Fabric Loader JUnit oder Spieltests mit dem Gametest-Framework von Minecraft. + +Unit-Tests sollten verwendet werden, um Komponenten deines Codes zu testen, wie z. B. Methoden und Hilfsklassen, während Spieltests einen tatsächlichen Minecraft-Client und -Server starten, um deine Tests auszuführen, was sie für das Testen von Funktionen und Gameplay geeignet macht. + +:::warning +Aktuell deckt dieser Leitfaden nur Unit Tests ab. +::: + +## Unit-Tests {#unit-testing} + +Da Minecraft Modding auf Laufzeit-Bytecode-Modifikationswerkzeuge wie Mixin angewiesen ist, würde das einfache Hinzufügen und Verwenden von JUnit normalerweise nicht funktionieren. Aus diesem Grund bietet Fabric, Fabric Loader JUnit, ein JUnit-Plugin, das Unit-Tests in Minecraft ermöglicht. + +### Fabric Loader JUnit reinrichten {#setting-up-fabric-loader-junit} + +Zuerst müssen wir Fabric Loader JUnit zu der Entwicklungsumgebung hinzufügen. Füge folgendes zu deinem Dependencies-Block in deiner `build.gradle`-Datei hinzu: + +@[code lang=groovy transcludeWith=:::automatic-testing:1](@/reference/build.gradle) + +Dann müssen wir Gradle anweisen, Fabric Loader JUnit zum Testen zu verwenden. Du kannst dies tun, indem du den folgenden Code zu deiner `build.gradle`-Datei hinzufügst: + +@[code lang=groovy transcludeWith=:::automatic-testing:2](@/reference/1.21/build.gradle) + +### Tests schreiben {#writing-tests} + +Nachdem du Gradle neu geladen hast, bist du bereit, Tests zu schreiben. + +Diese Tests werden genau wie normale JUnit-Tests geschrieben, mit ein paar zusätzlichen Einstellungen, wenn du auf eine von einer Registry abhängigen Klasse wie `ItemStack` zugreifen willst. Wenn du mit JUnit vertraut bist, kannst du zu [Registries einrichten](#setting-up-registries) übergehen. + +#### Deine erste Testklasse erstellen {#setting-up-your-first-test-class} + +Tests werden im Verzeichnis `src/test/java` geschrieben. + +Eine Namenskonvention besteht darin, die Paketstruktur der Klasse, die du testest, widerzuspiegeln. Zum Beispiel, um `src/main/java/com/example/docs/codec/BeanType.java` zu testen, würdest du eine Klasse `src/test/java/com/example/docs/codec/BeanTypeTest.java` erstellen. Beachte, dass wir `Test` an das Ende des Klassennamens angefügt haben. Dies ermöglicht dir den einfachen Zugang zu Paket-Privaten Methoden und Feldern. + +Eine andere Namenskonvention ist ein `test`-Paket, wie `src/test/java/com/example/docs/test/codec/BeanTypeTest.java`. Dies verhindert einige Probleme, die bei der Verwendung desselben Pakets auftreten können, wenn du Java-Module verwendest. + +Nachdem du die Testklasse erstellt hast, verwende ⌘/CTRLN, um das Generate-Menü aufzurufen. Wähle Test und beginne mit der Eingabe deines Methodennamens, der normalerweise mit `test` beginnt. Drücke ENTER, wenn du fertig bist. Weitere Tipps und Tricks zur Verwendung der IDE findest du unter [IDE Tipps und Tricks](./ide-tips-and-tricks#code-generation). + +![Eine Testmethode generieren](/assets/develop/misc/automatic-testing/unit_testing_01.png) + +Du kannst die Methodensignatur natürlich auch von Hand schreiben, und jede Instanzmethode ohne Parameter und mit einem ungültigen Rückgabetyp wird als Testmethode identifiziert. Das Ergebnis sollte wie folgt aussehen: + +![Eine leere Testmethode mit Testindikatoren](/assets/develop/misc/automatic-testing/unit_testing_02.png) + +Beachte die grünen Pfeilindikatoren in dem Zwischenraum: Du kannst ganz einfach einen Test ausführen, indem du sie anklickst. Alternativ dazu werden deine Tests automatisch bei jedem Build ausgeführt, einschließlich CI-Builds wie GitHub Actions. Wenn du GitHub Actions verwendest, solltest du unbedingt [GitHub Actions einrichten](#setting-up-github-actions) lesen. + +Nun ist es an der Zeit, den eigentlichen Testcode zu schreiben. Du kannst Bedingungen mit Hilfe von `org.junit.jupiter.api.Assertions` prüfen. Siehe dazu den folgenden Test an: + +@[code lang=java transcludeWith=:::automatic-testing:4](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +Für eine Erklärung, was dieser Code tatsächlich tut, siehe [Codecs](./codecs#registry-dispatch). + +#### Registries einrichten {#setting-up-registries} + +Großartig, der erste Test war erfolgreich! Aber Moment, der zweite Test ist fehlgeschlagen? In den Logs wird einer der folgenden Fehler angezeigt. + +@[code lang=java transcludeWith=:::automatic-testing:5](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +Dies liegt daran, dass wir versuchen, auf die Registry oder eine Klasse zuzugreifen, die von der Registry abhängt (oder, in seltenen Fällen, von anderen Minecraft-Klassen wie `SharedConstants`), aber Minecraft wurde noch nicht initialisiert. Wir müssen es nur ein wenig initialisieren, damit die Registries funktionieren. Fügen einfach den folgenden Code an den Anfang deiner Methode `beforeAll`. + +@[code lang=java transcludeWith=:::automatic-testing:7](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +### Github Actions einrichten {#setting-up-github-actions} + +:::info +In diesem Abschnitt wird davon ausgegangen, dass du den standardmäßigen GitHub Action-Workflow verwendest, der in dem Beispielmod und in der Mod-Vorlage enthalten ist. +::: + +Deine Tests werden nun bei jedem Build ausgeführt, auch bei denen von CI-Anbietern wie GitHub Actions. Was aber, wenn ein Build fehlschlägt? Wir müssen die Logs als Artefakt hochladen, damit wir die Testberichte ansehen können. + +Füge dies zu deiner `.github/workflows/build.yml`-Datei hinzu, unterhalb des `./gradlew build` Schrittes. + +```yaml +- name: Store reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: reports + path: | + **/build/reports/ + **/build/test-results/ +``` diff --git a/versions/1.21/translated/de_de/develop/blocks/block-entities.md b/versions/1.21/translated/de_de/develop/blocks/block-entities.md new file mode 100644 index 000000000..150e5205e --- /dev/null +++ b/versions/1.21/translated/de_de/develop/blocks/block-entities.md @@ -0,0 +1,112 @@ +--- +title: Block Entitäten +description: Lerne, wie du Block Entitäten für deine benutzerdefinierten Blöcke erstellst. +authors: + - natri0 +--- + +# Block Entitäten {#block-entities} + +Block Entitäten sind ein Weg für Blöcke zusätzliche Daten, die nicht Teil des Blockzustands sind, zu speichern: Inventarinhalte, benutzerdefinierter Name und so weiter. +Minecraft nutzt Block Entitäten für Blöcke, wie Kisten, Öfen und Befehlsblöcke. + +Als Beispiel werden wir einen Block erstellen, der zählt, wie oft er mit der rechten Maustaste angeklickt wurde. + +## Erstellen der Block Entität {#creating-the-block-entity} + +Damit Minecraft die neuen Block Entitäten erkennt und lädt, müssen wir einen Block Entität Typen erstellen. Das machen wir, indem wir die `BlockEntity` Klasse erweitern und in einer neuen `ModBlockEntities` Klasse registrieren. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Wenn eine `BlockEntity` registriert wird, gibt es einen `BlockEntityType` zurück, wie bei dem `COUNTER_BLOCK_ENTITY`, welches wir oben benutzt haben: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java) + +:::tip +Man beachte, dass der Konstruktor von der `CounterBlockEntity` zwei Parameter benötigt, der Konstruktor von der `BlockEntity` jedoch drei: den `BlockEntityType`, `BlockPos` und den `BlockState`. +Wenn wir den `BlockEntityType` nicht hart kodiert hätten, würde die Klasse `ModBlockEntities` nicht kompiliert werden! Das liegt daran, dass die `BlockEntityFactory`, die ein funktionales Interface ist, eine Funktion beschreibt, die nur zwei Parameter benötigt, genau wie unser Konstruktor. +::: + +## Erstellen des Blocks {#creating-the-block} + +Um als Nächstes die Block Entität zu nutzen, brauchen wir einen Block, der `BlockEntityProvider` implementiert. Lass uns einen erstellen und `CounterBlock` nennen. + +:::tip +Es gibt zwei Wege, um das zu machen: + +- Einen Block erstellen, der `BlockWithEntity` erweitert und die `createBlockEntity` Methode implementiert (_und_ die `getRenderType` Methode, da `BlockWithEntity` den Block standardmäßig Unsichtbar macht) +- Einen Block erstellen, der `BlockEntityProvider` implementiert und die `createBlockEntity` Methode überschreibt + +Wir werden in diesem Beispiel den ersten Weg nutzen, da `BlockWithEntity` ein paar nützliche Funktionen anbietet. +::: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Da wir die `BlockWithEntity` Klasse erweitern, müssen wir auch die `createCodec` Methode implementieren, was aber recht leicht ist. + +Im Gegensatz zu Blöcken, die Singletons sind, wird für jede Instanz des Blocks eine neue Blockentität erstellt. Dies geschieht mit der Methode `createBlockEntity`, die die Position und den `BlockState` entgegennimmt und ein `BlockEntity` zurückgibt, oder `null`, wenn es keins geben sollte. + +Vergiss nicht, den Block in der Klasse `ModBlocks` zu registrieren, genau wie in der Anleitung [Deinen ersten Block erstellen](../blocks/first-block): + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +## Nutzen der Block Entität {#using-the-block-entity} + +Jetzt, da wir eine Blockentität haben, können wir sie verwenden, um die Anzahl der Rechtsklicks auf den Block zu speichern. Dafür werden wir der Klasse `CounterBlockEntity` ein Feld `clicks` hinzufügen: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Die Methode `markDirty`, die in `incrementClicks` verwendet wird, teilt dem Spiel mit, dass die Daten dieser Entität aktualisiert wurden; dies wird nützlich sein, wenn wir die Methoden hinzufügen, um den Zähler zu serialisieren und ihn aus der Speicherdatei zurückzuladen. + +Als Nächstes müssen wir dieses Feld jedes Mal erhöhen, wenn der Block mit der rechten Maustaste angeklickt wird. Dies geschieht indem die Methode `onUse` in der Klasse `CounterBlock` überschrieben wird: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Da die `BlockEntity` nicht an die Methode übergeben wird, verwenden wir `world.getBlockEntity(pos)`, und wenn die `BlockEntity` nicht gültig ist, kehren wir aus der Methode zurück. + +!["You've clicked the block for the 6th time" Nachricht auf dem Bildschirm nach dem Rechtsklick](/assets/develop/blocks/block_entities_1.png) + +## Speichern und Laden von Daten {#saving-loading} + +Da wir nun einen funktionierenden Block haben, sollten wir dafür sorgen, dass der Zähler zwischen den Neustarts des Spiels nicht zurückgesetzt wird. Dies geschieht durch Serialisierung in NBT, wenn das Spiel speichert, und Deserialisierung, wenn es geladen wird. + +Die Serialisierung erfolgt mit der Methode `writeNbt`: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Hier fügen wir die Felder hinzu, die in dem übergebenen `NbtCompound` gespeichert werden sollen: im Fall des Zählerblocks ist das das Feld `clicks`. + +Das Lesen ist ähnlich, aber anstatt in dem `NbtCompound` zu speichern, holt man sich die Werte, die man vorher gespeichert hat, und speichert sie in den Feldern der BlockEntity: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Wenn wir nun speichern und das Spiel neu laden, sollte der Zählerblock dort weitermachen, wo er beim Speichern aufgehört hat. + +## Ticker {#tickers} + +Das Interface `BlockEntityProvider` definiert auch eine Methode namens `getTicker`, mit der für jede Instanz des Blocks bei jedem Tick Code ausgeführt werden kann. Wir können das implementieren, indem wir eine statische Methode erstellen, die als `BlockEntityTicker` verwendet wird: + +Die Methode `getTicker` sollte auch prüfen, ob der übergebene `BlockEntityType` derselbe ist wie der, den wir verwenden, und wenn ja, die Funktion zurückgeben, die bei jedem Tick aufgerufen wird. Glücklicherweise gibt es eine Hilfsfunktion, die diese Prüfung in `BlockWithEntity` durchführt: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +`CounterBlockEntity::tick` ist ein Verweis auf die statische Methode `tick`, die wir in der Klasse `CounterBlockEntity` erstellen sollten. Eine solche Strukturierung ist nicht erforderlich, aber es ist eine gute Praxis, um den Code sauber und übersichtlich zu halten. + +Nehmen wir an, wir wollen, dass der Zähler nur alle 10 Ticks (2 Mal pro Sekunde) erhöht werden kann. Wir können dies tun, indem wir der Klasse `CounterBlockEntity` ein Feld `ticksSinceLast` hinzufügen und es bei jedem Tick erhöhen: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Vergiss nicht, dieses Feld zu serialisieren und zu deserialisieren! + +Jetzt können wir `ticksSinceLast` verwenden, um zu prüfen, ob der Zähler in `incrementClicks` erhöht werden kann: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +:::tip +Wenn die Blockentität nicht zu ticken scheint, überprüfe den Registrierungscode! Es sollte die Blöcke, die für diese Entität gültig sind, an den `BlockEntityType.Builder`, übergeben, sonst wird eine Warnung in der Konsole ausgegeben: + +```text +[13:27:55] [Server thread/WARN] (Minecraft) Block entity fabric-docs-reference:counter @ BlockPos{x=-29, y=125, z=18} state Block{fabric-docs-reference:counter_block} invalid for ticking: +``` + +::: diff --git a/versions/1.21/translated/de_de/develop/blocks/block-entity-renderer.md b/versions/1.21/translated/de_de/develop/blocks/block-entity-renderer.md new file mode 100644 index 000000000..c93f354ba --- /dev/null +++ b/versions/1.21/translated/de_de/develop/blocks/block-entity-renderer.md @@ -0,0 +1,99 @@ +--- +title: Block Entität Renderer +description: Erfahre, wie du das Rendern mit Block Entitäts Renderern aufwerten kannst. +authors: + - natri0 +--- + +# Block Entität Renderer {#block-entity-renderers} + +Manchmal reicht das Nutzen von Minecraft's Modellformat nicht aus. Wenn du dynamisches Rendering zu diesen hinzufügen willst, wirst du einen `BlockEntityRenderer` nutzen müssen. + +Lasst uns als Beispiel den Zählerblock aus dem [Artikel zu Block Entitäten](../blocks/block-entities) die Zahl an Klicks auf der Oberseite anzeigen lassen. + +## Erstellen eines BlockEntityRenderer {#creating-a-blockentityrenderer} + +Zuerst müssen wir einen `BlockEntityRenderer` für unsere `CounterBlockEntity` erstellen. + +Beim Erstellen eines `BlockEntityRenderer` für die `CounterBlockEntity` ist es wichtig, wenn das Projekt geteilte Quellen für den Client und den Server nutzt, die Klasse in das passende Quellenverzeichnis, wie `src/client/`, zu platzieren. Der Zugriff auf Rendering-bezogene Klassen direkt im `src/main/` Quellenverzeichnis ist nicht sicher, da diese Klassen möglicherweise am Server nicht geladen sind. + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +Die neue Klasse hat einen Konstruktor mit einem `BlockEntityRendererFactory.Context` als Parameter. Der `Context` hat einige nützliche Rendering-Hilfsmittel, wie den `ItemRenderer` oder `TextRenderer`. +Durch die Aufnahme eines derartigen Konstruktors, wird es außerdem möglich den Konstuktor als funktionales Interface der `BlockEntityRendererFactory` selbst zu verwenden: + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java) + +Füge den Einstiegspunkt zu der Datei `fabric.mod.json` hinzu, damit der Renderer registriert ist. + +`BlockEntityRendererFactories` ist eine Registrierung, die jeden `BlockEntityType` mit benutzerdefinierten Rendering-Code dem entsprechenden `BlockEntityRenderer` zuordnet. + +## Auf Blöcke zeichnen {#drawing-on-blocks} + +Jetzt, da wir den Renderer haben, können wir zeichnen. Die Methode `render` wird bei jedem Frame aufgerufen und ist der Ort, an dem die Magie des Renderns passiert. + +### Umher bewegen {#moving-around} + +Zunächst müssen wir den Text versetzen und drehen, damit er sich auf der oberen Seite des Blocks befindet. + +:::info +Wie der Name bereits vermuten lässt ist der `MatrixStack` ein _Stapel_, was bedeutet, dass du Transformationen darauf hinzufügen (push) und davon entfernen (pop) kannst. +Eine gute Faustregel ist es, einen neuen Block an den Anfang der `render`-Methode hinzuzufügen und ihn am Ende wieder zu entfernen, so dass das Rendern eines Blocks die anderen nicht beeinflusst. + +Mehr Informationen zu dem `MatrixStack` kann in dem [Artikel zu den grundlegenden Konzepten des Rendering](../rendering/basic-concepts) gefunden werden. +::: + +Zum besseren Verständnis der erforderlichen Verschiebungen und Drehungen sollten wir sie visualisieren. In diesem Bild ist der grüne Block die Position, an der der Text gezeichnet werden würde, standardmäßig am äußersten linken unteren Punkt des Blocks: + +![Standard Position des Rendern](/assets/develop/blocks/block_entity_renderer_1.png) + +Zunächst müssen wir den Text auf der X- und Z-Achse in die Mitte und ihn dann an der Y-Achse an den oberen Rand des Blocks verschieben: + +![Grüner Block am obersten zentriertem Punkt](/assets/develop/blocks/block_entity_renderer_2.png) + +Died wird durch einen einzelnen `translate` Aufruf gemacht: + +```java +matrices.translate(0.5, 1, 0.5); +``` + +Somit ist die _Verschiebung_ erledigt, _Drehung_ und _Skalierung_ bleiben. + +Standardmäßig wird der Text auf der XY-Ebene gezeichnet, also müssen wir ihn um 90 Grad um die X-Achse drehen, damit er auf der XZ-Ebene nach oben zeigt: + +![Grüner Block, nach oben schauend, am obersten zentriertem Punkt](/assets/develop/blocks/block_entity_renderer_3.png) + +Der `MatrixStack` hat keine `rotate` Methode, stattdessen müssen wir `multiply` und `RotationAxis.POSITIVE_X` verwenden: + +```java +matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); +``` + +Jetzt ist der Text an der korrekten Position, aber ist zu groß. Der `BlockEntityRenderer` ordnet den ganzen Block zu einem `[-0.5, 0.5]` Würfel zu, während der `TextRenderer` X-Koordinaten von `[0, 9]` verwendet. Somit müssen wir es um den Faktor 18 herunter skalieren: + +```java +matrices.scale(1/18f, 1/18f, 1/18f); +``` + +Jetzt sieht die ganze Transformation wie folgt aus: + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +### Zeichnen von Text {#drawing-text} + +Wie bereits früher erwähnt, hat der an den Konstruktor unseres Renderers übergebene `Context` einen `TextRenderer`, welchen wir für das Zeichnen von Text einsetzen können. Für dieses Beispiel werden wir ihn in einem Feld speichern. + +Der `TextRenderer` hat Methoden um Text zu messen (`getWidth`), welche für das Zentrieren nützlich ist, und um ihn zu zeichnen (`draw`). + +@[code transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +Die Methode `draw` nimmt einige Paramter, aber die Wichtigsten sind: + +- der zu zeichnende `Text` (oder `String`); +- seine `x` und `y` Koordinaten; +- der RGB `color` Wert; +- die `Matrix4f`, die beschreibt, wie er transformiert werden soll (um eine aus einem `MatrixStack` zu erhalten, können wir `.peek().getPositionMatrix()` verwenden, um die `Matrix4f` für den obersten Eintrag zu erhalten). + +Und nach dieser ganzen Arbeit, ist hier das Ergebnis: + +![Zählerblock mit einer Zahl auf der Oberseite](/assets/develop/blocks/block_entity_renderer_4.png) diff --git a/versions/1.21/translated/de_de/develop/blocks/blockstates.md b/versions/1.21/translated/de_de/develop/blocks/blockstates.md new file mode 100644 index 000000000..1260bd16c --- /dev/null +++ b/versions/1.21/translated/de_de/develop/blocks/blockstates.md @@ -0,0 +1,127 @@ +--- +title: Blockzustände +description: Lerne, warum Blockzustände eine großartige Möglichkeit sind, Funktionalität zu deinem Block hinzuzufügen. +authors: + - IMB11 +--- + +# Blockzustände {#block-states} + +Ein Blockzustand entspricht ein wenig Daten, die einem einzelnen Block in der Minecraft-Welt zugeordnet sind und Informationen über den Block in Form von Eigenschaften enthält - einige Beispiele für Eigenschaften, die Vanilla in Blockzuständen speichert: + +- Rotation: Hauptsächlich für Baumstämme und andere natürliche Blöcke verwendet. +- Activated: Wird häufig in Redstone-Geräten und Blöcken wie dem Ofen oder dem Räucherofen verwendet. +- Age: Wird in Samen, Pflanzen, Setzlingen, Seetang, etc. verwendet + +Du kannst wahrscheinlich sehen, warum sie nützlich sind - sie vermeiden die Notwendigkeit, NBT-Daten in einer Blockentität zu speichern - was die Weltgröße reduziert und TPS-Probleme verhindert! + +Blockzustand-Definitionen finden sich im Ordner `assets//blockstates`. + +## Beispiel: Säulenblock {#pillar-block} + + + +Minecraft verfügt bereits über einige benutzerdefinierte Klassen, mit denen man schnell bestimmte Arten von Blöcken erstellen kann - in diesem Beispiel wird die Erstellung eines Blocks mit der Eigenschaft `axis` durch die Erstellung eines „Condensed Oak Log“-Blocks erläutert. + +Die Vanilla `PillarBlock` Klasse erlaubt, dass der Block in der X, Y oder Z Axe platziert werden kann. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Säulenblöcke haben zwei Texturen, oben und an der Seite - sie verwenden das Modell `block/cube_column`. + +Wie immer bei allen Blocktexturen befinden sich die Texturdateien in `assets//textures/block`. + +Texturen + +Da der Säulenblock zwei Positionen hat, eine horizontale und eine vertikale, müssen wir zwei separate Modelldateien erstellen: + +- `condensed_oak_log_horizontal.json` welche das `block/cube_column_horizontal` Modell erweitert. +- `condensed_oak_log.json` welche das `block/cube_column` Modell erweitert. + +Ein Beispiel der Datei `condensed_oak_log_horizontal.json`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +Einen tieferen Einblick in alle Modifikatoren, die in den Blockzustand-Dateien verfügbar sind, findest du auf der Seite [Minecraft Wiki - Models (Block States)](https://minecraft.wiki/w/Tutorials/Models#Block_states). +::: + +Als nächstes müssen wir eine Blockzustand-Datei erstellen. Die Blockzustand-Datei ist der Ort, an dem sich die Magie abspielt - Säulenblöcke haben drei Achsen, daher werden wir für die folgenden Situationen spezielle Modelle verwenden: + +- `axis=x` - Wenn der Block entlang der X-Achse platziert wird, drehen wir das Modell so, dass es in die positive X-Richtung zeigt. +- `axis=y` - Wenn der Block entlang der Y-Achse platziert wird, verwenden wir das normale vertikale Modell. +- `axis=z` - Wenn der Block entlang der Z-Achse platziert wird, drehen wir das Modell so, dass es in die positive X-Richtung zeigt. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +Wie immer musst du eine Übersetzung für deinen Block und ein Objektmodell erstellen, das einem der beiden Modelle übergeordnet ist. + +![Beispiel eines Säulenblock im Spiel](/assets/develop/blocks/blockstates_1.png) + +## Benutzerdefinierte Blockzustände {#custom-block-states} + +Benutzerdefinierte Blockzustände sind ideal, wenn dein Block einzigartige Eigenschaften hat - manchmal kannst du feststellen, dass dein Block Vanilla-Eigenschaften wiederverwenden kann. + +Dieses Beispiel wird eine einzigartiges boolesche Eigenschaft mit dem Namen `activated` erstellen - wenn ein Spieler den Block rechtsklickt, wird der Block von `activated=false` zu `activated=true` wechseln - und seine Textur entsprechend ändern. + +### Die Eigenschaft erstellen {#creating-the-property} + +Zunächst musst du die Eigenschaft selbst erstellen - da es sich um eine boolesche Eigenschaft handelt, wird die Methode `BooleanProperty.of` verwendet. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Als Nächstes müssen wir die Eigenschaft mit der Methode `appendProperties` an den Blockzustand-Manager anhängen. Du musst die Methode überschreiben, um auf den Builder zuzugreifen: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Außerdem musst du im Konstruktor deines benutzerdefinierten Blocks einen Standardzustand für die Eigenschaft `activated` festlegen. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +Vergiss nicht, deinen Block mit der benutzerdefinierten Klasse anstelle von `Block` zu registrieren! +::: + +### Die Eigenschaft nutzen {#using-the-property} + +In diesem Beispiel wird die boolesche Eigenschaft `activated` umgeschaltet, wenn der Spieler mit dem Block interagiert. Hierfür können wir die Methode `onUse` überschreiben: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### Die Eigenschaft visualisieren {#visualizing-the-property} + +Bevor du die Blockzustand-Datei erstellst, musst du Texturen für den aktivierten und den deaktivierten Zustand des Blocks sowie für das Blockmodell bereitstellen. + +Texturen + +Nutze dein Wissen über Blockmodelle, um zwei Modelle für den Block zu erstellen: Eines für den aktivierten Zustand und eines für den deaktivierten Zustand. Danach kannst du mit der Erstellung der Blockzustand-Datei beginnen. + +Da du eine neue Eigenschaft erstellt hast, musst du die Blockzustand-Datei für den Block aktualisieren, um diese Eigenschaft zu berücksichtigen. + +Wenn du mehrere Eigenschaften bei einem Block hast, musst du alle möglichen Kombinationen berücksichtigen. Zum Beispiel würden `activated` und `axis zu 6 Kombinationen führen (zwei mögliche Werte für `activated`und drei mögliche Werte für`axis\`). + +Da es für diesen Block nur zwei mögliche Varianten gibt, da er nur eine Eigenschaft hat (`activated`), sieht der Blockzustand JSON etwa so aus: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +Da es sich bei dem Beispielblock um eine Lampe handelt, müssen wir auch dafür sorgen, dass sie Licht ausstrahlt, wenn die Eigenschaft `activated` true ist. Dies kann über die Blockeinstellungen erfolgen, die bei der Registrierung des Blocks an den Konstruktor übergeben werden. + +Du kannst die `luminance`-Methode verwenden, um die vom Block ausgestrahlte Lichtstärke einzustellen. Wir können eine statische Methode in der `PrismarineLampBlock`-Klasse erstellen, um die Lichtstärke auf der Grundlage der `activated`-Eigenschaft zurückzugeben, und sie als Methodenreferenz an die `luminance`-Methode übergeben: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +Wenn du alles vervollständigt hast, sollte das Endergebnis etwa so aussehen wie das folgende: + + diff --git a/versions/1.21/translated/de_de/develop/blocks/first-block.md b/versions/1.21/translated/de_de/develop/blocks/first-block.md new file mode 100644 index 000000000..e5fe63059 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/blocks/first-block.md @@ -0,0 +1,170 @@ +--- +title: Deinen ersten Block erstellen +description: Lerne, wie du deinen ersten benutzerdefinierten Block in Minecraft erstellen kannst. +authors: + - IMB11 + - xEobardThawne + - its-miroma +--- + +# Deinen ersten Block erstellen {#creating-your-first-block} + +Blöcke sind die Baublöcke von Minecraft (kein Wortspiel beabsichtigt) - genau wie alles andere in Minecraft, werden sie in Registern gespeichert. + +## Deine Blockklasse vorbereiten {#preparing-your-blocks-class} + +Wenn du die Seite [Dein erstes Item erstellen](../items/first-item) abgeschlossen hast, wird dir dieser Prozess sehr vertraut vorkommen - Du musst eine Methode erstellen, die deinen Block und sein Block-Item registriert. + +Du solltest diese Methode in eine Klasse mit dem Namen `ModBlocks` (oder wie auch immer du sie nennen willst) einfügen. + +Mojang macht etwas sehr ähnliches mit Vanilleblöcken; Sie können sich die Klasse `Blocks` ansehen, um zu sehen, wie sie es machen. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Genau wie bei den Items musst du sicherstellen, dass die Klasse geladen ist, damit alle statischen Felder, die Ihre Blockinstanzen enthalten, initialisiert werden. + +Du kannst dies tun, indem du eine Dummy-Methode `initialize` erstellst, die in deinem [Mod-Initialisierer](./getting-started/project-structure#entrypoints) aufgerufen werden kann, um die statische Initialisierung auszulösen. + +:::info +Wenn du nicht weißt, was statische Initialisierung ist, ist es der Prozess der Initialisierung von statischen Feldern in einer Klasse. Dies geschieht, wenn die Klasse von der JVM geladen wird, und zwar bevor Instanzen der Klasse erstellt werden. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +## Erstellen und Registrieren deines Blocks {#creating-and-registering-your-block} + +Ähnlich wie Items nehmen Blöcke in ihrem Konstruktor die Klasse `Blocks.Settings` auf, die Eigenschaften des Blocks festlegt, wie z.B. seine Soundeffekte und die Abbauebene. + +Wir werden hier nicht alle Optionen behandeln - Du kannst die Klasse selbst ansehen, um die verschiedenen Optionen zu sehen, die selbsterklärend sein sollten. + +Als Beispiel werden wir einen einfachen Block erstellen, der die Eigenschaften von Erde hat, aber ein anderes Material ist. + +:::tip +Du kannst auch `AbstractBlock.Settings.copy(AbstractBlock block)` verwenden, um die Einstellungen eines bestehenden Blocks zu kopieren. In diesem Fall hätten wir auch `Blocks.DIRT` verwenden können, um die Einstellungen von Erde zu kopieren, aber für das Beispiel verwenden wir den Builder. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Um das Blockitem automatisch zu erstellen, können wir dem Parameter `shouldRegisterItem` der Methode `register`, die wir im vorherigen Schritt erstellt haben, `true` übergeben. + +### Deinen Block zu einer Itemgruppe hinzufügen {#adding-your-block-to-an-item-group} + +Da das `BlockItem` automatisch erstellt und registriert wird, musst du, um ihn zu einer Itemgruppe hinzuzufügen, die Methode `Block.asItem()` verwenden, um die `BlockItem`-Instanz zu erhalten. + +In diesem Beispiel wird eine benutzerdefinierte Itemgruppe verwendet, die auf der Seite [Benutzerdefinierte Itemgruppe](../items/custom-item-groups) erstellt wurde. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Du solltest nun feststellen, dass sich dein Block im Kreativ-Inventar befindet und in der Welt platziert werden kann! + +![Block in der Welt ohne passendes Modell oder Textur](/assets/develop/blocks/first_block_0.png) + +Es gibt jedoch ein paar Probleme - das Blockitem ist nicht benannt, und der Block hat keine Textur, kein Blockmodell und kein Itemmodell. + +## Blockübersetzungen hinzufügen {#adding-block-translations} + +Um eine Übersetzung hinzuzufügen, musst du einen Übersetzungsschlüssel in deiner Übersetzungsdatei erstellen - `assets//lang/en_us.json`. + +Minecraft verwendet diese Übersetzung im Kreativ-Inventar und an anderen Stellen, an denen der Blockname angezeigt wird, wie z. B. bei der Befehlsrückmeldung. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +Du kannst entweder das Spiel neu starten oder deinen Mod erstellen und F3+T drücken, um die Änderungen zu übernehmen - und du solltest sehen, dass der Block einen Namen im kreativen Inventar und an anderen Stellen wie dem Statistikbildschirm hat. + +## Modelle und Texturen {#models-and-textures} + +Alle Blocktexturen befinden sich im Ordner `assets//textures/block` - eine Beispieltextur für den Block "Condensed Dirt" ist frei verwendbar. + +Texturen + +Damit die Textur im Spiel angezeigt wird, musst du einen Block und ein Itemmodell erstellen, die du an den entsprechenden Stellen für den "Condensed Dirt"-Block finden kannst: + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +Das Itemmodell ist ziemlich einfach, es kann einfach das Blockmodell als Elternteil verwenden - da die meisten Blockmodelle Unterstützung für die Darstellung in einer grafischen Benutzeroberfläche haben: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +Das Blockmodell muss jedoch in unserem Fall dem Modell `block/cube_all` übergeordnet sein: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +Wenn du das Spiel lädst, wirst du feststellen, dass die Textur noch fehlt. Dies liegt daran, dass du eine Blockzustand-Definition hinzufügen musst. + +## Eine Blockzustandsdefinition erstellen {#creating-the-block-state-definition} + +Die Blockzustand-Definition wird verwendet, um dem Spiel mitzuteilen, welches Modell je nach dem aktuellen Zustand des Blocks gerendert werden soll. + +Für den Beispielblock, der keinen komplexen Blockzustand hat, ist nur ein Eintrag in der Definition erforderlich. + +Diese Datei sollte sich im Ordner `assets/mod_id/blockstates` befinden, und ihr Name sollte mit der Block-ID übereinstimmen, die bei der Registrierung des Blocks in der Klasse `ModBlocks` verwendet wurde. Wenn die Block-ID beispielsweise `condensed_dirt` lautet, sollte die Datei `condensed_dirt.json` heißen. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +Blockzustände sind sehr komplex, weshalb sie auf einer späteren Seite behandelt werden: [Blockzustände](./blockstates) + +Starte das Spiel neu oder lade es über F3+T neu, um die Änderungen zu übernehmen - Du solltest die Blocktextur im Inventar und physisch in der Welt sehen können: + +![Block in der Welt mit einer passenden Textur und Modell](/assets/develop/blocks/first_block_4.png) + +## Blockdrops hinzufügen {#adding-block-drops} + +Wenn man den Block im Survival-Modus abbaut, kann es sein, dass der Block nicht fallen gelassen wird - diese Funktionalität ist vielleicht erwünscht, aber um den Block als Item fallen zu lassen, wenn er abgebaut wird, muss man seine Beutetabelle implementieren - die Beutetabellendatei sollte in den Ordner `data//loot_table/blocks/` abgelegt werden. + +:::info +Für ein besseres Verständnis der Beutetabellen kannst du dir die Seite [Minecraft Wiki - Beutetabellen](https://de.minecraft.wiki/w/Beutetabellen) ansehen. +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +Diese Beutetabelle enthält einen einzelnen Gegenstand, der fallen gelassen wird, wenn der Block abgebaut wird und wenn er durch eine Explosion gesprengt wird. + +## Ein Abbauwerkzeug vorschlagen {#recommending-a-harvesting-tool} + +Vielleicht möchtest du auch, dass dein Block nur mit einem bestimmten Werkzeug abgebaut werden kann - zum Beispiel möchtest du, dass dein Block schneller mit einer Schaufel abgebaut werden kann. + +Alle Tool-Tags sollten im Ordner `data/minecraft/tags/block/mineable/` abgelegt werden - der Name der Datei hängt von der Art des verwendeten Tools ab, einer der folgenden: + +- `hoe.json` +- `axe.json` +- `pickaxe.json` +- `shovel.json` + +Der Inhalt der Datei ist recht einfach - es handelt sich um eine Liste von Elementen, die dem Tag hinzugefügt werden sollen. + +In diesem Beispiel wird der Block "Condensed Dirt" zum Tag `shovel` hinzugefügt. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +Wenn du möchtest, dass ein Tool zum Abbau des Blocks erforderlich ist, musst du die Blockeinstellungen um den Zusatz `.requiresTool()` erweitern und das entsprechende Mining-Tag hinzufügen. + +## Abbauebene {#mining-levels} + +Ähnlich verhält es sich mit dem Mining-Level-Tag, das im Ordner `data/minecraft/tags/block/` zu finden ist und das folgende Format hat: + +- `needs_stone_tool.json` - Eine minimale Ebene für Steinwerkzeuge. +- `needs_iron_tool.json` - Eine minimale Ebene für Eisenwerkzeuge. +- `needs_diamond_tool.json` - Eine minimale Ebene für Diamantwerkzeuge. + +Die Datei hat das gleiche Format wie die Datei des Abbauwerkzeuges - eine Liste von Items, die dem Tag hinzugefügt werden sollen. + +## Zusatz Notizen {#extra-notes} + +Wenn du mehrere Blöcke zu deinem Mod hinzufügst, solltest du die [Datengenerierung](https://fabricmc.net/wiki/tutorial:datagen_setup) in Betracht ziehen, um den Prozess der Erstellung von Block- und Itemmodellen, Blockzustandsdefinitionen und Beutetabellen zu automatisieren. diff --git a/versions/1.21/translated/de_de/develop/codecs.md b/versions/1.21/translated/de_de/develop/codecs.md new file mode 100644 index 000000000..2cdf7a753 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/codecs.md @@ -0,0 +1,399 @@ +--- +title: Codecs +description: Ein umfassender Leitfaden zum Verständnis und zur Verwendung von Mojangs Codec-System zum Serialisieren und Deserialisieren von Objekten. +authors: + - enjarai + - Syst3ms +--- + +# Listen {#codecs} + +Ein Codec ist ein System zur einfachen Serialisierung von Java-Objekten und ist in Mojangs DataFixerUpper (DFU) +Bibliothek enthalten, die in Minecraft enthalten ist. In einem Modding-Kontext können sie als Alternative zu GSON und Jankson verwendet werden, wenn man benutzerdefinierte JSON-Dateien liest und schreibt, wobei sie mehr und mehr an Bedeutung gewinnen, da Mojang eine Menge alten Code umschreibt, um Codecs zu verwenden. + +Codecs werden in Verbindung mit einer anderen API von DFU, `DynamicOps`, verwendet. Ein Codec definiert die Struktur eines Objekts, während dynamische Ops verwendet werden, um ein Format zu definieren, in das und aus dem serialisiert werden soll, zum Beispiel JSON oder NBT. Das bedeutet, dass jeder Codec mit allen dynamischen Ops verwendet werden kann und umgekehrt, was eine große Flexibilität ermöglicht. + +## Verwenden von Codecs {#using-codecs} + +### Serialisierung und Deserialisierung {#serializing-and-deserializing} + +Die grundlegende Verwendung eines Codecs ist die Serialisierung und Deserialisierung von Objekten in und aus einem bestimmten Format. + +Da einige Vanilla-Klassen bereits Codecs definiert haben, können wir diese als Beispiel verwenden. Mojang hat uns außerdem standardmäßig zwei dynamische Ops-Klassen zur Verfügung gestellt, `JsonOps` und `NbtOps`, die die meisten Anwendungsfälle abdecken. + +Nehmen wir nun an, wir wollen eine `BlockPos` nach JSON und zurück serialisieren. Wir können dies machen, indem wir den Codec, der statisch in `BlockPos.CODEC` gespeichert ist, mit den Methoden `Codec#encodeStart` bzw. + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// Serialisieren der BlockPos zu einem JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +Bei Verwendung eines Codecs werden die Werte in Form eines `DataResult` zurückgegeben. Dies ist ein Wrapper, der entweder einen Erfolg oder einen Misserfolg darstellen kann. Wir können dies auf verschiedene Weise nutzen: Wenn wir nur unseren serialisierten Wert haben wollen, gibt `DataResult#result` einfach ein `Optional` zurück, das unseren Wert enthält, während `DataResult#resultOrPartial` uns auch die Möglichkeit gibt, eine Funktion zu liefern, die eventuell aufgetretene Fehler behandelt. Letzteres ist besonders nützlich für benutzerdefinierte Datapack-Ressourcen, bei denen wir Fehler protokollieren wollen, ohne dass sie an anderer Stelle Probleme verursachen. + +Nehmen wir also unseren serialisierten Wert und verwandeln ihn zurück in eine `BlockPos`: + +```java +// Wenn du einen Mod schreibst, musst du natürlich mit leeren Optionals richtig umgehen +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Hier haben wir unseren JSON-Wert, der `[1, 2, 3]` entsprechen sollte, +// da dies das vom BlockPos-Codec verwendete Format ist. +LOGGER.info("Serialized BlockPos: {}", json); + +// Jetzt werden wir wir das JsonElement zurück in eine BlockPos deserialisieren +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// Auch hier holen wir uns den Wert einfach aus dem Ergebnis +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Und wir können sehen, dass wir unsere BlockPos erfolgreich serialisiert und deserialisiert haben! +LOGGER.info("Deserialized BlockPos: {}", pos); +``` + +### Eingebaute Codecs {#built-in-codecs} + +Wie bereits erwähnt, hat Mojang bereits Codecs für mehrere Vanilla- und Standard-Java-Klassen definiert, einschließlich, aber nicht beschränkt auf `BlockPos`, `BlockState`, `ItemStack`, `Identifier`, `Text` und Regex `Pattern`. Codecs für Mojangs eigene Klassen sind normalerweise als statische Attribute mit dem Namen `CODEC` in der Klasse selbst zu finden, während die meisten anderen in der Klasse `Codecs` untergebracht sind. Es sollte auch beachtet werden, dass alle Vanilla-Registries eine `getCodec()`-Methode enthalten, zum Beispiel kann man `Registries.BLOCK.getCodec()` verwenden, um einen `Codec` zu erhalten, der in die Block-ID und zurück serialisiert wird. + +Die Codec API selbst enthält auch einige Codecs für primitive Typen wie `Codec.INT` und `Codec.STRING`. Diese sind als statische Attribute der Klasse "Codec" verfügbar und werden in der Regel als Basis für komplexere Codecs verwendet, wie im Folgenden erläutert. + +## Erstellen von Codecs {#building-codecs} + +Nachdem wir nun gesehen haben, wie man Codecs verwendet, wollen wir uns ansehen, wie wir unsere eigenen erstellen können. Angenommen, wir haben die folgende Klasse und wollen Instanzen davon aus JSON-Dateien deserialisieren: + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +Die entsprechende JSON-Datei könnte etwa so aussehen: + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +Wir können einen Codec für diese Klasse erstellen, indem wir mehrere kleinere Codecs zu einem größeren zusammenfügen. In diesem Fall brauchen wir einen für jedes Feld: + +- ein `Codec` +- ein `Codec` +- ein `Codec>` + +Den ersten können wir aus den oben erwähnten primitiven Codecs in der Klasse `Codec` beziehen, insbesondere aus `Codec.INT`. Der zweite kann aus dem Register `Registries.ITEM` bezogen werden, das eine Methode `getCodec()` hat, die einen `Codec` zurückgibt. Wir haben keinen Standard-Codec für `List`, aber wir können einen aus `BlockPos.CODEC` erstellen. + +### Listen {#lists} + +`Codec#listOf` kann verwendet werden, um eine Listenversion eines beliebigen Codecs zu erstellen: + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +Es sollte beachtet werden, dass Codecs, die auf diese Weise erstellt werden, immer in eine `ImmutableList` deserialisiert werden. Wenn du stattdessen eine veränderbare Liste benötigst, kannst du [xmap](#wechselseitig-konvertierbare-typen) verwenden, um sie während der Deserialisierung in eine solche zu konvertieren. + +### Zusammenführung von Codecs für Record-ähnliche Klassen {#merging-codecs-for-record-like-classes} + +Da wir nun für jedes Feld einen eigenen Codec haben, können wir sie mit einem `RecordCodecBuilder` zu einem Codec für unsere Klasse kombinieren. Dies setzt voraus, dass unsere Klasse einen Konstruktor hat, der jedes Feld enthält, das wir serialisieren wollen, und dass jedes Feld eine entsprechende Getter-Methode hat. Dies macht es perfekt für die Verwendung in Verbindung mit Records, aber es kann auch mit normalen Klassen verwendet werden. + +Schauen wir uns an, wie wir einen Codec für unsere `CoolBeansClass` erstellen können: + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // Hier können bis zu 16 Attribute deklariert werden +).apply(instance, CoolBeansClass::new)); +``` + +Jede Zeile in der Gruppe gibt einen Codec, einen Attributname und eine Getter-Methode an. Der Aufruf `Codec#fieldOf` wird verwendet, um den Codec in einen [MapCodec](#mapcodec) zu konvertieren, und der Aufruf `forGetter` spezifiziert die Getter-Methode, die verwendet wird, um den Wert des Attributs von einer Instanz der Klasse abzurufen. In der Zwischenzeit gibt der Aufruf `apply` den Konstruktor an, der zur Erzeugung neuer Instanzen verwendet wird. Beachte, dass die Reihenfolge der Attribute in der Gruppe dieselbe sein sollte wie die Reihenfolge der Argumente im Konstruktor. + +Du kannst auch `Codec#optionalFieldOf` in diesem Zusammenhang verwenden, um ein Feld optional zu machen, wie in dem Abschnitt [Optionale Attribute](#optionale-attribute) erklärt. + +### MapCodec, nicht zu verwechseln mit Codec&lt;Map&gt; {#mapcodec} + +Der Aufruf von `Codec#fieldOf` wird einen `Codec` in einen `MapCodec` umwandeln, der eine Variante, aber keine direkte Implementierung von `Codec` ist. `MapCodec`s werden, wie ihr Name schon sagt, garantiert in eine Schlüssel-zu-Wert-Map oder deren Äquivalent in den verwendeten `DynamicOps` serialisiert. Einige Funktionen können einen solchen Codec über einen normalen Codec erfordern. + +Diese besondere Art der Erstellung eines `MapCodec` verpackt im Wesentlichen den Wert des Quellcodecs in eine Map ein, wobei der angegebene Attributname als Schlüssel dient. Zum Beispiel würde ein `Codec`, wenn er in JSON serialisiert wird, wie folgt aussehen: + +```json +[1, 2, 3] +``` + +Bei der Umwandlung in einen `MapCodec` unter Verwendung von `BlockPos.CODEC.fieldOf("pos")` würde es jedoch wie folgt aussehen: + +```json +{ + "pos": [1, 2, 3] +} +``` + +Während die gebräuchlichste Verwendung für Map-Codecs darin besteht, mit anderen Map-Codecs zusammengeführt zu werden, um einen Codec für eine ganze Klasse von Felder zu konstruieren, wie im Abschnitt [Zusammenführung von Codecs für Record-ähnliche Klassen](#Zusammenführung-von-Codecs-für-Record-ähnliche-Klassen) oben erklärt wurde, können sie auch mit `MapCodec#codec` in reguläre Codecs zurückverwandelt werden, die das gleiche Verhalten beibehalten, nämlich ihren Eingabewert verpacken. + +#### Optionale Felder {#optional-fields} + +`Codec#optionalFieldOf` kann verwendet werden, um einen optionalen Mapcodec zu erstellen. Wenn das angegebene Feld bei der Deserialisierung nicht im Container vorhanden ist, wird es entweder als leeres `Optional` oder als angegebener Standardwert deserialisiert. + +```java +// Ohne einem Standardwert +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// Mit einem Standardwert +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +Beachte, dass optionale Felder alle Fehler, die bei der Deserialisierung auftreten können, ignorieren. Das heißt, wenn das Feld vorhanden ist, aber der Wert ungültig ist, wird das Feld immer als Standardwert deserialisiert. + +**Seit 1.20.2**, Minecraft selbst (nicht DFU!) bietet jedoch `Codecs#createStrictOptionalFieldCodec`, das die Deserialisierung fehlschlägt, wenn der Feldwert ungültig ist. + +### Konstanten, Beschränkungen und Komposition {#constants-constraints-composition} + +#### Einheit {#unit} + +`Codec.unit` kann verwendet werden, um einen Codec zu erstellen, der immer zu einem konstanten Wert deserialisiert, unabhängig von der Eingabe. Bei der Serialisierung wird nichts getan. + +```java +Codec theMeaningOfCodec = Codec.unit(42); +``` + +#### Zahlenbereiche {#numeric-ranges} + +`Codec.intRange` und seine Kollegen `Codec.floatRange` und `Codec.doubleRange` können verwendet werden, um einen Codec zu erstellen, der nur Zahlenwerte innerhalb eines bestimmten **inklusiven** Bereichs akzeptiert. Dies gilt sowohl für die Serialisierung als auch für die Deserialisierung. + +```java +// Kann nicht mehr als 2 sein +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Paar {#pair} + +`Codec.pair` fasst zwei Codecs, `Codec
` und `Codec`, zu einem `Codec` zusammen. Denk daran, dass dies nur richtig mit Codecs funktioniert, die in ein bestimmtes Attribut serialisiert werden, wie zum Beispiel [konvertierte `MapCodec`s](#mapcodec) oder [Record Codecs](#Zusammenführung-von-Codecs-für-Record-ähnliche-Klassen). +Der resultierende Codec wird zu einer Map serialisiert, die die Attribute der beiden verwendeten Codecs kombiniert. + +Beispielsweise wird beim Ausführen dieses Codes: + +```java +// Erstellen von zwei separaten verpackten Codecs +Codec firstCodec = Codec.INT.fieldOf("i_am_number").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("this_statement_is_false").codec(); + +// Sie zu einem Paar-Codec zusammenführen +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// Zum Serialisieren von Daten verwenden +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +Folgendes JSON generiert: + +```json +{ + "i_am_number": 23, + "this_statement_is_false": true +} +``` + +#### Either {#either} + +`Codec.either` kombiniert zwei Codecs, `Codec` und `Codec`, zu einem `Codec>`. Der resultierende Codec wird bei der Deserialisierung versuchen, den ersten Codec zu verwenden, und _nur wenn das fehlschlägt_, versuchen, den zweiten Codec zu verwenden. +Wenn der zweite Codec ebenfalls fehlschlägt, wird der Fehler des _zweiten_ Codecs zurückgegeben. + +#### Maps {#maps} + +Für die Verarbeitung von Maps mit beliebigen Schlüsseln, wie zum Beispiel `HashMap`s, kann `Codec.unboundedMap` verwendet werden. Dies gibt einen `Codec>` für einen gegebenen `Codec` und `Codec` zurück. Der resultierende Codec wird zu einem JSON-Objekt serialisiert oder oder ein gleichwertiges Objekt, das für die aktuellen dynamische Ops verfügbar ist. + +Aufgrund der Einschränkungen von JSON und NBT _muss_ der verwendete Schlüsselcodec zu einer Zeichenkette serialisiert werden. Dazu gehören auch Codecs für Typen, die selbst keine Strings sind, aber zu ihnen serialisiert werden, wie zum Beispiel `Identifier.CODEC`. Siehe folgendes Beispiel: + +```java +// Erstellen eines Codecs für eine Abbildung von Bezeichnern auf Ganzzahlen +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// Zum Serialisieren von Daten verwenden +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "number"), 23, + new Identifier("example", "the_cooler_number"), 42 +)); +``` + +Dadurch wird dieses JSON ausgegeben: + +```json +{ + "example:number": 23, + "example:the_cooler_number": 42 +} +``` + +Wie du sehen kannst, funktioniert dies, weil `Identifier.CODEC` direkt zu einem String-Wert serialisiert wird. Einen ähnlichen Effekt kann man für einfache Objekte, die nicht in Strings serialisiert werden, erreichen, indem [Wechselseitig konvertierbare Typen](#wechselseitig-konvertierbare-typen) verwendet werden, um um sie zu konvertieren. + +### Wechselseitig konvertierbare Typen {#mutually-convertible-types} + +#### `xmap` {#xmap} + +Angenommen, wir haben zwei Klassen, die ineinander umgewandelt werden können, aber keine Eltern-Kind-Beziehung haben. Zum Beispiel, eine einfache `BlockPos` und `Vec3d`. Wenn wir einen Codec für eine Richtung haben, können wir mit `Codec#xmap` einen Codec für die andere Richtung erstellen, indem wir eine Konvertierungsfunktion für jede Richtung angeben. + +B`BlockPos` hat bereits einen Codec, aber tun wir mal so, als ob er keinen hätte. Wir können einen solchen Codec erstellen, indem wir ihn auf den Codec für `Vec3d` stützen, etwa so: + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // Konvertiert Vec3d zu BlockPos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // Konvertiert BlockPos zu Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// Bei der Konvertierung einer bestehenden Klasse (zum Beispiel `X`) +// in deine eigene Klasse (`Y`), kann es sinnvoll sein +// die Methode `toX` und die statische Methode `fromX` zu `Y` und +// Methodenreferenzen in deinem `xmap`-Aufruf hinzufügen. +``` + +#### flatComapMap, comapFlatMap und flatXMap {#flatcomapmap-comapflatmap-flatxmap} + +`Codec#flatComapMap`, `Codec#comapFlatMap` und `flatXMap` sind ähnlich wie xmap, erlauben aber, dass eine oder beide der Konvertierungsfunktionen ein DataResult zurückgeben. Dies ist in der Praxis nützlich, da eine bestimmte Objektinstanz möglicherweise nicht nicht immer für die Konvertierung gültig ist. + +Nimm zum Beispiel Vanille `Identifier` her. Während alle Bezeichner in Zeichenketten umgewandelt werden können, sind nicht alle Zeichenketten gültige Bezeichner, Daher würde die Verwendung von xmap hässliche Exceptions werfen, wenn die Umwandlung fehlschlägt. +Aus diesem Grund ist der eingebaute Codec eigentlich eine `comapFlatMap` auf `Codec.STRING`, was sehr schön veranschaulicht, wie man ihn verwendet: + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Not a valid resource location: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +Diese Methoden sind zwar sehr hilfreich, aber ihre Namen sind etwas verwirrend, deshalb hier eine Tabelle, damit du merken kannst, welche zu verwenden ist: + +| Methode | A -> B immer gültig? | B -> A immer gültig? | +| ----------------------- | -------------------- | -------------------- | +| `Codec#xmap` | Ja | Ja | +| `Codec#comapFlatMap` | Nein | Ja | +| `Codec#flatComapMap` | Ja | Nein | +| `Codec#flatXMap` | Nein | Nein | + +### Registry Dispatch {#registry-dispatch} + +`Codec#dispatch` ermöglicht die Definition eines Registry von Codecs und die Abfertigung eines bestimmten Codecs auf der Grundlage des Wertes eines +Attributs in den serialisierten Daten. Dies ist sehr nützlich bei der Deserialisierung von Objekten, die je nach Typ unterschiedliche Attribute haben, aber dennoch dasselbe Objekt darstellen. + +Nehmen wir an, wir haben ein abstraktes `Bean`-Interface mit zwei implementierenden Klassen: `StringyBean` und `CountingBean`. Um diese mit einem Registry Dispatch zu serialisieren, benötigen wir einige Dinge: + +- Separate Codecs für jede Art von Bohnen. +- Eine `BeanType`-Klasse oder ein Datensatz, der den Typ der Bohne repräsentiert und den Codec für sie zurückgeben kann. +- Eine Funktion für `Bean` zum Abrufen ihres `BeanType`. +- Eine Map oder Registry, um `Identifier` auf `BeanType` abzubilden. +- Ein `Codec>`, der auf dieser Registry basiert. Wenn du eine `net.minecraft.registry.Registry` verwendest, kann eine solche einfach mit `Registry#getCodec` erstellt werden. + +Mit all dem können wir einen Registry Dispatch Codec für Bohnen erstellen: + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// Jetzt können wir einen Codec für Bohnen-Typen erstellen +// basierend auf der zuvor erstellten Registry +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// Und darauf basierend, hier unser Registry Dispatch Codec für Bohnen! +// Das erste Argument ist der Feldname für den Bohnen-Typ. +// Wenn es weggelassen wird, wird sie standardmäßig zu "type". +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::codec); +``` + +Unser neuer Codec serialisiert Bohnen zu JSON und erfasst dabei nur die Felder, die für ihren spezifischen Typ relevant sind: + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "This bean is stringy!" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### Rekursive Codecs {#recursive-codecs} + +Manchmal ist es nützlich, einen Codec zu haben, der _sich selbst_ verwendet, um bestimmte Felder zu dekodieren, zum Beispiel wenn es um bestimmte rekursive Datenstrukturen geht. Im Vanilla-Code wird dies für `Text`-Objekte verwendet, die andere `Text`e als Kinder speichern können. Ein solcher Codec kann mit `Codec#recursive` konstruiert werden. + +Versuchen wir zum Beispiel, eine einfach verknüpfte Liste zu serialisieren. Diese Art der Darstellung von Listen besteht aus einem Bündel von Knoten, die sowohl einen Wert als auch einen Verweis auf den nächsten Knoten in der Liste enthalten. Die Liste wird dann durch ihren ersten Knoten repräsentiert, und das Durchlaufen der Liste erfolgt durch Verfolgen des nächsten Knotens, bis keiner mehr übrig ist. Hier ist eine einfache Implementierung von Knoten, die ganze Zahlen speichern. + +```java +public record ListNode(int value, ListNode next) {} +``` + +Wir können dafür keinen Codec mit normalen Mitteln konstruieren, denn welchen Codec würden wir für das Attribut `next` verwenden? Wir bräuchten einen `Codec`, und den sind wir gerade dabei zu konstruieren! Mit `Codec#recursive` können wir das mit einem magisch aussehendem Lambda erreichen: + +```java +Codec codec = Codec.recursive( + "ListNode", // Ein Name für den Codec + selfCodec -> { + // Hier, repräsentiert `selfCodec` den `Codec`, als wäre er bereits konstruiert + // Dieses Lambda sollte den Codec zurückgeben, den wir von Anfang an verwenden wollten, + // der sich durch `selfCodec` auf sich selbst bezieht + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // das `next` Feld wird rekursiv mit dem Selbstkodierer behandelt + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +Ein serialisierter `ListNode` kann dann wie folgt aussehen: + +```json +{ + "value": 2, + "next": { + "value": 3, + "next": { + "value": 5 + } + } +} +``` + +## Referenzen {#references} + +- Eine viel umfassendere Dokumentation von Codecs und verwandten APIs findest du in der [Inoffiziellen DFU JavaDoc](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec). +- Die allgemeine Struktur dieses Leitfadens wurde stark von dem [Forge Community Wiki's Seiten zu Codecs](https://forge.gemwire.uk/wiki/Codecs) inspiriert, einer eher Forge-spezifischen Darstellung desselben Themas. diff --git a/versions/1.21/translated/de_de/develop/commands/arguments.md b/versions/1.21/translated/de_de/develop/commands/arguments.md new file mode 100644 index 000000000..5d27a41a0 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/commands/arguments.md @@ -0,0 +1,65 @@ +--- +title: Befehlsargumente +description: Lerne, wie man Befehle mit komplexen Parametern erstellt. +--- + +# Befehlsargumente {#command-arguments} + +Parameter werden in den meisten Befehlen verwendet. Manchmal sind sie optional, das heißt, wenn du diesen Parameter nicht angibst, wird der Befehl dennoch ausgeführt. Ein Knoten kann mehrere Parametertypen haben, aber es ist zu beachten, dass die Möglichkeit einer +Mehrdeutigkeit besteht, die vermieden werden sollte. + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +In diesem Fall musst du nach dem Befehlstext `/command_with_arg` eine ganze Zahl eingeben. Wenn du zum Beispiel `/command_with_arg 3` ausführst, erhältst du eine Rückmeldungsnachricht: + +> Aufruf von /command_with_arg mit Wert = 3 + +Wenn du `/command_with_arg` ohne Argumente eingibst, kann der Befehl nicht korrekt geparst werden. + +Dann fügen wir ein optionales zweites Argument hinzu: + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Jetzt kannst du eine oder zwei ganze Zahlen eingeben. Wenn du eine ganze Zahl eingibst, wird ein Feedback-Text mit einem einzigen Wert ausgegeben. Wenn du zwei Ganzzahlen angibst, wird ein Feedback-Text mit zwei Werten ausgegeben. + +Du kannst es unnötig finden, ähnliche Ausführungen zweimal anzugeben. Daher können wir eine Methode erstellen, die in beiden Ausführungen verwendet wird. + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Benutzerdefinierte Argumenttypen {#custom-argument-types} + +Wenn Vanilla nicht den von dir benötigten Argumenttyp verfügt, kannst du deinen eigenen erstellen. Dazu musst du eine Klasse erstellen, die das Interface `ArgumentType` erbt, wobei `T` der Typ des Arguments ist. + +Du musst die Methode "parse" implementieren, die die Eingabezeichenfolge zu dem gewünschten Typ parst. + +Du kannst zum Beispiel einen Argumenttyp erstellen, der eine `BlockPos` aus einer Zeichenkette mit dem folgenden Format parst: `{x, y, z}` + +@[code lang=java highlight={3,5,6,7} transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Benutzerdefinierte Argumenttypen registrieren {#registering-custom-argument-types} + +:::warning +Du musst den benutzerdefinierten Argumenttyp sowohl im Server als auch im Client registrieren, sonst wird der Befehl nicht funktionieren! +::: + +Du kannst deinen benutzerdefinierten Argumenttyp in der Methode `onInitialize` deines [Mod-Initialisierers](./getting-started/project-structure#entrypoints) mit der Klasse `ArgumentTypeRegistry` registrieren: + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Benutzerdefinierte Argumenttypen verwenden {#using-custom-argument-types} + +Wir können unseren benutzerdefinierten Argumenttyp in einem Befehl verwenden, indem wir eine Instanz davon an die Methode `.argument` im Builder des Befehls übergeben. + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Durch das Ausführen des Befehls, können wir testen, ob der Argumenttyp funktioniert oder nicht: + +![Ungültiges Argument](/assets/develop/commands/custom-arguments_fail.png) + +![Gültiges Argument](/assets/develop/commands/custom-arguments_valid.png) + +![Ergebnis des Befehls](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/de_de/develop/commands/basics.md b/versions/1.21/translated/de_de/develop/commands/basics.md new file mode 100644 index 000000000..62d2e6270 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/commands/basics.md @@ -0,0 +1,177 @@ +--- +title: Befehle erstellen +description: Befehle mit komplexen Parametern und Aktionen erstellen. +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple +--- + +# Befehle erstellen {#creating-commands} + +Durch das Erstellen von Befehlen kann ein Mod-Entwickler Funktionen hinzufügen, die durch einen Befehl verwendet werden können. Dieses Tutorial wird dir erklären, wie man Befehle registriert und die allgemeine Befehlsstruktur von Brigadier. + +::: info +Brigadier is a command parser and dispatcher written by Mojang for Minecraft. It is a tree-based command library where +you build a tree of commands and arguments. + +Brigadier ist Open Source: +::: + +## Das Interface `Command` {#the-command-interface} + +`com.mojang.brigadier.Command` ist ein funktionales Interface, das einen bestimmten Code ausführt und in bestimmten Fällen eine `CommandSyntaxException` auslöst. Er hat einen generischen Typ `S`, der den Typ der _Befehlsquelle_ definiert. +Die Befehlsquelle liefert einen Kontext, in dem ein Befehl ausgeführt wurde. In Minecraft ist die Befehlsquelle normalerweise ein `ServerCommandSource`, die einen Server, einen Befehlsblock, eine Remote-Verbindung (RCON), einen Spieler oder eine Entität darstellen kann. + +Die einzige Methode in `Command`, `run(CommandContext)`, nimmt einen `CommandContext` als einzigen Parameter und gibt eine ganze Zahl zurück. Der Befehlskontext enthält die Befehlsquelle von `S` und ermöglicht es dir, Argumente zu erhalten, die geparsten Befehlsknoten zu betrachten und die in diesem Befehl verwendete Eingabe zu sehen. + +Wie andere funktionale Interfaces wird es in der Regel als Lambda oder als Methodenreferenz verwendet: + +```java +Command command = context -> { + return 0; +}; +``` + +Die Ganzzahl kann als Ergebnis des Befehls betrachtet werden. Normalerweise bedeuten Werte kleiner oder gleich Null, dass ein Befehl fehlgeschlagen ist und nichts machen wird. Positive Werte bedeuten, dass der Befehl erfolgreich war und etwas gemacht hat. Brigadier bietet eine Konstante zur Anzeige von Erfolg; `Befehl#SINGLE_SUCCESS`. + +### Was kann die `ServerCommandSource` machen? {#what-can-the-servercommandsource-do} + +Eine "ServerCommandSource" liefert einen zusätzlichen implementierungsspezifischen Kontext, wenn ein Befehl ausgeführt wird. Dazu gehört die Möglichkeit, die Entität, die den Befehl ausgeführt hat, die Welt, in der der Befehl ausgeführt wurde, oder den Server, auf dem der Befehl ausgeführt wurde, zu ermitteln. + +Du kannst auf die Befehlsquelle von einem Befehlskontext aus zugreifen, indem du `getSource()` für die Instanz `CommandContext` aufrufst. + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## Registrieren eines einfachen Befehls {#registering-a-basic-command} + +Befehle werden innerhalb des `CommandRegistrationCallback` registriert, der von der Fabric API bereitgestellt wird. + +:::info +Informationen zur Registrierung von Callbacks findest du in der Anleitung [Events](../events). +::: + +Das Event sollte in deinem [Mod Initialisierer](./getting-started/project-structure#entrypoints) registriert werden. + +Der Callback hat drei Parameter: + +- `CommandDispatcher dispatcher` - Dient zum Registrieren, Parsen und Ausführen von Befehlen. `S` ist der Typ + der Befehlsquelle, die der Command Dispatcher unterstützt. +- `CommandRegistryAccess registryAccess` - Bietet eine Abstraktion zu Registrys, die an bestimmte Befehlsargumente übergeben werden können + Argument-Methoden +- `CommandManager.RegistrationEnvironment environment` - Identifiziert den Typ des Servers, auf dem die Befehle registriert werden. + +Im Mod-Initialisierer registrieren wir nur einen einfachen Befehl: + +@[code lang=java transcludeWith=:::test_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +In der Methode `sendFeedback()` ist der erste Parameter der zu sendende Text, der ein `Supplier` ist, um zu vermeiden, dass Text-Objekte instanziert werden, wenn sie nicht benötigt werden. + +Der zweite Parameter bestimmt, ob die Rückmeldung an andere Operatoren gesendet werden soll. Im Allgemeinen sollte der Befehl `false` sein, wenn er etwas abfragen soll, ohne die Welt tatsächlich zu beeinflussen, wie zum Beispiel die aktuelle Zeit oder den Punktestand eines Spielers. die Zeit zu ändern oder den Spielstand einer Person zu ändern, sollte er `true` sein. + +Wenn der Befehl fehlschlägt, kannst du, anstatt `sendFeedback()` aufzurufen, direkt eine beliebige Ausnahme auslösen, die vom Server oder Client entsprechend behandelt wird. + +Die `CommandSyntaxException` wird im Allgemeinen ausgelöst, um Syntaxfehler in Befehlen oder Argumenten aufzuzeigen. Du kannst auch deine eigene Exception implementieren. + +Um diesen Befehl auszuführen, musst du `/test_command` eingeben, wobei Groß- und Kleinschreibung zu beachten sind. + +:::info +Von diesem Punkt an werden wir die Logik, die innerhalb des Lambdas an den `.execute()`-Builder übergeben wird, in einzelne Methoden extrahieren. Dann können wir eine Methodenreferenz an `.execute()` übergeben. Dies dient der Übersichtlichkeit. +::: + +### Umgebung der Registrierung {#registration-environment} + +Falls gewünscht, kannst du auch dafür sorgen, dass ein Befehl nur unter bestimmten Umständen registriert wird, zum Beispiel nur in der dedizierten Umgebung: + +@[code lang=java highlight={2} transcludeWith=:::dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Befehlsanforderungen {#command-requirements} + +Angenommen, du hast einen Befehl, den nur Operatoren ausführen können sollen. An dieser Stelle kommt die Methode `requires()` ins Spiel. Die Methode `requires()` hat ein Argument eines `Predicate`, das eine `ServerCommandSource` liefert, mit der getestet werden kann, ob die `CommandSource` den Befehl ausführen kann. + +@[code lang=java highlight={3} transcludeWith=:::required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Dieser Befehl wird nur ausgeführt, wenn die Quelle des Befehls mindestens ein Operator der Ebene 2 ist, einschließlich Befehlsblöcke. Andernfalls ist der Befehl nicht registriert. + +Dies hat den Nebeneffekt, dass dieser Befehl in der Tab-Vervollständigung für alle, die nicht Level 2 Operator sind, nicht angezeigt wird. Das ist auch der Grund, warum du die meisten Befehle nicht mit der Tabulatortaste vervollständigen kannst, wenn du keine Cheats aktivierst. + +### Unterbefehle {#sub-commands} + +Um einen Unterbefehl hinzuzufügen, registriere den ersten buchstäblichen Knoten des Befehls ganz normal. Um einen Unterbefehl zu haben, musst du den nächsten buchstäblichen Knoten an den bestehenden Knoten anhängen. + +@[code lang=java highlight={3} transcludeWith=:::sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Ähnlich wie die Argumente können auch die Unterbefehlsknoten auf optional gesetzt werden. Im folgenden Fall sind sowohl `/command_two` als auch `/command_two sub_command_two` gültig. + +@[code lang=java highlight={2,8} transcludeWith=:::sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Client-Befehle {#client-commands} + +Die Fabric API verfügt über einen `ClientCommandManager` im Paket `net.fabricmc.fabric.api.client.command.v2`, der zur Registrierung clientseitiger Befehle verwendet werden kann. Der Code sollte nur im clientseitigen Code vorhanden sein. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## Befehlsumleitungen {#command-redirects} + +Befehlsumleitungen - auch bekannt als Aliase - sind eine Möglichkeit, die Funktionalität eines Befehls auf einen anderen umzuleiten. Dies ist nützlich, wenn du den Namen eines Befehls ändern möchtest, aber den alten Namen beibehalten willst. + +:::warning +Brigadier [wird nur Befehlsknoten mit Argumenten umleiten](https://github.com/Mojang/brigadier/issues/46). Wenn du einen Befehlsknoten ohne Argumente umleiten willst, gib einen `.executes()` Builder mit einem Verweis auf die gleiche Logik wie im Beispiel beschrieben an. +::: + +@[code lang=java transcludeWith=:::redirect_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_redirected_by](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## FAQ {#faq} + +### Warum kompiliert mein Code nicht? {#why-does-my-code-not-compile} + +- Abfangen oder Auslösen einer `CommandSyntaxException` - `CommandSyntaxException` ist keine `RuntimeException`. Wenn du sie auslöst, sollte sie in Methoden ausgelöst werden, die `CommandSyntaxException` in den Methodensignaturen auslösen, oder sie sollte abgefangen werden. + Brigadier wird die checked Exceptions behandeln und die entsprechende Fehlermeldung im Spiel für dich weiterleiten. + +- Probleme mit generischen Typen - Es kann sein, dass du hin und wieder ein Problem mit generischen Typen hast. Wenn du Serverbefehle registrierst (was in den meisten Fällen der Fall ist), stelle sicher, dass du `CommandManager.literal` oder `CommandManager.argument` anstelle von `LiteralArgumentBuilder.literal` oder `RequiredArgumentBuilder.argument` benutzt. + +- Überprüfe die Methode `sendFeedback()` - Du hast vielleicht vergessen, einen booleschen Wert als zweites Argument anzugeben. Denke auch daran dass seit Minecraft 1.20 der erste Parameter `Supplier` anstelle von `Text` ist. + +- Ein Befehl sollte eine ganze Zahl zurückgeben - Bei der Registrierung von Befehlen akzeptiert die Methode `executes()` ein `Command` Objekt, das normalerweise ein Lambda ist. Das Lambda sollte eine ganze Zahl zurückgeben, anstelle anderen Typen. + +### Kann ich Befehle zur Laufzeit registrieren? {#can-i-register-commands-at-runtime} + +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +Danach musst du den Befehlsbaum mit `CommandManager.sendCommandTree(ServerPlayerEntity)` erneut an jeden Spieler senden. + +Dies ist erforderlich, da der Client den Befehlsbaum, den er bei der Anmeldung (oder beim Senden von Operator-Paketen) erhält, lokal zwischenspeichert, um Fehlermeldungen zu vervollständigen. +::: + +### Kann ich die Registrierung von Befehlen während der Laufzeit aufheben? {#can-i-unregister-commands-at-runtime} + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +Um die Dinge einfach zu halten, musst du Reflection auf Brigadier anwenden und Knoten entfernen. Danach musst du den Befehlsbaum erneut an jeden Spieler mit `sendCommandTree(ServerPlayerEntity)` senden. + +Wenn du den aktualisierten Befehlsbaum nicht sendest, kann es sein, dass der Client denkt, dass der Befehl noch existiert, obwohl die Ausführung am Server fehlschlägt. +::: diff --git a/versions/1.21/translated/de_de/develop/commands/suggestions.md b/versions/1.21/translated/de_de/develop/commands/suggestions.md new file mode 100644 index 000000000..b7b027ba2 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/commands/suggestions.md @@ -0,0 +1,49 @@ +--- +title: Befehlsvorschläge +description: Lerne, wie man Spielern Werte für Befehlsargumente vorschlagen kann. +authors: + - IMB11 +--- + +# Befehlsvorschläge {#command-suggestions} + +Minecraft hat ein mächtiges System für Befehlsvorschläge, das an vielen Stellen verwendet wird, wie zum Beispiel beim Befehl `/give`. Mit diesem System kannst du dem Spieler Werte für Befehlsargumente vorschlagen, aus denen er dann auswählen kann - eine großartige Möglichkeit, um deine Befehle benutzerfreundlicher und ergonomischer zu gestalten. + +## Vorschlaganbieter {#suggestion-providers} + +Ein `SuggestionProvider` wird verwendet, um eine Liste von Vorschlägen zu erstellen, die an den Spieler gesendet werden. Ein Vorschlaganbieter ist eine funktionales Interface, das einen `CommandContext` und einen `SuggestionBuilder` entgegennimmt und einige `Suggestions` zurückgibt. Der `SuggestionProvider` gibt ein `CompletableFuture` zurück, da die Vorschläge möglicherweise nicht sofort verfügbar sind. + +## Verwenden von Vorschlaganbietern {#using-suggestion-providers} + +Um einen Vorschlaganbieter zu verwenden, musst du die Methode `suggests` auf dem Argument Builder aufrufen. Diese Methode nimmt einen `SuggestionProvider` und gibt den geänderten Argument Builder mit dem angehängten Suggestion Provider zurück. + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Eingebaute Vorschlaganbieter {#built-in-suggestion-providers} + +Es gibt einige eingebaute Vorschlaganbieter, du verwenden kannst: + +| Vorschlaganbieter | Beschreibung | +| ----------------------------------------- | ------------------------------------------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | Schläft alle Entitäten vor, die beschworen werden können. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | Schlägt alle Klänge vor, die abgespielt werden können. | +| `LootCommand.SUGGESTION_PROVIDER` | Zeigt alle verfügbaren Loottabellen an. | +| `SuggestionProviders.ALL_BIOMES` | Schlägt alle Biome vor, die verfügbar sind. | + +## Erstellen eines benutzerdefinierten Vorschlagsanbieters {#creating-a-custom-suggestion-provider} + +Wenn ein eingebauter Anbieter deine Anforderungen nicht erfüllt, kannst du einen eigenen Vorschlaganbieter erstellen. Zu diesem Zweck musst du eine Klasse erstellen, die das Interface `SuggestionProvider` implementiert und die Methode `getSuggestions` überschreibt. + +In diesem Beispiel erstellen wir einen Vorschlaganbieter, der alle Benutzernamen der Spieler auf dem Server vorschlägt. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +Um diesen Vorschlaganbieter zu verwenden, übergebe einfach eine Instanz davon an die Methode `.suggests` im Argument Builder. + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Natürlich können die Anbieter von Vorschlägen komplexer sein, da sie auch den Befehlskontext lesen können, um Vorschläge zu machen, die auf dem Zustand des Befehls basieren - zum Beispiel auf den Argumenten, die bereits angegeben wurden. + +Dies könnte in Form von Lesen des Inventars des Spielers und Vorschlagen von Gegenständen oder Entitäten, die sich in der Nähe des Spielers befinden, geschehen. diff --git a/versions/1.21/translated/de_de/develop/data-generation/advancements.md b/versions/1.21/translated/de_de/develop/data-generation/advancements.md new file mode 100644 index 000000000..4876ba9e9 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/data-generation/advancements.md @@ -0,0 +1,167 @@ +--- +title: Generierung von Fortschritten +description: Ein Leitfaden zur Einrichtung der Generierung von Fortschritten mit dem Datengenerator. +authors: + - skycatminepokie + - MattiDragon + - Spinoscythe +authors-nogithub: + - jmanc3 + - mcrafterzz +--- + +# Generierung von Fortschritten {#advancement-generation} + +:::info VORAUSSETZUNGEN +Stelle sicher, dass du den Prozess der [Einrichtung der Datengenerierung](./setup) zuerst abgeschlossen hast. +::: + +## Einrichten {#setup} + +Zuerst müssen wir unseren Provider erstellen. Erstelle eine Klasse, die `extends FabricAdvancementProvider` beinhaltet und fülle die Basismethoden aus: + +@[code lang=java transcludeWith=:::datagen-advancements:provider-start](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Um die Einrichtung abzuschließen, füge den Provider zu deinem `DataGeneratorEntrypoint` in der `onInitializeDataGenerator` Methode hinzu. + +@[code lang=java transclude={24-24}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Struktur eines Fortschritts {#advancement-structure} + +Ein Fortschritt setzt sich aus mehreren Komponenten zusammen. Neben den Voraussetzungen, auch als "Kriterien" bezeichnet, kann er auch folgendes haben: + +- Ein `AdvancementDisplay`, das dem Spiel mitteilt, wie der Fortschritt den Spielern angezeigt werden soll, +- `AdvancementRequirements`, bei denen es sich um Listen von Kriterien handelt, von denen mindestens ein Kriterium aus jeder Teilliste erfüllt sein muss, +- `AdvancementRewards`, die der Spieler für den Abschluss des Fortschritts erhält. +- Ein `CriterionMerger`, der dem Fortschritt mitteilt wie er mehrere Kriterien verarbeiten soll, und +- Ein übergeordnetes `Advancement`, das die Hierachie organisiert, welche du in dem "Fortschritt" Fenster sehen kannst. + +## Einfacher Fortschritt {#simple-advancements} + +Hier ist ein einfacher Fortschritt, um einen Erdblock zu erhalten: + +@[code lang=java transcludeWith=:::datagen-advancements:simple-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +:::details JSON Ausgabe +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/fabric-docs-reference/get_dirt.json) +::: + +## Ein weiteres Beispiel {#one-more-example} + +Um den Dreh raus zu bekommen, fügen wir noch einen weiteren Fortschritt hinzu. Wir üben das Hinzufügen von Belohnungen, die Verwendung mehrerer Kriterien und die Zuweisung von Eltern: + +@[code lang=java transcludeWith=:::datagen-advancements:second-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Vergiss nicht, sie zu generieren! Nutze den untenstehenden Terminal-Befehl oder die Laufkonfiguration in IntelliJ. + +::: code-group + +```sh [Windows] +gradlew runDatagen +``` + +```sh [Linux] +./gradlew runDatagen +``` + +::: + +## Benutzdefinierte Kriterien {#custom-criteria} + +:::warning +Während der Datengenerator auf der Client-Seite liegen kann, befinden sich `Criterion`s und `Predicate`s im Hauptquellenverzeichnis (beide Seiten), da der Server sie auslösen und auswerten muss. +::: + +### Definition {#definitions} + +Ein **Kriterium** (Plural: Kriterien) ist etwas, was Spieler machen können (oder was einem Spieler passieren kann) was möglicherweise einem Fortschritt angerechnet wird. Das Spiel kommt mit vielen [Kriterien](https://minecraft.wiki/w/Advancement_definition#List_of_triggers), welche in dem `net.minecraft.advancement.criterion` Packet gefunden werden können. Generell musst du nur ein neues Kriterium hinzufügen, wenn du eine benutzdefinierte Mechanik zum Spiel hinzufügst. + +**Bedingungen** werden von Kriterien ausgewertet. Ein Kriterium wird nur gezählt, wenn alle relevanten Bedingungen zutreffen. Bedingungen werden in der Regel durch ein Prädikat ausgedrückt. + +Ein **Prädikat** ist etwas, das einen Wert entgegennimmt und einen `boolean` zurück gibt. Zum Beispiel, ein `Predicate` gibt möglicherweise `true` zurück, wenn das Item ein Diamant ist, während ein `Predicate` möglicherweise `true` zurückgibt, wenn die Entität nicht gegenüber einem Dorfbewohner feindlich gesinnt ist. + +### Erstellen von benutzdefinierten Kriterien {#creating-custom-criteria} + +Zuerst müssen wir eine neue Mechanik implementieren. Wir können dem Spieler jedes Mal, wenn er einen Block abbaut, mitteilen, welches Werkzeug er benutzt hat. + +@[code lang=java transcludeWith=:::datagen-advancements:entrypoint](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Beachte, dass dieser Code wirklich schlecht ist. Die `HashMap` wird nirgendwo dauerhaft gespeichert, daher wird sie bei jedem Neustart des Spiels zurückgesetzt. Es geht nur darum, `Criterion`s aufzuzeigen. Starte das Spiel und teste es! + +Als Nächstes erstellen wir unser benutzerdefiniertes Kriterium `UseToolCriterion`. Es wird seine eigene Klasse `Conditions` benötigen, also werden wir beide auf einmal erstellen: + +@[code lang=java transcludeWith=:::datagen-advancements:criterion-base](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Puh, das ist eine Menge! Schauen wir uns das mal genauer an. + +- `UseToolCriterion` ist ein `AbstractCriterion`, auf das `Conditions` angewendet werden können. +- `Conditions` hat ein `playerPredicate` Feld. Alle `Conditions` sollten ein Spielerprädikat haben (technisch gesehen ein `LootContextPredicate`). +- `Conditions` haben auch einen `CODEC`. Dieser `Codec` ist einfach der Codec für sein einziges Feld, `playerPredicate`, mit zusätzlichen Anweisungen zur Konvertierung zwischen ihnen (`xmap`). + +:::info +Um mehr über Codecs zu erfahren, sieh dir die [Codecs](../codecs) Seite an. +::: + +Wir brauchen einen Weg, um zu überprüfen, ob Bedingungen erfüllt sind. Lasst uns eine Hilfsmethode zu `Conditions` hinzufügen: + +@[code lang=java transcludeWith=:::datagen-advancements:conditions-test](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Da wir nun ein Kriterium und seine Bedingungen haben, brauchen wir eine Möglichkeit, es auszulösen. Füge eine Auslösungsmethode zu `UseToolCriterion` hinzu: + +@[code lang=java transcludeWith=:::datagen-advancements:criterion-trigger](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Fast geschafft! Als nächstes benötigen wir eine Instanz unseres Kriteriums, mit der wir arbeiten können. Fügen wir sie in eine neue Klasse mit dem Namen `ModCriteria` ein. + +@[code lang=java transcludeWith=:::datagen-advancements:mod-criteria](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +Um sicherzustellen, dass unsere Kriterien zum richtigen Zeitpunkt initialisiert werden, füge eine leere `init`-Methode hinzu: + +@[code lang=java transcludeWith=:::datagen-advancements:mod-criteria-init](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +Und rufe es in deinem Mod-Initialisierer auf: + +@[code lang=java transcludeWith=:::datagen-advancements:call-init](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Schließlich müssen wir unsere Kriterien auslösen. Füge dies zu der Stelle hinzu, an der wir in der Hauptmodklasse eine Nachricht an den Spieler geschickt haben. + +@[code lang=java transcludeWith=:::datagen-advancements:trigger-criterion](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Dein neues Kriterium ist jetzt einsatzbereit! Lasst es uns zu unserem provider hinzufügen: + +@[code lang=java transcludeWith=:::datagen-advancements:custom-criteria-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Führe den Datengenerator Task erneut aus und du hast einen neuen Fortschritt bekommen, mit dem du spielen kannst! + +## Bedingungen mit Parametern {#conditions-with-parameters} + +Das ist alles schön und gut, aber was ist, wenn wir einen Fortschritt nur dann gewähren wollen, wenn wir etwas fünfmal getan haben? Und warum nicht noch einen bei zehn Mal? Hierfür müssen wir unserer Bedingung einen Parameter geben. Du kannst bei `UseToolCriterion` bleiben, oder du kannst mit einem neuen `ParameterizedUseToolCriterion` nachziehen. In der Praxis solltest du nur die parametrisierte Variante haben, aber für dieses Tutorial werden wir beide behalten. + +Lass uns von unten nach oben arbeiten. Wir müssen prüfen, ob die Anforderungen erfüllt sind, also bearbeiten wir unsere Methode `Condtions#requirementsMet`: + +@[code lang=java transcludeWith=:::datagen-advancements:new-requirements-met](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +`requiredTimes` existiert nicht, also mache es zu einem Parameter von `Conditions`: + +@[code lang=java transcludeWith=:::datagen-advancements:new-parameter](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Jetzt ist unser Codec fehlerhaft. Lass uns einen neuen Codec für die neuen Änderungen schreiben: + +@[code lang=java transcludeWith=:::datagen-advancements:new-codec](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Nun müssen wir unsere `trigger`-Methode korrigieren: + +@[code lang=java transcludeWith=:::datagen-advancements:new-trigger](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Wenn du ein neues Kriterium erstellt hast, müssen wir es zu `ModCriteria` hinzufügen + +@[code lang=java transcludeWith=:::datagen-advancements:new-mod-criteria](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +Und rufe sie in unserer Hauptklasse auf, genau dort, wo die alte Klasse ist: + +@[code lang=java transcludeWith=:::datagen-advancements:trigger-new-criterion](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Füge den Fortschritt zu deinem Provider hinzu: + +@[code lang=java transcludeWith=:::datagen-advancements:new-custom-criteria-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Führe den Datengenerator erneut aus, und du bist endlich fertig! diff --git a/versions/1.21/translated/de_de/develop/data-generation/loot-tables.md b/versions/1.21/translated/de_de/develop/data-generation/loot-tables.md new file mode 100644 index 000000000..08ca976f2 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/data-generation/loot-tables.md @@ -0,0 +1,57 @@ +--- +title: Generierung von Beutetabellen +description: Ein Leitfaden zur Einrichtung der Generierung von Beutetabellen mit dem Datengenerator. +authors: + - skycatminepokie + - Spinoscythe + - Alphagamer47 + - matthewperiut + - JustinHuPrime +authors-nogithub: + - mcrafterzz + - jmanc3 +--- + +# Generierung von Beutetabellen {#loot-table-generation} + +:::info VORAUSSETZUNGEN +Stelle sicher, dass du den Prozess der [Einrichtung der Datengenerierung](./setup) zuerst abgeschlossen hast. +::: + +Du wirst unterschiedliche Provider (Klassen) für Blöcke, Truhen und Entitäten benötigen. Vergesse nicht, alle diese zu deinem Pack in deinem `DataGeneratorEntrypoint` innerhalb der `onInitializeDataGenerator` Methode hinzuzufügen. + +@[code lang=java transclude={32-33}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Beutetabellen erklärt {#loot-tables-explained} + +**Beutetabellen** definieren, was du erhältst, wenn du einen Block abbaust (ohne den Inhalt, wie bei Truhen), eine Entität tötest oder einen neu erzeugten Container öffnest. Jede Beutetabelle hat einen **Pool** aus welchem Items ausgewählt werden. Beutetabellen haben außerdem **Funktionen**, welche die resultierenden Beute auf irgendeine Art verändern. + +Beutepools haben **Einträge**, **Bedingungen**, Funktionen, **Rollen** und **Bonusrollen**. Einträge sind Gruppen, Sequenzen, Möglichkeiten an Items oder einfach Items. Bedingungen sind Dinge, die in der Welt getestet werden, wie z. B. Verzauberungen auf einem Werkzeug oder eine zufällige Chance. Die minimale Anzahl an Einträgen, welche von einem Pool gewählt werden, nennen sich Rollen und alles darüber nennt sich eine Bonusrolle. + +## Blöcke {#blocks} + +Damit Blöcke Items - auch sich selbst - fallen lassen können, müssen wir eine Beutetabelle erstellen. Erstelle eine Klasse, die `extends FabricBlockLootTableProvider`: + +@[code lang=java transcludeWith=:::datagen-loot-tables:block-provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java) + +Füge diesen Provider unbedingt zu deinem Pack hinzu! + +Es gibt eine Reihe von Hilfsmethoden, die dir bei der Erstellung deiner Beutetabellen unterstützen. Wir werden sie nicht alle aufzählen, aber du solltest sie in deiner IDE ansehen. + +Lasst uns ein paar Drops in der Methode `generate` hinzufügen: + +@[code lang=java transcludeWith=:::datagen-loot-tables:block-drops](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java) + +## Truhen {#chests} + +Beute von Truhen sind ein wenig komplizierter als Beute von Blöcken. Erstelle eine Klasse, die `extends SimpleFabricLootTableProvider` ähnlich zu dem Beispiel unterhalb \*\* und füge sie zu deinem Pack hinzu\*\*. + +@[code lang=java transcludeWith=:::datagen-loot-tables:chest-provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java) + +Wir werden einen `RegistryKey` für unsere Beutetabelle benötigen. Lasst uns dies in eine neue Klasse mit dem Namen `ModLootTables` packen. Stelle sicher, dass dies dein `main` Quellenverzeichnis ist, wenn du geteilte Quellen nutzt. + +@[code lang=java transcludeWith=:::datagen-loot-tables:mod-loot-tables](@/reference/1.21/src/main/java/com/example/docs/ModLootTables.java) + +Dann können wir eine Beutetabelle innerhalb der `generate` Methode unseres Providers generieren. + +@[code lang=java transcludeWith=:::datagen-loot-tables:chest-loot](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java) diff --git a/versions/1.21/translated/de_de/develop/data-generation/recipes.md b/versions/1.21/translated/de_de/develop/data-generation/recipes.md new file mode 100644 index 000000000..5d63fdaed --- /dev/null +++ b/versions/1.21/translated/de_de/develop/data-generation/recipes.md @@ -0,0 +1,50 @@ +--- +title: Generierung von Rezepten +description: Ein Leitfaden zur Einrichtung der Generierung von Rezepten mit dem Datengenerator. +authors: + - skycatminepokie + - Spinoscythe +authors-nogithub: + - mcrafterzz + - jmanc3 +--- + +# Generierung von Rezepten {#recipe-generation} + +:::info VORAUSSETZUNGEN +Stelle sicher, dass du den Prozess der [Einrichtung der Datengenerierung](./setup) zuerst abgeschlossen hast. +::: + +## Einrichten {#setup} + +Zuerst benötigen wir unseren Provider. Erstelle eine Klasse, die `extends FabricRecipeProvider`. Die ganze Generierung der Rezepte wird innerhalb der `generate` Methode unseres Provider geschehen. + +@[code lang=java transcludeWith=:::datagen-recipes:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +Um die Einrichtung abzuschließen, füge den Provider zu deinem `DataGeneratorEntrypoint` in der `onInitializeDataGenerator` Methode hinzu. + +@[code lang=java transclude={30-30}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Formlose Rezepte {#shapeless-recipes} + +Formlose Rezepte sind relativ unkompliziert. Füge sie einfach zu der `generate` Methode in deinem Provider hinzu: + +@[code lang=java transcludeWith=:::datagen-recipes:shapeless](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +## Geformte Rezepte {#shaped-recipes} + +Für ein geformtes Rezept, definierst du die Form unter Verwendung eines `String`, dann definiere, was jedes `char` in dem `String` repräsentiert. + +@[code lang=java transcludeWith=:::datagen-recipes:shaped](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +:::tip +Es gibt viele Hilfsmethoden für die Erstellung von allgemeinen Rezepten. Sieh dir an, was der `RecipeProvider` anbietet! Nutze `Alt + 7` in IntelliJ, um die Struktur, einschließlich einer Liste an Methoden, einer Klasse zu öffnen. +::: + +## Andere Rezepte {#other-recipes} + +Andere Rezepte funktionieren ähnlich, aber erfordern einige zusätzliche Parameter. Zum Beispiel, Schmelzrezepte müssen wissen, wie viel Erfahrung zu vergeben ist. + +@[code lang=java transcludeWith=:::datagen-recipes:other](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +## Benutzerdefinierte Rezepttypen {#custom-recipe-types} diff --git a/versions/1.21/translated/de_de/develop/data-generation/setup.md b/versions/1.21/translated/de_de/develop/data-generation/setup.md new file mode 100644 index 000000000..282bb51aa --- /dev/null +++ b/versions/1.21/translated/de_de/develop/data-generation/setup.md @@ -0,0 +1,88 @@ +--- +title: Einrichtung der Datengenerierung +description: Ein Leitfaden zur Einrichtung der Datengenerierung mit der Fabric API. +authors: + - skycatminepokie + - modmuss50 + - earthcomputer + - shnupbups + - arkosammy12 + - haykam821 + - matthewperiut + - SolidBlock-cn + - Jab125 +authors-nogithub: + - jmanc3 + - macrafterzz +--- + +# Einrichten der Dtaengenerierung {#data-generation-setup} + +## Was ist Datengenerierung? {#what-is-data-generation} + +Datengenerierung (oder datagen) ist eine API für das programmatische generieren von Rezepten, Fortschritten, Tags, Itemmodellen, Sprachdateien, Beutetabllen und im Grunde allem auf JSON Basis. + +## Aktivieren der Datengenerierung {#enabling-data-generation} + +### Bei der Projekterstellung {#enabling-data-generation-at-project-creation} + +Der leichteste Weg die Datengenerierung zu aktivieren ist bei der Projekterstellung. Aktiviere das Kontrollkästchen "Enable Data Generation", wenn du den [Vorlagengenerator](https://fabricmc.net/develop/template/) verwendest. + +![Das aktivierte "Data Generation" Kontrollkästchen beim Vorlagengenerator](/assets/develop/data-generation/data_generation_setup_01.png) + +:::tip +Wenn die Datengenerierung aktiviert ist, solltest du eine "Data Generation" Laufkonfiguration udn einen `runDatagen` Gradle Task haben. +::: + +### Manuell {#manually-enabling-data-generation} + +Zuerst müssen wir die Datengenerierung in der `build.Gradle`-Datei aktivieren. + +@[code lang=groovy transcludeWith=:::datagen-setup:configure](@/reference/build.gradle) + +Als nächstes, benötigen wir eine Klasse für den Einstiegspunkt. Dies ist dort, wo unsere Datengenerierung startet. Platziere diese irgendwo in dem `client` Packet - dieses Beispiel platziert diese in `src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java`. + +@[code lang=java transcludeWith=:::datagen-setup:generator](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +Schließlich müsen wir Fabric in der `fabric.mod.json` über den Einstiegspunkt informieren: + +```json +{ + // ... + "entrypoints": { + // ... + "client": [ + // ... + ], + "fabric-datagen": [ // [!code ++] + "com.exmaple.docs.datagen.FabricDocsReferenceDataGenerator" // [!code ++] + ] // [!code ++] + } +} +``` + +:::warning +Vergesse nicht, ein Komma (`,`) nach dem vorherigen Einstiegspunkt-Block hinzuzufügen! +::: + +Schließe IntelliJ und öffne es erneut, um eine Laufkonfiguration für die Datengenerierung zu erstellen. + +## Ein Packet erstellen {#creating-a-pack} + +Innerhalb der Methode `onInitializeDataGenerator` deines Einstiegspunktes für die Datengenerierung m+ssen wir ein `Pack` erstellen. Später fügst du **Provider** hinzu, die generierte Daten in dieses `Pack` einfügen. + +@[code lang=java transcludeWith=:::datagen-setup:pack](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Ausführen des Datengenerators {#running-data-generation} + +Um die Datengenerierung auszuführen, nutze die Laufkonfiguration in deiner IDE oder führe in der Konsole `./gradlew runDatagen` aus. Die generierten Dateien werden in `src/main/generated` erstellt. + +## Nächste Schritte {#next-steps} + +Nachdem der Datengenerator nun eingerichtet ist, müssen wir **Provider** hinzufügen. Diese erzeugen die Daten, die du zu deinem `Pack` hinzufügst. Auf den folgenden Seiten wird beschrieben, wie du dies tun kannst. + +- [Fortschritte](./advancements) +- [Beutetabellen](./loot-tables) +- [Rezepte](./recipes) +- [Tags](./tags) +- [Übersetzungen](./translations) diff --git a/versions/1.21/translated/de_de/develop/data-generation/tags.md b/versions/1.21/translated/de_de/develop/data-generation/tags.md new file mode 100644 index 000000000..412167108 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/data-generation/tags.md @@ -0,0 +1,44 @@ +--- +title: Generierung von Tags +description: Ein Leitfaden zur Einrichtung der Generierung von Tags mit dem Datengenerator. +authors: + - skycatminepokie + - IMB11 + - Spinoscythe +authors-nogithub: + - mcrafterzz +--- + +# Generierung von Tags {#tag-generation} + +:::info VORAUSSETZUNGEN +Stelle sicher, dass du den Prozess der [Einrichtung der Datengenerierung](./setup) zuerst abgeschlossen hast. +::: + +## Einrichten {#setup} + +Erstelle zunächst eine eigene Klasse, die `extends FabricTagProvider`, wobei `T` der Typ der Sache ist, für die du ein Tag bereitstellen möchtest. Dies ist dein **Provider**. Hier werden wir zeigen, wie man `Item` Tags erstellt, aber das gleiche Prinzip lässt sich auf alle anderen Sachen anwenden. Lass deiner IDE den erforderlichen Code ausfüllen und ersetze dann den Konstruktorparameter `registryKey` durch den `RegistryKey` für deinen Typ: + +@[code lang=java transcludeWith=:::datagen-tags:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) + +:::info HINWEIS +Du wirst für jeden Tag-Typ einen anderen Provider benötigen (z. B. einen `FabricTagProvider>` und einen `FabricTagProvider`). +::: + +Um die Einrichtung abzuschließen, füge den Provider zu deinem `DataGeneratorEntrypoint` in der `onInitializeDataGenerator` Methode hinzu. + +@[code lang=java transclude={28-28}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Erstellen eines Tags {#creating-a-tag} + +Jetzt, nachdem du den Provider erstellt hast, lasst uns ein Tag zu diesem hinzufpgen. Zuerst, erstelle ein `TagKey`: + +@[code lang=java transcludeWith=:::datagen-tags:tag-key](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) + +Als nächstes, rufe `getOrCreateTagBuilder` innerhalb deiner Provider `configure` Methode auf. Von dort aus kannst du einzelne Items oder andere Tags hinzufügen oder diese Tags bereits vorhandene Tags ersetzen lassen. + +Wenn du ein Tag hinzufügen willst, verwende `addOptionalTag`, da der Inhalt des Tags während der Datengenerierung möglicherweise nicht geladen wird. Wenn du sicher bist, dass der Tag geladen ist, rufe `addTag` auf. + +Um zwangsweise ein Tag hinzuzufügen und das defekte Format zu ignorieren, verwende `forceAddTag`. + +@[code lang=java transcludeWith=:::datagen-tags:build](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) diff --git a/versions/1.21/translated/de_de/develop/data-generation/translations.md b/versions/1.21/translated/de_de/develop/data-generation/translations.md new file mode 100644 index 000000000..7f49442a5 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/data-generation/translations.md @@ -0,0 +1,49 @@ +--- +title: Generierung von Übersetzungen +description: Ein Leitfaden zur Einrichtung der Generierung von Übersetzungen mit dem Datengenerator. +authors: + - skycatminepokie + - MattiDragon + - IMB11 + - Spinoscythe +authors-nogithub: + - sjk1949 + - mcrafterzz + - jmanc3 +--- + +# Generierung von Übersetzungen {#translation-generation} + +:::info VORAUSSETZUNGEN +Stelle sicher, dass du den Prozess der [Einrichtung der Datengenerierung](./setup) zuerst abgeschlossen hast. +::: + +## Einrichten {#setup} + +Zuerst werden wir unseren **Provider** vorbereiten. Denke daran, dass es die Provider sind, die die Daten für uns generieren. Erstelle eine Klasse, die `extends FabricLanguageProvider` beinhaltet und fülle die Basismethoden aus: + +@[code lang=java transcludeWith=:::datagen-translations:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) + +:::info HINWEIS +Du wirst für jede Sprache, die du generieren möchtest, einen eigenen Provider benötigen (z. B. einen `ExampleEnglishLangProvider` und einen `ExamplePirateLangProvider`). +::: + +Um die Einrichtung abzuschließen, füge den Provider zu deinem `DataGeneratorEntrypoint` in der `onInitializeDataGenerator` Methode hinzu. + +@[code lang=java transclude={26-26}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Erstellen von Übersetzungen {#creating-translations} + +Neben der Erstellung von Rohübersetzungen, Übersetzungen aus einem `Identifier` und dem Kopieren aus einer bereits existierenden Datei (durch die Übergabe eines `Path`), gibt es Hilfsmethoden für die Übersetzung von Items, Blöcken, Tags, Statistiken, Entitäten, Statuseffekten, Itemgruppen, Entitätsattributen und Verzauberungen. Rufe einfach `add` beim `translationBuilder` auf und gebe an, was du übersetzen willst und in zu was es übersetzt werden soll: + +@[code lang=java transcludeWith=:::datagen-translations:build](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) + +## Nutzen einer Übersetzung {#using-translations} + +Generierte Übersetzungen ersetzen viele Übersetzungen, die in anderen Tutorials hinzugefügt wurden, aber du kannst sie auch überall dort verwenden, wo du ein `Text`-Objekt verwendest. In unserem Beispiel, wenn wir Ressourcenpaketen erlauben wollen unsere Begrüßung zu übersetzen, nutzen wir `Text.translatable` anstelle von `Text.of`: + +```java +ChatHud chatHud = MinecraftClient.getInstance().inGameHud.getChatHud(); +chatHud.addMessage(Text.literal("Hello there!")); // [!code --] +chatHud.addMessage(Text.translatable("text.fabric_docs_reference.greeting")); // [!code ++] +``` diff --git a/versions/1.21/translated/de_de/develop/entities/damage-types.md b/versions/1.21/translated/de_de/develop/entities/damage-types.md new file mode 100644 index 000000000..1d2dac068 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/entities/damage-types.md @@ -0,0 +1,96 @@ +--- +title: Schadensarten +description: Lerne, wie man benutzerdefinierte Schadensarten hinzufügt. +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# Schadensarten {#damage-types} + +Schadensarten definieren die Arten von Schaden, die Entitäten erleiden können. Seit Minecraft 1.19.4 ist die Erstellung neuer Schadensarten datengesteuert, das heißt sie werden mithilfe von JSON-Dateien erstellt. + +## Eine Schadensart erstellen {#creating-a-damage-type} + +Lass uns eine benutzerdefinierte Schadensart mit dem Namen _Tater_ erstellen. Wir beginnen mit der Erstellung einer JSON-Datei für deinen benutzerdefinierten Schaden. Diese Datei wird im `data`-Verzeichnis deines Mods in einem Unterverzeichnis mit dem Namen `damage_type` abgelegt. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +Sie hat folgende Struktur: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +Diese benutzerdefinierte Schadensart verursacht jedes Mal, wenn ein Spieler Schaden erleidet, einen Anstieg von 0,1 an [Erschöpfung](https://de.minecraft.wiki/w/Hunger#Ersch%C3%B6pfung), wenn der Schaden von einer lebenden Nicht-Spieler-Quelle (z.B. Weiterhin skaliert sich die Höhe des verursachten Schadens mit dem Schwierigkeitsgrad der Welt. + +::: info + +Im [Minecraft Wiki](https://de.minecraft.wiki/w/Schadensarten#Dateiformat) findest du alle möglichen Schlüssel und Werte. + +::: + +### Zugriff Auf Schadensarten Durch Code {#accessing-damage-types-through-code} + +Wenn wir über den Code auf unsere benutzerdefinierte Schadensart zugreifen müssen, verwenden wir seinen `RegistryKey`, um eine Instanz von `DamageSource` zu erstellen. + +Der `RegistryKey` kann wie folgt ermittelt werden: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### Schadensarten verwenden {#using-damage-types} + +Um die Verwendung von benutzerdefinierten Schadensarten zu demonstrieren, werden wir einen benutzerdefinierten Block mit dem Namen _Tater-Block_ verwenden. Wenn eine lebende Entität auf einen _Tater-Block_ tritt, verursacht er _Tater_ Schaden. + +Du kannst `onSteppedOn` überschreiben, um diesen Schaden zu zuzufügen. + +Wir beginnen mit der Erstellung einer `DamageSource` unserer benutzerdefinierten Schadensart. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Dann rufen wir `entity.damage()` mit unserer `DamageSource` und einem Betrag auf. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Die vollständige Implementierung des Blocks: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Wenn nun eine lebende Entität auf unseren benutzerdefinierten Block tritt, erleidet sie mit unserer benutzerdefinierten Schadensart 5 Schaden (2,5 Herzen). + +### Benutzerdefinierte Todesnachricht {#custom-death-message} + +Du kannst eine Todesnachricht für die Schadensart im Format `death.attack.` in der Datei `en_us.json` unseres Mods definieren. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +Beim Tod durch unsere Schadensart wirst du die folgende Todesnachricht sehen: + +![Effekt im Inventar eines Spielers](/assets/develop/tater-damage-death.png) + +### Schadensart-Tags {#damage-type-tags} + +Einige Schadensarten können Rüstung, Statuseffekte usw. Tags werden verwendet, um diese Art von Eigenschaften von Schadensarten zu kontrollieren. + +Vorhandene Schadensarten-Tags kannst du in `data/minecraft/tags/damage_type` finden. + +::: info + +Im [Minecraft Wiki](https://minecraft.wiki/w/Tag#Damage_types) kannst du eine umfassende Liste der Schadensarten-Tags finden. + +::: + +Fügen wir unsere Tater-Schadensart dem Schadensart-Tag `bypasses_armor` hinzu. + +Um unsere Schadensart zu einem dieser Tags hinzuzufügen, erstellen wir eine JSON-Datei im Namespace `minecraft`. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +Mit folgendem Inhalt: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +Stelle sicher, dass dein Tag das bestehende Tag nicht ersetzt, indem du den Schlüssel `replace` auf `false` setzt. diff --git a/versions/1.21/translated/de_de/develop/entities/effects.md b/versions/1.21/translated/de_de/develop/entities/effects.md new file mode 100644 index 000000000..292376a8f --- /dev/null +++ b/versions/1.21/translated/de_de/develop/entities/effects.md @@ -0,0 +1,87 @@ +--- +title: Statuseffekte +description: Lerne, wie man benutzerdefinierte Statuseffekte erstellt. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil + - Manchick0 +authors-nogithub: + - siglong + - tao0lu +--- + +# Statuseffekte {#status-effects} + +Statuseffekte, auch Effekte genannt, sind ein Zustand, der eine Entität beeinflussen kann. Sie können positiver, negativer oder neutraler Natur sein. Das Basisspiel wendet diese Effekte auf verschiedene Weise an, zum Beispiel durch Nahrung, Tränke usw. + +Der Befehl `/effect` kann verwendet werden, um Effekte auf eine Entität anzuwenden. + +## Benutzerdefinierte Statuseffekte {#custom-status-effects} + +In diesem Tutorial fügen wir einen neuen benutzerdefinierten Effekt namens _Tater_ hinzu, der dir einen Erfahrungspunkt pro Spieltick gibt. + +### `StatusEffect` erweitern {#extend-statuseffect} + +Lasst uns eine benutzerdefinierte Effektklasse erstellen, indem wir `StatusEffect` erweitern, die die Basisklasse für alle Effekte ist. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### Deinen benutzerdefinierten Effekt registrieren {#registering-your-custom-effect} + +Ähnlich wie bei der Registrierung von Blöcken und Items verwenden wir `Registry.register`, um unseren benutzerdefinierten Effekt in der `STATUS_EFFECT`-Registry zu registrieren. Dies kann in unserem Initialisierer geschehen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### Texturen {#texture} + +Das Statuseffekt-Symbol ist ein 18x18 PNG. Platziere dein eigenes Icon in: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + +Beispiel Textur + +### Übersetzungen {#translations} + +Wie jede andere Übersetzung kannst du einen Eintrag mit dem ID-Format `"effect..": "Wert"` zur Sprachdatei hinzufügen. + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### Einen Effekt anwenden {#applying-the-effect} + +Es lohnt sich, einen Blick darauf zu werfen, wie man normalerweise einen Effekt auf eine Entität anwendet. + +::: tip +For a quick test, it might be a better idea to use the previously mentioned `/effect` command: + +```mcfunction +effect give @p fabric-docs-reference:tater +``` + +::: + +Um einen Effekt intern anzuwenden, sollte man die Methode `LivingEntity#addStatusEffect` verwenden, die eine +eine `StatusEffectInstance` entgegennimmt und einen boolean zurückgibt, der angibt, ob der Effekt erfolgreich angewendet wurde. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java) + +| Argument | Typ | Beschreibung | +| ----------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `effect` | `RegistryEntry` | Ein Registrierungseintrag, der den Effekt repräsentiert. | +| `duration` | `int` | Die Dauer des Effekts **in Ticks**, **nicht** in Sekunden | +| `amplifier` | `int` | Der Verstärker auf das Level des Effekts. Es entspricht nicht dem **Level** des Effekts, sondern wird zusätzlich zu diesem hinzugefügt. Folglich, `amplifier` von `4` => Level von `5` | +| `ambient` | v | Dies ist ein schwieriger. Es gibt im Grunde an, dass der Effekt durch die Umgebung (z. B. ein **Leuchtfeuer**) hinzugefügt wurde und keine direkte Ursache hat. Wenn `true`, wird das Icon des Effekts im HUD mit einer türkiesen Überlagerung erscheinen. | +| `particles` | v | Ob Partikel angezeigt werden sollen. | +| `icon` | v | Ob das Icon des Effekts im HUD angezeigt werden soll. Der Effekt wird im Inventar unabhängig von dieser Flag angezeigt. | + +:::info +Um einen Trank zu erstellen, der diesen Effekt nutzt, lies bitte die Anleitung [Tränke](../items/potions). +::: diff --git a/versions/1.21/translated/de_de/develop/events.md b/versions/1.21/translated/de_de/develop/events.md new file mode 100644 index 000000000..9a4940f4f --- /dev/null +++ b/versions/1.21/translated/de_de/develop/events.md @@ -0,0 +1,122 @@ +--- +title: Events +description: Ein Leitfaden für die Nutzung von Events, welche von der Fabric API bereitgestellt werden. +authors: + - dicedpixels + - mkpoli + - daomephsta + - solidblock + - daomephsta + - jamieswhiteshirt + - PhoenixVX + - Juuxel + - YanisBft + - liach + - natanfudge +authors-nogithub: + - stormyfabric +--- + +# Ein einfaches Beispiel {#events} + +Die Fabric API bietet ein System, das es Mods erlaubt, auf Aktionen oder Ereignisse zu reagieren, die auch als _Events_ im Spiel definiert sind. + +Events sind Hooks, die gemeinsame Anwendungsfälle erfüllen und/oder die Kompatibilität und Leistung zwischen Mods verbessern, die sich in dieselben Bereiche des Codes einklinken. Die Verwendung von Ereignissen ersetzt oft die Verwendung von Mixins. + +Die Fabric API stellt Ereignisse für wichtige Bereiche der Minecraft-Codebasis bereit, an denen mehrere Modder interessiert sein könnten. + +Ereignisse werden durch Instanzen von `net.fabricmc.fabric.api.event.Event` dargestellt, die _Callbacks_ speichern und aufrufen. Oft gibt es eine einzige Event-Instanz für einen Callback, die in einem statischen Attribut `EVENT` des Callback-Interfaces gespeichert wird, aber es gibt auch andere Muster. Zum Beispiel fasst `ClientTickEvents` mehrere zusammenhängende Ereignisse zusammen. + +## Callbacks {#callbacks} + +Callbacks sind ein Teil des Codes, der als Argument an ein Event übergeben wird. Wenn das Event vom Spiel ausgelöst wird, wird der übergebene Teil des Codes ausgeführt. + +### Callback Interfaces {#callback-interfaces} + +Jedes Ereignis hat ein entsprechendes Callback-Interface, das üblicherweise `Callback` genannt wird. Callbacks werden durch den Aufruf der Methode `register()` für eine Event-Instanz registriert, wobei eine Instanz des Callbacks als Argument angegeben wird. + +Alle Event-Callback-Interfaces, die von der Fabric API bereitgestellt werden, sind im Paket `net.fabricmc.fabric.api.event` zu finden. + +## Auf Events hören {#listening-to-events} + +Dieses Beispiel registriert einen `AttackBlockCallback`, um dem Spieler Schaden zuzufügen, wenn er Blöcke trifft, die keinen Gegenstand fallen lassen, wenn sie von Hand abgebaut werden. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +### Items zu existierenden Beutetabellen hinzufügen {#adding-items-to-existing-loot-tables} + +Manchmal willst du vielleicht Gegenstände zu Beutetabellen hinzufügen. Zum Beispiel, indem du deine Drops zu einem Vanille-Block oder einer Entität hinzufügst. + +Die einfachste Lösung, das Ersetzen der Beutetabellen-Datei, kann andere Mods zerstören. Was ist, wenn sie diese auch ändern wollen? Wir sehen uns an, wie du Gegenstände zu Beutetabellen hinzufügen kannst, ohne die Tabelle zu überschreiben. + +Wir werden die Beutetabelle für Kohleerz um Eier erweitern. + +#### Auf das Laden der Beutetabelle hören {#listening-to-loot-table-loading} + +Die Fabric API hat ein Event, das ausgelöst wird, wenn Beutetabellen geladen werden, `LootTableEvents.MODIFY`. Du kannst hierfür einen Callback in deinem [Mod Initialisierer](./getting-started/project-structure#entrypoints) registrieren. Überprüfen wir auch, ob die aktuelle Beutetabelle die Beutetabelle für Kohleerz ist. + +@[code lang=java transclude={38-40}](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +#### Hinzufügen von Items zur Beutetabelle {#adding-items-to-the-loot-table} + +In Beutetabellen werden Gegenstände in _Beutepool-Einträgen_ gespeichert, und Einträge werden in _Beutepools_ gespeichert. Um einen Gegenstand hinzuzufügen, müssen wir der Beutetabelle einen Pool mit einem Eintrag für ein Item hinzufügen. + +Wir können einen Pool mit `LootPool#builder` erstellen, und ihn zur Beutetabelle hinzufügen. + +Unser Pool hat auch keine Items, also erstellen wir einen Item-Eintrag mit `ItemEntry#builder` und fügen ihn dem Pool hinzu. + +@[code highlight={6-7} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +## Benutzerdefinierte Events {#custom-events} + +In einigen Bereichen des Spiels gibt es keine von der Fabric API bereitgestellten Hooks, so dass du entweder ein Mixin verwenden oder dein eigenes Event erstellen kannst. + +Wir werden uns ein Event ansehen, das ausgelöst wird, wenn Schafe geschoren werden. Der Prozess der Erstellung eines Events ist wie folgt: + +- Erstellen des Interface für einen Event Callback +- Auslösen des Events von einem Mixin +- Erstellen einer Testimplementierung + +### Erstellen des Interface für einen Event Callback {#creating-the-event-callback-interface} + +Das Callback-Interface beschreibt, was von den Event-Listenern implementiert werden muss, die auf dein Event hören werden. Das Callback-Interface beschreibt auch, wie das Event von unserem Mixin ausgelöst werden soll. Es ist üblich, ein `Event`-Objekt als Attribut in dem Callback-Interface zu platzieren, das unser tatsächliches Event identifiziert. + +Für unsere `Event`-Implementierung werden wir uns für ein Array-gestütztes Event entscheiden. Das Array enthält alle Event-Listener, die auf das Event hören. + +Unsere Implementierung ruft die Event-Listener der Reihe nach auf, bis einer von ihnen kein `ActionResult.PASS` zurückgibt. Das bedeutet, dass ein Listener mit Hilfe seines Rückgabewerts sagen kann: "_Abbrechen_", "_Zustimmen_" oder "_Egal, überlasse es dem nächsten Event-Listener_". + +Die Verwendung von `ActionResult` als Rückgabewert ist ein konventioneller Weg, um Event-Handler auf diese Weise zusammenarbeiten zu lassen. + +Du musst ein Interface erstellen, das eine `Event`-Instanz und eine Methode zur Implementierung der Antwort hat. Ein Grundaufbau für unseren Schafschur-Callback ist: + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Schauen wir uns das genauer an. Wenn der Invoker aufgerufen wird, wird über alle Listener iteriert: + +@[code lang=java transclude={21-22}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Dann rufen wir unsere Methode (in diesem Fall `interact`) auf dem Listener auf, um seine Antwort zu erhalten: + +@[code lang=java transclude={33-33}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Wenn der Listener sagt, dass wir abbrechen (`ActionResult.FAIL`) oder vollständig beenden (`ActionResult.SUCCESS`) müssen, gibt der Callback das Ergebnis zurück und beendet die Schleife. `ActionResult.PASS` geht zum nächsten Listener über und sollte in den meisten Fällen zum Erfolg führen, wenn keine weiteren Listener registriert sind: + +@[code lang=java transclude={25-30}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Wir können Javadoc-Kommentare an die oberste Stelle der Callback-Klassen setzen, um zu dokumentieren, was jedes `ActionResult` macht. In unserem Fall könnte das wie folgt sein: + +@[code lang=java transclude={9-16}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +### Auslösen des Events von einem Mixin {#triggering-the-event-from-a-mixin} + +Jetzt haben wir das Grundgerüst für ein Event, aber wir müssen es auslösen. Da wir das Ereignis auslösen wollen, wenn ein Spieler versucht, ein Schaf zu scheren, rufen wir das Ereignis `invoker` in `SheepEntity#interactMob` auf, wenn `sheared()` aufgerufen wird (d.h. + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java) + +### Erstellen einer Testimplementierung {#creating-a-test-implementation} + +Jetzt müssen wir unser Event testen. Du kannst einen Listener in deiner Initialisierungsmethode (oder in einem anderen Bereich, wenn du das bevorzugst) registrieren und dort benutzerdefinierte Logik hinzufügen. Hier ist ein Beispiel, bei dem dem ein Diamant anstelle von Wolle auf die Füße des Schafs fällt: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +Wenn du im Spiel ein Schaf scherst, sollte anstelle von Wolle ein Diamant fallen. diff --git a/versions/1.21/translated/de_de/develop/getting-started/creating-a-project.md b/versions/1.21/translated/de_de/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..7459cc4b2 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/getting-started/creating-a-project.md @@ -0,0 +1,71 @@ +--- +title: Ein Projekt erstellen +description: Eine Schritt-für-Schritt-Anleitung, wie man ein neues Mod-Projekt mit dem Fabric Vorlagen Mod Generator erstellt. +authors: + - IMB11 + - Cactooz +--- + +# Ein Projekt erstellen {#creating-a-project} + +Fabric bietet eine einfache Möglichkeit, ein neues Mod-Projekt mit dem Fabric Template Mod Generator zu erstellen - wenn du möchtest, kannst du ein neues Projekt auch manuell erstellen, indem du das Beispiel-Mod-Repository verwendest, dann solltest du den Abschnitt [Manuelle Projekterstellung](#manuelle-projekterstellung) lesen. + +## Erstellung eines Projekts {#generating-a-project} + +Du kannst den [Fabric Vorlagen Mod Generator](https://fabricmc.net/develop/template/) verwenden, um ein neues Projekt für deinen Mod zu generrieren - du solltest die erforderlichen Felder ausfüllen, wie beispielsweise den Paketnamen und den Mod-Namen, sowie die Minecraft-Version, für die du entwickeln möchtest. + +Der Paketname sollte klein geschrieben, durch Punkte getrennt und eindeutig sein, um Konflikte mit den Paketen anderer Programmierer zu vermeiden. Er ist typischerweise wie eine umgedrehte Internet-Domain formatiert, beispielsweise wie `com.example.modid`. + +![Vorschau des Generators](/assets/develop/getting-started/template-generator.png) + +Wenn du Kotlin verwenden, die offiziellen Mappings von Mojang anstelle der Yarn-Mappings nutzen oder Datengeneratoren hinzufügen möchtest, kannst du die entsprechenden Optionen im Abschnitt `Advanced Options` auswählen. + +![Der Abschnitt "Advanced options"](/assets/develop/getting-started/template-generator-advanced.png) + +Der Generator erstellt dann ein neues Projekt in Form einer ZIP-Datei für dich. + +Du solltest diese ZIP-Datei an einem Ort deiner Wahl entpacken und dann den entpackten Ordner in IntelliJ IDEA öffnen: + +![Aufforderung zum Öffnen des Projekts](/assets/develop/getting-started/open-project.png) + +## Import des Projekts {#importing-the-project} + +Sobald du das Projekt in IntelliJ IDEA geöffnet hast, sollte IDEA automatisch die Gradle-Konfiguration des Projekts laden und die notwendigen Einrichtungsaufgaben durchführen. + +Wenn du eine Benachrichtigung über ein Gradle-Build-Skript erhältst, solltest du auf die Schaltfläche `Import Gradle Project` klicken: + +![Gradle Aufforderung](/assets/develop/getting-started/gradle-prompt.png) + +Sobald das Projekt importiert wurde, solltest du die Dateien des Projekts im Projekt-Explorer sehen und mit der Entwicklung deines Mods beginnen können. + +## Manuelle Projekterstellung {#manual-project-creation} + +:::warning +Du musst [Git](https://git-scm.com/) installiert haben, um das Beispiel-Mod-Repository klonen zu können. +::: + +Wenn du den Fabric Vorlagen Mod Generator nicht verwenden kannst, kannst du ein neues Projekt manuell erstellen, indem du folgende Schritte befolgst. + +Klone zunächst das Beispiel-Mod-Repository mit Git: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +Dadurch wird das Repository in einen neuen Ordner mit dem Namen `my-mod-project` geklont. + +Anschließend solltest du den Ordner `.git` aus dem geklonten Repository löschen und das Projekt in IntelliJ IDEA öffnen. Wenn der Ordner `.git` nicht angezeigt wird, solltest du die Option zur Anzeige versteckter Dateien in deinem Dateimanager aktivieren. + +Sobald du das Projekt in IntelliJ IDEA geöffnet hast, sollte es automatisch die Gradle-Konfiguration des Projekts laden und die notwendigen Einrichtungsaufgaben durchführen. + +Wie bereits erwähnt, solltest du, wenn du eine Benachrichtigung über ein Gradle-Build-Skript erhältst, auf die Schaltfläche `Import Gradle Project` klicken. + +### Die Vorlage bearbeiten {#modifying-the-template} + +Sobald das Projekt importiert wurde, solltest du die Details des Projekts so ändern, dass sie mit den Details deines Mods übereinstimmen: + +- Ändere die Datei `gradle.properties` des Projekts, um die Eigenschaften `maven_group` und `archive_base_name` an die Details deines Mods anzupassen. +- Ändere die Datei `fabric.mod.json`, um die Eigenschaften `id`, `name` und `description` an die Details deines Mods anzupassen. +- Stelle sicher, dass die Versionen von Minecraft, die Mappings, der Loader und Loom - die alle über abgefragt werden können - mit den Versionen übereinstimmen, die du ansprechen möchtest. + +Du kannst natürlich den Paketnamen und die Hauptklasse des Mods ändern, um die Details deines Mods anzupassen. diff --git a/versions/1.21/translated/de_de/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/de_de/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..2022b8440 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Einführung in Fabric und Modding +description: "Eine kurze Einführung in Fabric und Modding in Minecraft: Java Edition." +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Einführung in Fabric und Modding {#introduction-to-fabric-and-modding} + +## Voraussetzungen {#prerequisites} + +Bevor du anfängst, solltest du ein Grundverständnis für die Entwicklung mit Java und ein Verständnis für objektorientierte Programmierung (OOP) haben. + +Wenn du mit diesen Konzepten nicht vertraut bist, solltest du dir einige Tutorials zu Java und OOP ansehen, bevor du mit dem Modding beginnst. + +- [W3: Java Tutorials](https://www.w3schools.com/java/) +- [Codecademy: Java lernen](https://www.codecademy.com/learn/learn-java) +- [W3: Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium: Einführung in die OOP](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### Begriffserklärung {#terminology} + +Bevor wir beginnen, wollen wir einige Begriffe erläutern, die bei der Arbeit mit Fabric vorkommen werden: + +- **Mod**: Eine Modifikation des Spiels, die neue Funktionen hinzufügt oder bestehende ändert. +- **Mod-Loader**: Ein Tool, das Mods in das Spiel lädt, wie zum Beispiel der Fabric Loader. +- **Mixin**: Ein Werkzeug zum Ändern des Spielcodes zur Laufzeit - siehe [Mixin-Einführung](https://fabricmc.net/wiki/tutorial:mixin_introduction) für weitere Informationen. +- **Gradle**: Ein Build-Automatisierungstool zum Erstellen und Kompilieren von Mods, das von Fabric zum Erstellen von Mods verwendet wird. +- **Mappings**: Eine Reihe von Mappings, die obfuskierten Code auf menschenlesbaren Code abbilden. +- **Obfuskation**: Der Prozess, der Code schwer verständlich macht und von Mojang verwendet wird, um den Code von Minecraft zu schützen. +- **Remapping**: Der Prozess der Umwandlung von obfuskierten Code in für Menschen lesbaren Code. + +## Was ist Fabric? {#what-is-fabric} + +Fabric ist eine leichtgewichtige Modding-Werkzeugbox für Minecraft: Java Edition. + +Sie ist als einfache und leicht zu bedienende Modding-Plattform konzipiert. Fabric ist ein von der Gemeinschaft getragenes Projekt und ist Open Source, was bedeutet, dass jeder zu dem Projekt beitragen kann. + +Du solltest die vier Hauptkomponenten von Fabric kennen: + +- **Fabric Loader**: Ein flexibler, plattformunabhängiger Mod-Loader für Minecraft und andere Spiele und Anwendungen. +- **Fabric Loom**: Ein Gradle-Plugin, das es Entwicklern ermöglicht, Mods einfach zu entwickeln und zu debuggen. +- **Fabric API**: Eine Reihe von APIs und Werkezuge für Mod-Entwickler, die du bei der Erstellung von Mods verwenden kannst. +- **Yarn**: Eine Reihe offener Minecraft-Mappings, die unter der Creative Commons Zero-Lizenz für jeden frei nutzbar sind. + +## Warum wird Fabric für das Modden von Minecraft benötigt? {#why-is-fabric-necessary-to-mod-minecraft} + +> Beim Modding wird ein Spiel modifiziert, um sein Verhalten zu ändern oder neue Funktionen hinzuzufügen - im Fall von Minecraft kann dies alles sein, vom Hinzufügen neuer Items, Blöcke oder Entitäten bis hin zur Änderung der Spielmechanik oder dem Hinzufügen neuer Spielmodi. + +Minecraft: Die Java Edition wird von Mojang obfuskiert, was Modifikationen allein schwierig macht. Mit Hilfe von Modding-Werkzeugen wie Fabric wird das Modding jedoch viel einfacher. Es gibt verschiedene Mapping-Systeme, die bei diesem Prozess helfen können. + +Loom wandelt den obfuskierten Code mit Hilfe dieser Mappings in ein für Menschen lesbares Format um, was es Moddern erleichtert, den Code des Spiels zu verstehen und zu verändern. Yarn ist eine beliebte und ausgezeichnete Wahl für diese Mappings, aber es gibt auch andere Optionen. Jedes Mapping-Projekt kann seine eigenen Stärken oder Schwerpunkte haben. + +Mit Loom kannst du auf einfache Weise Mods entwickeln und Mods gegen remapped Code kompilieren, und mit Fabric Loader kannst du diese Mods in das Spiel laden. + +## Was bietet die Fabric API und warum ist sie nötig? {#what-does-fabric-api-provide-and-why-is-it-needed} + +> Fabric API ist eine Sammlung von APIs und Werkzeugen, die Mod-Entwickler bei der Erstellung von Mods verwenden können. + +Die Fabric API bietet eine Vielzahl von APIs, die auf der bestehenden Funktionalität von Minecraft aufbauen - zum Beispiel neue Hooks und Events, die Modder nutzen können, oder neue Utilities und Werkzeuge, die das Modding vereinfachen - wie zum Beispiel Access Wideners und die Möglichkeit, auf interne Registrys zuzugreifen, wie zui, Beispiel die Registry für kompostierbare Items. + +Während die Fabric API leistungsstarke Funktionen bietet, können einige Aufgaben, wie zum Beispiel die grundlegende Blockregistrierung, auch ohne sie mit den Vanilla APIs durchgeführt werden. diff --git a/versions/1.21/translated/de_de/develop/getting-started/launching-the-game.md b/versions/1.21/translated/de_de/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..a49b7e8ee --- /dev/null +++ b/versions/1.21/translated/de_de/develop/getting-started/launching-the-game.md @@ -0,0 +1,72 @@ +--- +title: Starten des Spiels +description: Lerne, wie du die verschiedenen Startprofile verwendest, um deine Mods in einer Live-Spielumgebung zu starten und zu debuggen. +authors: + - IMB11 + - Tenneb22 +--- + +# Starten des Spiels {#launching-the-game} + +Fabric Loom bietet eine Vielzahl von Startprofilen, die dir helfen, deine Mods in einer Live-Spielumgebung zu starten und zu debuggen. Dieser Leitfaden behandelt die verschiedenen Startprofile und wie man sie zum Debuggen und Testen der Mods verwendet. + +## Startprofile {#launch-profiles} + +Wenn du IntelliJ IDEA verwendest, findest du die Startprofile in der oberen rechten Ecke des Fensters. Klicke auf das Dropdown-Menü, um die verfügbaren Startprofile anzuzeigen. + +Es sollte ein Client- und ein Serverprofil geben, mit der Möglichkeit, es entweder normal oder im Debug-Modus auszuführen: + +![Startprofile](/assets/develop/getting-started/launch-profiles.png) + +## Gradle Aufgaben {#gradle-tasks} + +Wenn du die Kommandozeile verwendest, kannst du die folgenden Gradle-Befehle verwenden, um das Spiel zu starten: + +- `./gradlew runClient` - Startet das Spiel im Client-Modus. +- `./gradlew runServer` - Startet das Spiel im Server-Modus. + +Das einzige Problem bei diesem Ansatz ist, dass Sie Ihren Code nicht einfach debuggen können. Wenn du deinen Code debuggen willst, musst du die Startprofile in IntelliJ IDEA oder über die Gradle-Integration deiner IDE verwenden. + +## Hotswapping von Klassen {#hotswapping-classes} + +Wenn du das Spiel im Debug-Modus ausführst, kannst du deine Klassen per Hotswap austauschen, ohne das Spiel neu zu starten. Dies ist nützlich, um Änderungen an deinem Code schnell zu testen. + +Du bist aber immer noch ziemlich eingeschränkt: + +- Du kannst keine Methoden hinzufügen oder entfernen +- Du kannst die Methodenparameter nicht ändern +- Du kannst keine Attribute hinzufügen oder entfernen + +Mit der Nutzung der [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime) hingegen, kannst du die meisten Einschränkungen umgehen, wie das Erstellen und Löschen von Klassen und Methoden. Dadurch sollten die meisten Änderungen möglich sein, ohne das Spiel neu zu starten. + +Füge außerdem in deine Minecraft Start Konfigurationen Folgendes zu den VM Argumenten hinzu: + +```:no-line-numbers +-XX:+AllowEnhancedClassRedefinition +``` + +## Hotswapping von Mixins {#hotswapping-mixins} + +Wenn du Mixins verwendest, kannst du deine Mixin-Klassen per Hotswap austauschen, ohne das Spiel neu zu starten. Dies ist nützlich, um Änderungen an deinen Mixins schnell zu testen. + +Hierzu musst du allerdings den Mixin-Java-Agent installieren, damit das funktioniert. + +### 1. Finde die JAR der Mixin Bibliothek {#1-locate-the-mixin-library-jar} + +In IntelliJ IDEA findest du die Mixin-Bibliothek JAR im Abschnitt "External Libraries" des Abschnitts "Project": + +![Mixin Bibliothek](/assets/develop/getting-started/mixin-library.png) + +Für den nächsten Schritt musst du den "Absolute Path" (Absoluten Pfad) der JAR-Datei kopieren. + +### 2. Füge das VM-Argument `-javaagent` hinzu {#2-add-the--javaagent-vm-argument} + +Füge in deiner "Minecraft Client"- und/oder "Minecraft Server"-Ausführungskonfiguration Folgendes zur Option VM-Argumente hinzu: + +```:no-line-numbers +-javaagent:"Pfad zur Mixin-Bibliothek JAR hier" +``` + +![Bildschirmfoto der VM-Argumente](/assets/develop/getting-started/vm-arguments.png) + +Jetzt solltest du in der Lage sein, den Inhalt deiner Mixin-Methoden während des Debuggens zu ändern und die Änderungen wirksam werden zu lassen, ohne das Spiel neu zu starten. diff --git a/versions/1.21/translated/de_de/develop/getting-started/project-structure.md b/versions/1.21/translated/de_de/develop/getting-started/project-structure.md new file mode 100644 index 000000000..0aed813a6 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/getting-started/project-structure.md @@ -0,0 +1,64 @@ +--- +title: Projektstruktur +description: Ein Überblick über die Struktur eines Fabric-Mod-Projekts. +authors: + - IMB11 +--- + +# Projektstruktur {#project-structure} + +Auf dieser Seite wird die Struktur eines Fabric-Mod-Projekts und der Zweck der einzelnen Dateien und Ordner im Projekt erläutert. + +## `fabric.mod.json` {#fabric-mod-json} + +Die Datei `fabric.mod.json` ist die Hauptdatei, die deinen Mod für den Fabric Loader beschreibt. Sie enthält Informationen wie die ID des Mods, die Version und die Abhängigkeiten. + +Die wichtigsten Felder in der Datei `fabric.mod.json` sind: + +- `id`: Die Mod-ID, Welche einzigartig sein sollte. +- `name`: Der Name des Mods. +- `environment`: Die Umgebung in der dein Mod läuft, wie beispielsweise `client`, `server`, oder `*` für beide. +- `entrypoints`: Die Einstiegspunkte, die dein Mod bereitstellt, wie beispielsweise `main` oder `client`. +- `depends`: Die Mods, von denen dein Mod abhängt. +- `mixins`: Die Mixins, die dein Mod bereitstellt. + +Nachfolgend siehst du eine Beispieldatei `fabric.mod.json` - dies ist die Datei `fabric.mod.json` für das Referenzprojekt, das diese Dokumentationsseite betreibt. + +:::details Referenzprojekt `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## Einstiegspunkte {#entrypoints} + +Wie bereits erwähnt, enthält die Datei `fabric.mod.json` ein Feld namens `entrypoints` - dieses Feld wird verwendet, um die Einstiegspunkte anzugeben, die dein Mod bereitstellt. + +Der Template-Mod-Generator erstellt standardmäßig sowohl einen `main`- als auch einen `client`-Einstiegspunkt: + +- Der Einstiegspunkt `main` wird für allgemeinen Code verwendet und ist in einer Klasse enthalten, die `ModInitializer` implementiert +- Der `client` Einstiegspunkt wird für clientspezifischen Code genutzt und seine Klasse implementiert `ClientModInitializer` + +Diese Einstiegspunkte werden jeweils aufgerufen, wenn das Spiel beginnt. + +Hier ist ein Beispiel für einen einfachen `main`-Einstiegspunkt, der eine Nachricht an die Konsole ausgibt, wenn das Spiel startet: + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +## `src/main/resources` {#src-main-resources} + +Der Ordner `src/main/resources` wird verwendet, um die Ressourcen zu speichern, die dein Mod verwendet, wie Texturen, Modelle und Sounds. + +Es ist auch der Ort, an dem sich die Datei `fabric.mod.json` und alle Mixin-Konfigurationsdateien befinden, die dein Mod verwendet. + +Assets werden in einer Struktur gespeichert, die die Struktur von Ressourcenpaketen widerspiegelt - eine Textur für einen Block würde zum Beispiel in `assets/modid/textures/block/block.png` gespeichert werden. + +## `src/client/resources` {#src-client-resources} + +Der Ordner `src/client/resources` wird verwendet, um Client-spezifische Ressourcen zu speichern, wie Texturen, Modelle und Sounds, die nur auf der Client-Seite verwendet werden. + +## `src/main/java` {#src-main-java} + +Der Ordner `src/main/java` wird verwendet, um den Java-Quellcode für deinen Mod zu speichern - er existiert sowohl auf der Client- als auch auf der Serverumgebung. + +## `src/client/java` {#src-client-java} + +Der Ordner `src/client/java` wird verwendet, um clientspezifischen Java-Quellcode zu speichern, wie zum Beispiel Rendering-Code oder clientseitige Logik - wie zum Beispiel Blockfarbenprovider. diff --git a/versions/1.21/translated/de_de/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/de_de/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..73ca9f088 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: Entwicklungsumgebung einrichten +description: Ein Schritt-für-Schritt-Leitfaden, wie man eine Entwicklungsumgebung für die Erstellung von Mods mit Fabric einrichtet. +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# Entwicklungsumgebung einrichten {#setting-up-a-development-environment} + +Um mit der Entwicklung von Mods mit Fabric zu beginnen, musst du eine Entwicklungsumgebung mit IntelliJ IDEA einrichten. + +## JDK 17 installieren {#installing-jdk-21} + +Um Mods für Minecraft 1.21 zu entwickeln, benötigst du das JDK 17. + +Wenn du Hilfe bei der Installation von Java benötigst, kannst du die verschiedenen Java-Installationsanleitungen im Abschnitt [Leitfäden für Spieler](../../players/index) nachlesen. + +## IntelliJ IDEA installieren {#installing-intellij-idea} + +:::info +Natürlich kannst du auch andere IDEs verwenden, wie zum Beispiel Eclipse oder Visual Studio Code, aber die meisten Seiten dieser Dokumentation gehen davon aus, dass du IntelliJ IDEA verwendest - wenn du eine andere IDE verwendest, solltest du die Dokumentation für deine IDE lesen. +::: + +Wenn du IntelliJ IDEA nicht installiert hast, kannst du es von der [offiziellen Website](https://www.jetbrains.com/idea/download/) herunterladen - befolge die Installationsschritte für dein Betriebssystem. + +Die Community-Edition von IntelliJ IDEA ist kostenlos und Open Source, und sie ist die empfohlene Version für das Modding mit Fabric. + +Möglicherweise musst du nach unten scrollen, um den Download-Link für die Community-Edition zu finden - er sieht wie folgt aus: + +![Aufforderung für den Download der IDEA Community Edition](/assets/develop/getting-started/idea-community.png) + +## IDEA Plugins installieren {#installing-idea-plugins} + +Obwohl diese Plugins nicht unbedingt notwendig sind, können sie das Modding mit Fabric erheblich erleichtern - deshalb solltest du in Erwägung ziehen, sie zu installieren. + +### Minecraft Development {#minecraft-development} + +Das Minecraft Development Plugin bietet Unterstützung für das Modding mit Fabric und ist das wichtigste Plugin, das man installieren sollte. + +Du kannst es installieren, indem du IntelliJ IDEA öffnest und dann zu `File > Settings > Plugins > Marketplace Tab` navigierst - suche nach `Minecraft Development` in der Suchleiste und klicke dann auf die `Install` Schaltfläche. + +Alternativ kannst du es von der [Plugin-Seite](https://plugins.jetbrains.com/plugin/8327-minecraft-development) herunterladen und dann installieren, indem du zu `File > Settings > Plugins > Install Plugin From Disk` navigierst. diff --git a/versions/1.21/translated/de_de/develop/ide-tips-and-tricks.md b/versions/1.21/translated/de_de/develop/ide-tips-and-tricks.md new file mode 100644 index 000000000..b89cd6b30 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/ide-tips-and-tricks.md @@ -0,0 +1,310 @@ +--- +title: Tipps und Tricks für die Entwicklungsumgebung +description: Nützliche Informationen, um dein Projekt mit der IDE effizient zu bearbeiten und zu durchsuchen. +authors: + - JR1811 + - AnAwesomGuy +--- + +# Tipps und Tricks für die Entwicklungsumgebung {#ide-tips-and-tricks} + +Diese Seite stellt nützliche Informationen, um das Arbeiten von Entwicklern so schnell und angenehm wie möglich zu gestalten, bereit. Benutze diese je nach Bedarf. +Es kann eine gewisse Einarbeitungszeit brauchen, um sich an die Tastenkombinationen und anderen Optionen zu gewöhnen. Diese Seite kann dafür als eine Hilfe dafür genutzt werden. + +:::warning +Tastenkombinationen im Text beziehen sich auf die Standardtastaturbelegung von IntelliJ IDEA, wenn nicht anders angegeben. +Schaue unter `Datei > Einstellungen > Tastaturbelegung` nach oder suche woanders nach dieser Funktion, wenn du ein anderes Tastaturlayout verwendest. +::: + +## Fortbewegung in Projekten{#traversing-projects} + +### Manuell {#manually} + +IntelliJ bietet mehrere Möglichkeiten, sich im Projekt fortzubewegen. Falls die Quelldaten mit den `./gradlew genSources` Befehlen oder über die `Tasks > fabric > genSources` Gradle Tasks im Gradle Fenster generiert wurden, können die Quelldaten von Minecraft, innerhalb des Projektfensters `Externe Bibliotheken`, manuell nachgeschlagen werden. + +![Gradle Tasks](/assets/develop/misc/using-the-ide/traversing_01.png) + +Die Quelldaten von Minecraft können mit dem Suchbegriff `net.minecraft` im Projektfensters Externe Bibliotheken gefunden werden. +Wenn dein Projekt geteilte Quellen aus dem Online [Template Modgenerator](https://fabricmc.net/develop/template) verwendet, gibt es zwei Quellen, wie durch den Namen (client/common) angegeben. +Zusätzlich werden auch andere Quellen von Projekten, Bibliotheken und Abhängigkeiten, die über die Datei `build.gradle` importiert werden, verfügbar sein. +Diese Methode wird häufig bei der Suche nach Assets, Tags und anderen Dateien verwendet. + +![Externe Bibliothek](/assets/develop/misc/using-the-ide/traversing_02_1.png) + +![Geteilte Quellen](/assets/develop/misc/using-the-ide/traversing_02_2.png) + +### Suchen {#search} + +Durch zweimaliges Drücken von Shift öffnet sich ein Suchfenster. Dort kannst du nach den Dateien und Klassen deines Projekts suchen. Durch Aktivieren des Kontrollkästchens `include non-project items` oder durch zweimaliges Drücken von Shift wird nicht nur im eigenen Projekt gesucht, sondern auch in anderen, z. B. in den Externen Bibliotheken. + +Du kannst auch die Tastenkombination ⌘/STRG+N zur Suche von Klassen und ⌘/STRG+Shift+N zur Suche aller _Dateien_ nutzen. + +![Suchfenster](/assets/develop/misc/using-the-ide/traversing_03.png) + +### Letzte Fenster {#recent-window} + +Ein weiteres nützliches Werkzeug in IntelliJ ist das Fenster `Recent`. Du kannst es mit der Tastenkombination ⌘/STRG+E öffnen. +Dort kannst du zu den Dateien springen, die du bereits besucht hast, und Werkzeugfenster öffnen, z. B. das Fenster [Struktur](#structure-of-a-class) oder [Lesezeichen](#bookmarks). + +![Letzte Fenster](/assets/develop/misc/using-the-ide/traversing_04.png) + +## Fortbewegung in Code {#traversing-code} + +### Zur Definition / Verwendung springen {#jump-to-definition-usage} + +Wenn du entweder die Definition oder Nutzung von Variablen, Methoden, Klassen oder anderen Dingen ansehen willst, kannst du ⌘/STRG+Linksklick / B +oder Mittlere Maustate (drücken des Mausrads) auf deren Namen verwenden. Auf diese Weise vermeidest du langes Scrollen oder eine manuelle Suche nach einer Definition, die sich in einer anderen Datei befindet. + +Du kannst außerdem ⌘/STRG+⌥/Shift+Linklsklick / B verwenden, um alle Implementationen einer Klasse oder eines Interfaces zu sehen. + +### Lesezeichen {#bookmarks} + +Du kannst Codezeilen, Dateien oder sogar geöffnete Editor-Registerkarten mit Lesezeichen versehen. +Besonders bei der Recherche von Quellcodes kann es helfen, Stellen zu markieren, die man in Zukunft schnell wiederfinden möchte. + +Klicke entweder mit der rechten Maustaste auf eine Datei im Projektfenster, auf eine Registerkarte im Editor oder auf die Zeilennummer in einer Datei. +Das Anlegen von `Mnemonic Bookmarks` ermöglicht es dur, schnell zu diesen Bookmarks zurück zu wechseln, indem du die Tastenkombination ⌘/STRG und die von dir gewählte Ziffer verwendest. + +![Lesezeichen setzen](/assets/develop/misc/using-the-ide/traversing_05.png) + +Es ist möglich, im Fenster `Bookmarks` mehrere Lesezeichenlisten gleichzeitig zu erstellen, wenn du sie trennen oder ordnen möchtest. +[Haltepunkte](./basic-problem-solving#breakpoint) werden dort ebenfalls angezeigt. + +![Lesezeichen Fenster](/assets/develop/misc/using-the-ide/traversing_06.png) + +## Klassen analysieren {#analyzing-classes} + +### Klassenstruktur {#structure-of-a-class} + +Durch das Öffnen des Fensters `Struktur` (⌘/Alt+7) erhältst du einen Überblick über deine aktuell aktive Klasse. Du kannst sehen, welche Klassen und Enums sich in dieser Datei befinden, welche Methoden implementiert wurden und welche Felder und Variablen deklariert sind. + +Manchmal kann es auch hilfreich sein, die Option `Inherited` oben in den Ansichtsoptionen zu aktivieren, wenn man nach potenziellen Methoden sucht, die man überschreiben kann. + +![Struktur Fenster](/assets/develop/misc/using-the-ide/analyzing_01.png) + +### Typenhierarchie einer Klasse {#type-hierarchy-of-a-class} + +Indem du den Cursor auf einen Klassennamen setzt und ⌘/STRG+H drückst, kannst du ein neues Typenhierarchie-Fenster öffnen, das alle Eltern- und Kindklassen anzeigt. + +![Typenhierachie Fenster](/assets/develop/misc/using-the-ide/analyzing_02.png) + +## Code-Utility {#code-utility} + +### Code Vervollständigung {#code-completion} + +Die Code-Vervollständigung sollte standardmäßig aktiviert sein. Du bekommst die Empfehlungen automatisch beim Schreiben deines Codes. +Wenn du sie versehentlich geschlossen oder den Mauszeiger an eine neue Stelle bewegt hast, kannst du sie mit ⌘/STRG+Leertaste wieder öffnen. + +Wenn du zum Beispiel Lambdas verwendest, kannst du sie mit dieser Methode schnell schreiben. + +![Lambda mit vielen Parametern](/assets/develop/misc/using-the-ide/util_01.png) + +### Code Generierung {#code-generation} + +Das Menü Generieren kannst du schnell durch Alt+Einfügen (⌘ Befehl+N auf Mac) aufgerufen werden oder indem du oben auf `Code` gehst und `Generieren` auswählst. +In einer Java-Datei kannst du Konstruktoren, Getter, Setter, überschreibende oder implementierende Methoden und vieles mehr generrieren. +Du kannst auch Accessors und Invokers erzeugen, wenn du das [Minecraft Development Plugin](./getting-started/setting-up-a-development-environment#minecraft-development) installiert hast. + +Zusätzlich kannst du Methoden mit ⌘/STRG+O überschreiben und mit ⌘/STRG+I implementieren. + +![Menü zur Codegenerierung in einer Java-Datei](/assets/develop/misc/using-the-ide/generate_01.png) + +In einer Java-Testdatei erhälst du Optionen, um die entsprechenden Testmethoden zu generieren, wie folgt: + +![Menü zur Codegenerierung in einer Java-Testdatei](/assets/develop/misc/using-the-ide/generate_02.png) + +### Parameter anzeigen {#displaying-parameters} + +Die Anzeige der Parameter sollte standardmäßig aktiviert sein. Du bekommst automatisch die Typen und Namen der Parameter, während du deinen Code schreibst. +Wenn du sie versehentlich geschlossen oder den Cursor an eine neue Stelle bewegt hast, kannst du sie mit ⌘/STRG+P wieder öffnen. + +Methoden und Klassen können mehrere Implementationen mit unterschiedlichen Parametern haben, was auch als Überladen bezeichnet wird. Auf diese Weise kannst du beim Schreiben des Methodenaufrufs entscheiden, welche Implementation du verwenden möchtest. + +![Methodenparameter anzeigen](/assets/develop/misc/using-the-ide/util_02.png) + +### Refactoring {#refactoring} + +Refactoring ist der Prozess der Umstrukturierung von Code, ohne dessen Laufzeitfunktionalität zu verändern. Das sichere Umbenennen und Löschen von Teilen des Codes ist ein Teil davon, aber Dinge wie das Extrahieren von Teilen des Codes in separate Methoden und die Einführung neuer Variablen für wiederholte Code-Anweisungen werden auch als "Refactoring" bezeichnet. + +Viele IDEs verfügen über ein umfangreiches Toolkit, das bei diesem Prozess hilft. In IntelliJ klicke einfach mit der rechten Maustaste auf Dateien oder Teile des Codes, um Zugriff auf die verfügbaren Refactoring-Tools zu erhalten. + +![Refactoring](/assets/develop/misc/using-the-ide/refactoring_01.png) + +Es ist besonders nützlich, sich an die Tastenkombination Shift+F6 zu gewöhnen, da du in der Zukunft wahrscheinlich viele Dinge umbenennen wirst. +Mit dieser Funktion wird jedes Code-Vorkommen des umbenannten Codes umbenannt und bleibt funktionell gleich. + +Du kannst den Code auch entsprechend deinem Codestil umformatieren. +Wähle dazu den Code aus, den du neu formatieren möchtest (wenn nichts ausgewählt ist, wird die gesamte Datei neu formatiert) und drücke ⌘/STRG+⌥/ALT+L. +Um zu ändern, wie IntelliJ Code formatiert, siehst du die Einstellungen unter `Datei > Einstellungen > Editor > Codestil > Java `. + +#### Kontextaktionen {#context-actions} + +Mit Hilfe von Kontextaktionen können bestimmte Codeabschnitte kontextabhängig umgestaltet werden. +Bewege dazu einfach den Mauszeiger auf den Bereich, den du überarbeiten möchtest, und drücke ⌥/ALT+Enter oder klicke Sie auf die Glühbirne auf der linken Seite. +Es erscheint ein Popup-Fenster mit Kontextaktionen, die für den ausgewählten Code verwendet werden können. + +![Beispiel von Kontextaktionen](/assets/develop/misc/using-the-ide/context_actions_01.png) + +![Beispiel von Kontextaktionen](/assets/develop/misc/using-the-ide/context_actions_02.png) + +### Suchen und Ersetzen von Dateiinhalten {#search-and-replace-file-content} + +Manchmal sind einfachere Werkzeuge erforderlich, um Code-Vorkommen zu bearbeiten. + +| Tastenkombination | Funktion | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| ⌘/STRG+F | Finde in der aktuellen Datei | +| ⌘/STRG+R | Ersetze in der aktuellen Datei | +| ⌘/STRG+Shift+F | Finde in einem größeren Bereich (kann spezifische Dateitypmaske einstellen) | +| ⌘/STRG+Shift+R | Ersetze in einem größeren Bereich (kann spezifische Dateitypmaske einstellen) | + +Falls verwendet, ermöglichen alle diese Werkzeuge einen spezifischeren Mustervergleich durch [Regex](https://en.wikipedia.org/wiki/Regular_expression). + +![Regex Ersetzung](/assets/develop/misc/using-the-ide/search_and_replace_01.png) + +### Andere nützliche Tastenkombinationen {#other-keybinds} + +Wenn du einen Text markierst und ⌘/STRG+Shift+↑ Nach oben / ↓ Nach unten verwendest, kannst du den markierten Text nach oben oder unten verschieben. + +In IntelliJ ist die Tastenkombination für `Redo` nicht unbedingt die übliche ⌘/STRG+Y (Zeile löschen). +Stattdessen kann es ⌘/STRG+Shift+Z sein. Du kannst dies in der **Tastaturbelegung** ändern. + + + +Weitere Tastenkombinationen findest du in der [IntelliJ-Dokumentation](https://www.jetbrains.com/help/idea/mastering-keyboard-shortcuts.html). + +## Kommentare {#comments} + +Guter Code sollte leicht lesbar und [selbst-dokumentierend](https://bytedev.medium.com/code-comment-anti-patterns-and-why-the-comment-you-just-wrote-is-probably-not-needed-919a92cf6758) sein. +Die Wahl aussagekräftiger Namen für Variablen, Klassen und Methoden kann sehr hilfreich sein, aber manchmal sind Kommentare notwendig, um Notizen zu hinterlassen oder **vorübergehend** Code zum Testen zu deaktivieren. + +Um Code schneller auszukommentieren, kannst du einen Text markieren und die Tastenkombinationen ⌘/STRG+/ (Zeilenkommentar) und ⌘/STRG+⌥/Shift+/ (Blockkommentar) verwenden. + +Jetzt kannst du den erforderlichen Code markieren (oder einfach den Mauszeiger darauf halten) und die Tastenkombinationen verwenden, um den Abschnitt auszukommentieren. + +```java +// private static final int PROTECTION_BOOTS = 2; +private static final int PROTECTION_LEGGINGS = 5; +// private static final int PROTECTION_CHESTPLATE = 6; +private static final int PROTECTION_HELMET = 1; +``` + +```java +/* +ModItems.initialize(); +ModSounds.initializeSounds(); +ModParticles.initialize(); +*/ + +private static int secondsToTicks(float seconds) { + return (int) (seconds * 20 /*+ 69*/); +} +``` + +### Code-Faltung {#code-folding} + +In IntelliJ kannst du neben den Zeilennummern kleine Pfeil-Symbole sehen. +Diese können verwendet werden, um Methoden, if-Anweisungen, Klassen und viele andere Dinge vorübergehend auszublenden, wenn du nicht aktiv an ihnen arbeitest. +Um einen benutzerdefinierten Block zu erstellen, der eingeklappt werden kann, verwende die Kommentare `region` und `endregion`. + +```java +// region collapse block name + ModBlocks.initialize(); + ModBlockEntities.registerBlockEntityTypes(); + ModItems.initialize(); + ModSounds.initializeSounds(); + ModParticles.initialize(); +// endregion +``` + +![Einklappen von Regionen](/assets/develop/misc/using-the-ide/comments_02.png) + +:::warning +Wenn du feststellst, dass du zu viele davon verwendest, solltest du deinen Code überarbeiten, um ihn lesbarer zu machen! +::: + +### Den Formatierer deaktivieren {#disabling-formatter} + +Kommentare können den Formatierer auch während der oben erwähnten Codeumstrukturierung deaktivieren, indem sie ein Codestück wie folgt umschließen: + +```java +//formatter:off (disable formatter) + public static void disgustingMethod() { /* ew this code sucks */ } +//formatter:on (re-enable the formatter) +``` + +### Unterdrückung von Inspektionen {#noinspection} + +`//noinspection` Kommentare können außerdem auch dazu genutzt werden um Inspektionen und Warnungen zu unterdrücken. +Sie sind funktionell identisch mit der Annotation `@SuppressWarnings`, jedoch ohne die Einschränkung, dass es sich um eine Annotation handelt, und können für Anweisungen verwendet werden. + +```java +// below is bad code and IntelliJ knows that + +@SuppressWarnings("rawtypes") // annotations can be used here +List list = new ArrayList(); + +//noinspection unchecked (annotations cannot be here so we use the comment) +this.processList((List)list); + +//noinspection rawtypes,unchecked,WriteOnlyObject (you can even suppress multiple!) +new ArrayList().add("bananas"); +``` + +:::warning +Wenn du merkst, dass du zu viele Warnungen unterdrückst, solltest du deinen Code so umschreiben, dass er nicht so viele Warnungen erzeugt! +::: + +### TODO und FIXME Notizen {#todo-and-fixme-notes} + +Bei der Arbeit am Code kann es hilfreich sein, Notizen zu hinterlassen, was noch zu erledigen ist. Manchmal entdeckst du auch ein potenzielles Problem im Code, aber du willst nicht aufhören, dich auf das aktuelle Problem zu konzentrieren. Verwende in diesem Fall die Kommentare `TODO` oder `FIXME`. + +![TODO und FIXME Kommentare](/assets/develop/misc/using-the-ide/comments_03.png) + +IntelliJ behält sie im `TODO`-Fenster im Auge und kann dich benachrichtigen, wenn du Code committen willst, der diese Art von Kommentaren verwendet. + +![TODO und FIXME Kommentar](/assets/develop/misc/using-the-ide/comments_04.png) + +![Kommentar mit TODO](/assets/develop/misc/using-the-ide/comments_05.png) + +### JavaDocs {#javadocs} + +Eine gute Möglichkeit, deinen Code zu dokumentieren, ist die Verwendung von JavaDoc. +JavaDocs liefern nicht nur nützliche Informationen zur Implementation von Methoden und Klassen, sondern sind auch tief in IntelliJ integriert. + +Wenn du mit dem Mauszeiger über Methoden- oder Klassennamen fährst, die mit JavaDoc-Kommentaren versehen sind, werden diese Informationen in deren Informationsfenster angezeigt. + +![JavaDoc](/assets/develop/misc/using-the-ide/comments_06.png) + +Um zu beginnen, schreibe einfach `/**` über die Methoden- oder Klassendefinition und drücke die Eingabetaste. IntelliJ erzeugt automatisch Zeilen für den Rückgabewert und die Parameter, aber du kannst sie nach Belieben ändern. Es sind viele benutzerdefinierte Funktionen verfügbar, und du kannst bei Bedarf auch HTML verwenden. + +Minecraft's `ScreenHandler` Klasse hat einige Beispiele. Um die Renderansicht umzuschalten, verwende die Stifttaste neben den Zeilennummern. + +![JavaDoc Bearbeitung](/assets/develop/misc/using-the-ide/comments_07.png) + +## IntelliJ weiter optimieren {#optimizing-intellij-further} + +Es gibt noch viele weitere Abkürzungen und praktische kleine Tricks, die den Rahmen dieser Seite sprengen würden. +Jetbrains hat viele gute Vorträge, Videos und Dokumentationsseiten darüber, wie du deinen Arbeitsbereich weiter anpassen kannst. + +### PostFix Vervollständigung {#postfix-completion} + +Verwende die PostFix Vervollständigung, um Code nach dem Schreiben schnell zu ändern. Häufig verwendete Beispiele sind `.not`, `.if`, `.var`, `.null`, `.nn`, `.for`, `.fori`, `.return` und `.new`. +Neben den bereits vorhandenen kannst du in den Einstellungen von IntelliJ auch eigene erstellen. + + + +### Live-Vorlagen {#live-templates} + +Verwende Live-Vorlagen, um deinen eigenen Vorlagen-Code schneller zu generieren. + + + +### Mehr Tipps und Tricks {#more-tips} + +Anton Arhipov von Jetbrains hielt auch einen ausführlichen Vortrag über Regex Matching, Code Vervollständigung, Debugging und viele andere Themen in IntelliJ. + + + +Für weitere Informationen, sieh dir [Jetbrains Tips & Tricks Seite](https://blog.jetbrains.com/idea/category/tips-tricks) und [IntelliJ's Dokumentation](https://www.jetbrains.com/help/idea/getting-started) an. +Die meisten ihrer Beiträge sind auch auf das Ökosystem von Fabric anwendbar. diff --git a/versions/1.21/translated/de_de/develop/index.md b/versions/1.21/translated/de_de/develop/index.md new file mode 100644 index 000000000..1bbde2eba --- /dev/null +++ b/versions/1.21/translated/de_de/develop/index.md @@ -0,0 +1,14 @@ +--- +title: Leitfäden für Entwickler +description: Unsere von der Community verfassten Leitfäden für Entwickler decken alles ab, von der Einrichtung deiner Entwicklungsumgebung bis hin zu fortgeschrittenen Themen wie Rendering und Networking. +--- + +# Leitfäden für Entwickler {#developer-guides} + +Diese von der Community verfassten Leitfäden decken ein breites Spektrum an Themen ab, von der Einrichtung der Entwicklungsumgebung bis hin zu fortgeschrittenen Bereichen wie Rendering und Networking. + +In der Seitenleiste findest du eine Liste aller verfügbaren Leitfäden. Wenn du nach etwas Bestimmtem suchst, ist die Suchleiste oben auf der Seite dein bester Freund. + +Merke: Ein voll lauffähiger Mod mit all dem Code für diese Dokumentation ist in dem [`/reference` Order auf GitHub](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21) verfügbar. + +Wenn du zur Fabric-Dokumentation beitragen möchtest, findest du den Quellcode auf [GitHub](https://github.com/FabricMC/fabric-docs), und die entsprechenden [Beitragsrichtlinien](../contributing). diff --git a/versions/1.21/translated/de_de/develop/items/custom-armor.md b/versions/1.21/translated/de_de/develop/items/custom-armor.md new file mode 100644 index 000000000..7b1018339 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/custom-armor.md @@ -0,0 +1,160 @@ +--- +title: Benutzerdefinierte Rüstung +description: Lerne, wie du deine eigenen Rüstungssets erstellst. +authors: + - IMB11 +--- + +# Benutzerdefinierte Rüstung {#custom-armor} + +Die Rüstung bietet dem Spieler eine bessere Verteidigung gegen Angriffe von Mobs und anderen Spielern. + +## Eine Rüstungsmaterial Klasse erstellen {#creating-an-armor-materials-class} + +Genau wie Items und Blöcke müssen auch Rüstungsmaterialien registriert werden. Wir werden eine Klasse `ModArmorMaterials` erstellen, um unsere benutzerdefinierten Rüstungsmaterialien zum Zweck der Organisation zu speichern. + +Du musst eine statische Methode `initialize()` zu dieser Klasse hinzufügen und sie vom [Mod-Initialisierer](./getting-started/project-structure#entrypoints) deines Mods aus aufrufen, damit die Materialien registriert werden. + +```java +// Within the ModArmorMaterials class +public static void initialize() {}; +``` + +:::warning +Achte darauf, die Methode **vor** du das Item registrierst aufzurufen, da die Materialien registriert werden müssen, bevor das Item erstellt werden kann. +::: + +```java +@Override +public void onInitialize() { + ModArmorMaterials.initialize(); +} +``` + +--- + +Innerhalb dieser `ModArmorMaterials` Klasse, musst du eine statische Methode erstellen, welche das Rüstungsmaterial registrieren wird. Diese Methode sollte einen Registrierungseintrag für das Material zurückgeben, da dieser Eintrag vom Rüstungsitem-Konstruktor zur Erstellung des Rüstungsitem verwendet wird. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Rüstungsmaterial Eigenschaften {#armor-material-properties} + +:::tip +Wenn du Schwierigkeiten hast, einen guten Wert für eine dieser Eigenschaften zu finden, solltest du dir die Vanilla-Rüstungsmaterialien in der Klasse `ArmorMaterials` ansehen. +::: + +Bei der Erstellung eines Rüstungsmaterials musst du die folgenden Eigenschaften festlegen: + +### Verteidigungspunkte {#defense-points} + +:::warning +Vergewissere dich, dass du jeder Art von Rüstungsteil, die du erstellst und als Item registrieren willst, einen Wert zuweisen. Wenn du ein Item für ein Rüstungsteil ohne einen festgelegten Verteidigungspunktwert machst, wird das Spiel abstürzen. +::: + +Die Map `defensePoints` wird verwendet, um die Anzahl der Verteidigungspunkte zu definieren, die jedes Rüstungsteil zur Verfügung stellen wird. Je höher die Zahl, desto mehr Schutz bietet das Rüstungsteil. Die Map sollte einen Eintrag für jeden Rüstungsteil-Typ enthalten. + +### Verzauberbarkeit {#enchantability} + +Die Eigenschaft `enchantability` bestimmt, wie leicht die Rüstung verzaubert werden kann. Je höher die Zahl, desto mehr Verzauberungen kann die Rüstung erhalten. + +### Ausrüstungssound {#equip-sound} + +Die Eigenschaft `equipSound` ist der Sound, der gespielt wird, wenn die Rüstung ausgerüstet wird. Dieser Sound sollte ein Registry-Eintrag eines `SoundEvent` sein. Wirf einen Blick auf die Seite [Benutzerdefinierte Soundevents](../sounds/custom), wenn du in Erwägung ziehst, benutzerdefinierte Sounds zu erstellen, anstatt dich auf Vanilla-Sounds innerhalb der Klasse `SoundEvents` zu beruhen. + +### Reparaturzutat(en) {#repair-ingredient} + +Die Eigenschaft `repairIngredientSupplier` ist ein Lieferant einer `Ingredient`, die zur Reparatur der Rüstung verwendet wird. Diese Zutat kann so ziemlich alles sein, es wird empfohlen, sie so einzustellen, dass sie mit der Herstellungszutat des Materials übereinstimmt, mit der die Rüstungsgegenstände tatsächlich hergestellt werden. + +### Härte {#toughness} + +Die Eigenschaft `toughness` bestimmt, wie viel Schaden die Rüstung absorbiert. Je höher die Zahl, desto mehr Schaden kann die Rüstung absorbieren. + +### Rückstoßwiderstand {#knockback-resistance} + +Die Eigenschaft `knockbackResistance` legt fest, wie viel Rückstoß der Spieler reflektiert, wenn er getroffen wird. Je höher die Zahl, desto weniger Rückschlag erhält der Spieler. + +### Färbbar {#dyeable} + +Die Eigenschaft `dyeable` ist ein boolescher Wert, der angibt, ob die Rüstung gefärbt werden kann. Wenn diese Option auf `true` gesetzt ist, kann die Rüstung mit Hilfe von Farbstoffen in einer Werkbank gefärbt werden. + +Wenn du dich dafür entscheidest, deine Rüstung färbbar zu machen, muss die Texturen deiner Rüstungsebene und deines Items **für das Färben ausgelegt** sein, da die Farbe die Textur überlagert und nicht ersetzt. Schau dir zum Beispiel die Vanille-Lederrüstung an. Die Texturen sind in Graustufen gehalten und die Farbe wird als Overlay aufgetragen, wodurch die Rüstung ihre Farbe ändert. + +## Das Rüstungsmaterial registrieren {#registering-the-armor-material} + +Nachdem du nun eine Utility-Methode erstellt hast, die zur Registrierung von Rüstungsmaterialien verwendet werden kann, kannst du deine benutzerdefinierten Rüstungsmaterialien als statisches Feld in der Klasse `ModArmorMaterials` registrieren. + +In diesem Beispiel werden wir eine Guidite-Rüstung mit den folgenden Eigenschaften erstellen: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Rüstungsitems erstellen {#creating-the-armor-items} + +Nachdem du das Material registriert hast, kannst du die Rüstungsitems in deiner Klasse `ModItems` erstellen: + +Natürlich muss ein Rüstungsset nicht jeden Typ abdecken, man kann auch ein Set mit nur Stiefeln oder Hosen etc. haben. - Der Vanille-Schildkrötenpanzerhelm ist ein gutes Beispiel für ein Rüstungsset mit fehlenden Slots. + +### Haltbarkeit {#durability} + +Im Gegensatz zu `ToolMaterial` speichert `ArmorMaterial` keine Informationen über die Haltbarkeit von Items. +Aus diesem Grund muss die Haltbarkeit manuell zu den `Item.Settings` der Rüstungsitems hinzugefügt werden, wenn diese registriert werden. + +Dies kann durch die Methode `maxDamage` in der Klasse `Item.Settings` bewirkt werden. +Die verschiedenen Rüstungsslots haben unterschiedliche Grundhaltbarkeiten, die üblicherweise mit einem gemeinsamen Multiplikator des Rüstungsmaterials multipliziert werden, es können aber auch fest kodierte Werte verwendet werden. + +Für die Guidite-Rüstung werden wir einen gemeinsamen Multiplikator für die Rüstung verwenden, der zusammen mit dem Rüstungsmaterial gespeichert wird: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +Anschließend können wir die Rüstungsitems unter Verwendung der Haltbarkeitskonstante erstellen: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Außerdem musst du die Items **einer Itemgruppe hinzufügen**, wenn du möchtest, dass sie über das kreative Inventar zugänglich sind. + +Wie bei allen Items solltest du auch für diese Übersetzungsschlüssel erstellen. + +## Texturierung und Modellierung {#texturing-and-modelling} + +Du wirst zwei Sets von Texturen erstellen müssen: + +- Texturen und Modelle für die Items selbst. +- Die eigentliche Rüstungstextur, die sichtbar ist, wenn eine Entität die Rüstung trägt. + +### Itemtexturen und Modell {#item-textures-and-model} + +Diese Texturen unterscheiden sich nicht von anderen Items - Du musst die Texturen erstellen und ein generisches Itemmodell erstellen, was in der Anleitung [Erstellen des ersten Items](./first-item#adding-a-texture-and-model) behandelt wurde. + +Als Beispiel dient das folgende Textur- und Modell-JSON als Referenz. + +Item Texturen + +:::info +Du benötigst JSON-Modelldateien für alle Gegenstände, nicht nur für den Helm. Es ist das gleiche Prinzip wie bei anderen Itemmodellen. +::: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json) + +Wie du sehen kannst, sollten die Rüstungsitems im Spiel geeignete Modelle haben: + +![Rüstungsitem Modelle](/assets/develop/items/armor_1.png) + +## Rüstungstexturen und Modelle {#armor-textures-and-model} + +Wenn eine Entität deine Rüstung trägt, wird die fehlende Textur angezeigt: + +![Kaputtes Rüstungsmodell an einem Spieler](/assets/develop/items/armor_2.png) + +Es gibt zwei Schichten für die Rüstungstextur, beide müssen vorhanden sein. + +Da der Name des Rüstungsmaterial in unserem Fall `guidite` lautet, werden die Texturen wie folgt angeordnet: + +- `assets//textures/models/armor/guidite_layer_1.png` +- `assets//textures/models/armor/guidite_layer_2.png` + +Rüstungsmodell Texturen + +Die erste Schicht enthält Texturen für den Helm und den Brustpanzer, während die zweite Schicht Texturen für Hosen und Stiefel enthält. + +Wenn diese Texturen vorhanden sind, solltest du deine Rüstung auf Entitäten sehen können, die sie tragen: + +![Funktionierendes Rüstungsmodell an einem Spieler](/assets/develop/items/armor_3.png) diff --git a/versions/1.21/translated/de_de/develop/items/custom-data-components.md b/versions/1.21/translated/de_de/develop/items/custom-data-components.md new file mode 100644 index 000000000..78e0a733b --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/custom-data-components.md @@ -0,0 +1,271 @@ +--- +title: Benutzerdefinierte Datenkomponenten +description: Lerne, wie du benutzerdefinierte Datenkomponenten zu deinen Items mit Hilfe des neuen 1.20.5 Komponenten-System hinzufügst. +authors: + - Romejanic +--- + +# Benutzerdefinierte Datenkomponenten {#custom-data-components} + +Je komplexer deine Items werden, desto mehr benutzerdefinierte Daten musst du vielleicht für jedes Item speichern. Das Spiel erlaubt es, persistente Daten in einem `ItemStack` zu speichern, und seit der Version 1.20.5 tun wir das mit Hilfe von **Datenkomponenten**. + +Datenkomponenten ersetzen NBT-Daten aus früheren Versionen durch strukturierte Datentypen, die auf einen `ItemStack` angewendet werden können, um dauerhafte Daten über diesen Stack zu speichern. Datenkomponenten sind namensgebunden, was bedeutet, dass wir unsere eigenen Datenkomponenten implementieren können, um benutzerdefinierte Daten über einen `ItemStack` zu speichern und später darauf zuzugreifen. Eine vollständige Liste der Vanilla-Datenkomponenten kann auf dieser [Minecraft-Wiki-Seite](https://minecraft.wiki/w/Data_component_format#List_of_components) gefunden werden. + +Neben der Registrierung von benutzerdefinierten Komponenten wird auf dieser Seite auch die allgemeine Verwendung der Komponenten-API behandelt, die auch für Vanilla-Komponenten gilt. Du kannst die Definitionen aller Vanilla-Komponenten in der Klasse `DataComponentTypes` sehen und darauf zugreifen. + +## Eine Komponente registrieren {#registering-a-component} + +Wie bei allem anderen in deinem Mod musst du deine benutzerdefinierte Komponente mit einem `ComponentType` registrieren. Dieser Komponententyp nimmt ein generisches Argument entgegen, das den Typ des Wertes deiner Komponente enthält. Darauf werden wir weiter unten bei der Behandlung von [einfachen](#basic-data-components) und [fortgeschrittenen](#advanced-data-components) Komponenten näher eingehen. + +Wähle eine sinnvolle Klasse, in der du dies unterbringen kannst. Für dieses Beispiel werden wir ein neues Paket namens `component` und eine Klasse erstellen, die alle unsere Komponententypen enthält und `ModComponents` heißt. Stelle sicher, dass du `ModComponents.initialize()` in deinem [Mod-Initialisierer](./getting-started/project-structure#entrypoints) aufrufst. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Dies ist die grundlegende Vorlage für die Registrierung eines Component Typs: + +```java +public static final ComponentType MY_COMPONENT_TYPE = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "my_component"), + ComponentType.builder().codec(null).build() +); +``` + +Hier gibt es einige Dinge zu beachten. In der ersten und vierten Zeile ist ein `?` zu sehen. Dieser wird durch den Typ des Wertes deiner Komponente ersetzt. Wir werden das bald befüllen. + +Zweitens musst du einen `Identifier` angeben, der die beabsichtigte ID deiner Komponente enthält. Diese ist mit der Mod-ID deines Mods verknüpft. + +Schließlich haben wir einen `ComponentType.Builder`, der die eigentliche `ComponentType`-Instanz erstellt, die registriert wird. Dies enthält ein weiteres wichtiges Detail, das wir besprechen müssen: den `Codec`. deiner Komponente. Dies ist derzeit `null`, aber wir werden es auch bald befüllen. + +## Einfache Datenkomponenten {#basic-data-components} + +Einfache Datenkomponenten (wie `minecraft:damage`) bestehen aus einzelnen Datenwerten, wie einem `int`, `float`, `boolean` oder `String`. + +Als Beispiel wollen wir einen `Integer`-Wert erstellen, der festhält, wie oft der Spieler mit der rechten Maustaste geklickt hat, während er unseren Gegenstand hielt. Aktualisieren wir unsere Komponentenregistrierung wie folgt: + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Du kannst sehen, dass wir jetzt `` als unseren generischen Typ übergeben, was anzeigt, dass diese Komponente als ein einzelner `int` Wert gespeichert wird. Für unseren Codec verwenden wir den mitgelieferten `Codec.INT` Codec. Für einfache Komponenten wie diese können wir mit einfachen Codecs auskommen, aber komplexere Szenarien erfordern möglicherweise einen benutzerdefinierten Codec (dies wird später kurz behandelt). + +Wenn du das Spiel startest, solltest du einen Befehl wie diesen eingeben können: + +![/give Befehl, welcher due benutzerdefinierte Komponente zeigt](/assets/develop/items/custom_component_0.png) + +Wenn du den Befehl ausführst, solltest du das Element erhalten, das die Komponente enthält. Allerdings verwenden wir unsere Komponente derzeit nicht für irgendetwas Nützliches. Beginnen wir damit, den Wert der Komponente so zu lesen, dass wir ihn sehen können. + +## Den Komponentenwert lesen {#reading-component-value} + +Fügen wir ein neues Item hinzu, das den Zähler jedes Mal erhöht, wenn es mit der rechten Maustaste angeklickt wird. Du solltest die Seite [Benutzerdefinierte Iteminteraktionen](./custom-item-interactions) lesen, die die Techniken behandelt, die wir in diesem Leitfaden verwenden werden. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Denke wie üblich daran, das Item in deiner Klasse `ModItems` zu registrieren. + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings() +), "counter"); +``` + +Wir werden einen Tooltip-Code hinzufügen, um den aktuellen Wert der Klickzahl anzuzeigen, wenn wir mit dem Mauszeiger über unser Item im Inventar fahren. Wir können die Methode `get()` auf unserem `ItemStack` verwenden, um den Wert unserer Komponente wie folgt zu erhalten: + +```java +int clickCount = stack.get(ModComponents.CLICK_COUNT_COMPONENT); +``` + +Dadurch wird der aktuelle Wert der Komponente als der Typ zurückgegeben, den wir bei der Registrierung unserer Komponente definiert haben. Diesen Wert können wir dann verwenden, um einen Tooltip-Eintrag hinzuzufügen. Füge diese Zeile der Methode `appendTooltip` in der Klasse `CounterItem` hinzu: + +```java +public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + int count = stack.get(ModComponents.CLICK_COUNT_COMPONENT); + tooltip.add(Text.translatable("item.fabric-docs-reference.counter.info", count).formatted(Formatting.GOLD)); +} +``` + +Vergiss nicht, deine Sprachdatei (`/assets//lang/en_us.json`) zu aktualisieren und diese zwei Zeilen hinzuzufügen: + +```json +{ + "item.fabric-docs-reference.counter": "Counter", + "item.fabric-docs-reference.counter.info": "Used %1$s times" +} +``` + +Starte das Spiel und führe diesen Befehl aus, um dir ein neues Zähler Item mit einer Anzahl von 5 zu geben. + +```mcfunction +/give @p fabric-docs-reference:counter[fabric-docs-reference:click_count=5] +``` + +Wenn du den Mauszeiger über dieses Item in deinem Inventar bewegst, solltest du die Anzahl im Tooltip sehen! + +![Tooltip zeigt "Used 5 times"](/assets/develop/items/custom_component_1.png) + +Wenn du dir jedoch ein neues Counter Item _ohne_ die benutzerdefinierte Komponente gibst, stürzt das Spiel ab, wenn du den Mauszeiger über den Gegenstand in deinem Inventar bewegst. Im Absturzbericht sollte ein Fehler wie dieser angezeigt werden: + +```log +java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "net.minecraft.item.ItemStack.get(net.minecraft.component.ComponentType)" is null + at com.example.docs.item.custom.CounterItem.appendTooltip(LightningStick.java:45) + at net.minecraft.item.ItemStack.getTooltip(ItemStack.java:767) +``` + +Da der `ItemStack` derzeit keine Instanz unserer benutzerdefinierten Komponente enthält, wird der Aufruf von `stack.get()` mit unserem Komponententyp erwartungsgemäß `null` zurückgeben. + +Es gibt drei Lösungen, mit denen wir dieses Problem angehen können. + +### Ein Standard Wert für die Komponente setzen {#setting-default-value} + +Wenn du deinen Artikel registrierst und ein `Item.Settings`-Objekt an deinen Item Konstruktor übergibst, kannst du auch eine Liste von Standardkomponenten angeben, die auf alle neuen Items angewendet werden. Wenn wir zu unserer Klasse `ModItems` zurückkehren, wo wir das `CounterItem`, registrieren, können wir einen Standardwert für unsere benutzerdefinierte Komponente hinzufügen. Füge dies hinzu, damit bei neuen Einträgen die Anzahl `0` angezeigt wird. + +@[code transcludeWith=::_13](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Wenn ein neues Item erstellt wird, wird automatisch unsere benutzerdefinierte Komponente mit dem angegebenen Wert angewendet. + +:::warning +Mit Hilfe von Befehlen ist es möglich, eine Standardkomponente aus einem `ItemStack` zu entfernen. In den nächsten beiden Abschnitten erfährst du, wie du vorgehen musst, wenn die Komponente in deinem Item nicht vorhanden ist. +::: + +### Lesen mit einem Standardwert {#reading-default-value} + +Außerdem können wir beim Lesen des Komponentenwerts die Methode `getOrDefault()` auf unserem Objekt `ItemStack` verwenden, um einen bestimmten Standardwert zurückzugeben, wenn die Komponente nicht auf dem Stack vorhanden ist. Dadurch werden Fehler vermieden, die durch eine fehlende Komponente entstehen. Wir können unseren Tooltip-Code wie folgt anpassen: + +```java +int clickCount = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); +``` + +Wie du sehen kannst, benötigt diese Methode zwei Argumente: Unseren Komponententyp wie zuvor und einen Standardwert, der zurückgegeben wird, wenn die Komponente nicht vorhanden ist. + +### Prüfen, ob eine Komponente existiert {#checking-if-component-exists} + +Mit der Methode `contains()` kann auch geprüft werden, ob eine bestimmte Komponente auf einem `ItemStack` vorhanden ist. Sie nimmt den Komponententyp als Argument und gibt `true` oder `false` zurück, je nachdem, ob der Stack diese Komponente enthält. + +```java +boolean exists = stack.contains(ModComponents.CLICK_COUNT_COMPONENT); +``` + +### Den Fehler beheben {#fixing-the-error} + +Wir fahren mit der dritten Option fort. Wir fügen also nicht nur einen Standardkomponentenwert hinzu, sondern prüfen auch, ob die Komponente auf dem Stack vorhanden ist, und zeigen den Tooltip nur an, wenn dies der Fall ist. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Starte das Spiel erneut und fahre mit dem Mauszeiger über das Item ohne die Komponente. Du solltest sehen, dass er "Used 0 times" anzeigt und das Spiel nicht mehr abstürzt. + +![Tooltip zeigt "Used 0 times"](/assets/develop/items/custom_component_2.png) + +Versuche, dir selbst einen Counter zu geben, indem du unsere benutzerdefinierte Komponente entfernst. Du kannst diesen Befehl nutzen, um dies zu tun: + +```mcfunction +/give @p fabric-docs-reference:counter[!fabric-docs-reference:click_count] +``` + +Wenn du den Mauszeiger über dieses Element bewegst, sollte der Tooltip fehlen. + +![Counter Item ohne Tooltip](/assets/develop/items/custom_component_7.png) + +## Einen Komponentenwert aktualisieren {#setting-component-value} + +Lass uns nun versuchen, unseren Komponentenwert zu aktualisieren. Wir werden die Anzahl der Klicks jedes Mal erhöhen, wenn wir unser Counter Item verwenden. Um den Wert einer Komponente auf einem `ItemStack` zu ändern, verwenden wir die Methode `set()` wie folgt: + +```java +stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Hier wird unser Komponententyp und der Wert, auf den wir ihn setzen wollen, verwendet. In diesem Fall ist das unsere neue Klickzahl. Diese Methode gibt auch den alten Wert der Komponente zurück (falls vorhanden), was in manchen Situationen nützlich sein kann. Zum Beispiel: + +```java +int oldValue = stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Richten wir eine neue Methode `use()` ein, um die alte Klickzahl zu lesen, sie um eins zu erhöhen und dann die aktualisierte Klickzahl zu setzen. + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Starte nun das Spiel und klicke mit der rechten Maustaste auf den Counter in deiner Hand. Wenn du dein Inventar öffnest und dir das Item noch einmal ansiehst, solltest du sehen, dass die Nutzungszahl um die Anzahl der Klicks gestiegen ist, die du darauf gemacht hast. + +![Tooltip zeigt "Used 8 times"](/assets/develop/items/custom_component_3.png) + +## Einen Komponentenwert entfernen {#removing-component-value} + +Du kannst auch eine Komponente von deinem `ItemStack` entfernen, wenn sie nicht mehr benötigt wird. Dies geschieht mit der Methode `remove()`, die deinen Komponententyp entgegennimmt. + +```java +stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +Diese Methode gibt auch den Wert der Komponente zurück, bevor sie entfernt wird, sodass du sie auch wie folgt verwenden kannst: + +```java +int oldCount = stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +## Fortgeschrittene Datenkomponenten {#advanced-data-components} + +Möglicherweise musst du mehrere Attribute in einer einzigen Komponente speichern. Als Vanilla-Beispiel speichert die Komponente `minecraft:food` mehrere Werte in Bezug auf Nahrung, wie `nutrition`, `saturation`, `eat_seconds` und mehr. In diesem Leitfaden werden sie als "zusammengesetzte" Komponenten bezeichnet. + +Für zusammengesetzte Komponenten musst du eine `record`-Klasse erstellen, um die Daten zu speichern. Dies ist der Typ, den wir in unserem Komponententyp registrieren und den wir lesen und schreiben werden, wenn wir mit einem `ItemStack` interagieren. Beginne mit der Erstellung einer neuen Record-Klasse im Paket `component`, das wir zuvor erstellt haben. + +```java +public record MyCustomComponent() { +} +``` + +Beachte, dass sich nach dem Klassennamen Klammern befinden. Hier definieren wir die Liste der Eigenschaften, die unsere Komponente haben soll. Fügen wir eine Fließkommazahl und einen booleschen Wert mit den Bezeichnungen `temperature` und `burnt` hinzu. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Da wir eine benutzerdefinierte Datenstruktur definieren, gibt es für unseren Anwendungsfall keinen bereits vorhandenen `Codec` wie bei den [einfachen Komponenten](#basic-data-components). Das bedeutet, dass wir unseren eigenen Codec konstruieren müssen. Definieren wir einen in unsere Record-Klasse mit einem `RecordCodecBuilder`, auf den wir verweisen können, sobald wir die Komponente registrieren. Weitere Einzelheiten zur Verwendung eines `RecordCodecBuilder` findest du in [diesem Abschnitt der Codecs-Seite](../codecs#merging-codecs-for-record-like-classes). + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Du kannst sehen, dass wir eine Liste von benutzerdefinierten Feldern auf der Grundlage der primitiven `Codec`-Typen definieren. Wir teilen dem Spiel jedoch auch mit, wie unsere Felder heißen, indem wir `fieldOf()` verwenden und dann `forGetter()` benutzen, um dem Spiel mitzuteilen, welches Attribut unseres Datensatzes es füllen soll. + +Du kannst auch optionale Felder definieren, indem du `optionalFieldOf()` verwendest und einen Standardwert als zweites Argument übergibst. Alle Felder, die nicht als optional gekennzeichnet sind, werden benötigt, wenn die Komponente mit `/give` erstellt wird, also stelle sicher, dass du alle optionalen Argumente als solche kennzeichnest, wenn du deinen Codec erstellst. + +Schließlich rufen wir `apply()` auf und übergeben den Konstruktor unseres Datensatzes. Weitere Einzelheiten über die Erstellung von Codecs und fortgeschrittene Anwendungsfälle findest du auf der Seite [Codecs](../codecs). + +Die Registrierung einer zusammengesetzten Komponente ist ähnlich wie zuvor. Wir übergeben einfach unsere Record-Klasse als generischen Typ und unseren benutzerdefinierten `Codec` an die Methode `codec()`. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Starte jetzt das Spiel. Versuche, die Komponente mit dem Befehl `/give` anzuwenden. Zusammengesetzte Komponentenwerte werden als ein mit `{}` umschlossenes Objekt übergeben. Wenn du leere geschweifte Klammern einfügst, wird eine Fehlermeldung angezeigt, die besagt, dass der erforderliche Schlüssel `temperature` fehlt. + +![Give-Befehl, der den fehlenden Schlüssel "temperature" zeigt](/assets/develop/items/custom_component_4.png) + +Füge dem Objekt einen Temperaturwert mit dem Syntax `temperature:8.2` hinzu. Du kannst auch optional einen Wert für `burnt` mit dem gleichen Syntax übergeben, aber entweder `true` oder `false`. Du solltest nun sehen, dass der Befehl gültig ist und dir ein Item mit der Komponente liefern kann. + +![Gültiger give-Befehl, der beide Eigenschaften zeigt](/assets/develop/items/custom_component_5.png) + +### Abrufen, Setzen und Entfernen von fortgeschrittenen Komponenten {#getting-setting-removing-advanced-comps} + +Die Verwendung der Komponente im Code ist die gleiche wie zuvor. Die Verwendung von `stack.get()` gibt eine Instanz der Klasse `record` zurück, die Sie dann zum Lesen der Werte verwenden können. Da Datensätze schreibgeschützt sind, musst du eine neue Instanz deines Datensatzes erstellen, um die Werte zu aktualisieren. + +```java +// read values of component +MyCustomComponent comp = stack.get(ModComponents.MY_CUSTOM_COMPONENT); +float temp = comp.temperature(); +boolean burnt = comp.burnt(); + +// set new component values +stack.set(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(8.4f, true)); + +// check for component +if (stack.contains(ModComponents.MY_CUSTOM_COMPONENT)) { + // do something +} + +// remove component +stack.remove(ModComponents.MY_CUSTOM_COMPONENT); +``` + +Du kannst auch einen Standardwert für eine zusammengesetzte Komponente festlegen, indem du ein Komponenten-Objekt an deine `Item.Settings` übergibst. Zum Beispiel: + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings().component(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(0.0f, false)) +), "counter"); +``` + +Jetzt kannst du benutzerdefinierte Daten an einem `ItemStack` speichern. Nutze dies mit Bedacht! + +![Item zeigt einen Tooltip für die Klickzahl, Temperatur und Brennzustand](/assets/develop/items/custom_component_6.png) diff --git a/versions/1.21/translated/de_de/develop/items/custom-enchantment-effects.md b/versions/1.21/translated/de_de/develop/items/custom-enchantment-effects.md new file mode 100644 index 000000000..53c41f1dc --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/custom-enchantment-effects.md @@ -0,0 +1,62 @@ +--- +title: Benutzerdefinierte Verzauberungseffekte +description: Lerne, wie du deine eigenen Verzauberungseffekte erstellst. +authors: + - krizh-p +--- + +# Benutzerdefinierte Verzauberungen {#custom-enchantments} + +Ab der Version 1.21 verwenden benutzerdefinierte Verzauberungen in Minecraft einen "datengesteuerten" Ansatz. Das macht es einfacher, einfache Verzauberungen hinzuzufügen, wie z. B. die Erhöhung des Angriffsschadens, aber schwieriger, komplexe Verzauberungen zu erstellen. Dabei werden die Verzauberungen in _Effektkomponenten_ zerlegt. + +Eine Effektkomponente enthält den Code, der die speziellen Effekte einer Verzauberung definiert. Minecraft unterstützt verschiedene Standardeffekte, wie z. B. Schaden, Rückschlag und Erfahrung. + +:::tip +Überprüfe, ob die Standard-Minecraft-Effekte deinen Bedürfnissen entsprechen, indem du [die Seite der Verzauberungseffekt-Komponenten im Minecraft-Wiki](https://de.minecraft.wiki/w/Verzauberungsdefinition#Effektkomponenten) besuchst. Dieser Leitfaden setzt voraus, dass du weißt, wie man "einfache" datengesteuerte Verzauberungen konfiguriert und konzentriert sich auf die Erstellung von benutzerdefinierten Verzauberungseffekten, die nicht standardmäßig unterstützt werden. +::: + +## Benutzerdefinierte Verzauberungseffekte {#custom-enchantment-effects} + +Starte mit der Erstellung eines Ordners `enchantment` und erstelle innerhalb dieses Ordners einen Ordner `effect`. Darin erstellen wir den Record `LightningEnchantmentEffect`. + +Als nächstes können wir einen Konstruktor erstellen und die Methoden des Interfaces `EnchantmentEntityEffect` überschreiben. Wir werden auch eine `CODEC`-Variable erstellen, um unseren Effekt zu kodieren und zu dekodieren; Du kannst [hier](../codecs) mehr über Codecs lesen. + +Der Großteil unseres Codes wird in das Ereignis `apply()` einfließen, das aufgerufen wird, wenn die Kriterien für die Wirkung der Verzauberung erfüllt sind. Wir werden diesen `Effect` später so konfigurieren, dass er aufgerufen wird, wenn eine Entität getroffen wird, aber für den Moment wollen wir einfachen Code schreiben, um das Ziel mit einem Blitz zu treffen. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/enchantment/effect/LightningEnchantmentEffect.java) + +Hier gibt die Variable `amount` einen Wert an, der auf die Stufe der Verzauberung abgestimmt ist. Auf diese Weise können wir die Wirksamkeit der Verzauberung je nach Stufe verändern. Im obigen Code verwenden wir die Stufe der Verzauberung, um zu bestimmen, wie viele Blitze erzeugt werden. + +## Den Verzauberungseffekt registrieren {#registering-the-enchantment-effect} + +Wie jede andere Komponente deines Mods müssen wir auch diesen `EnchantmentEffect` zur Minecraft-Registry hinzufügen. Füge hierzu eine Klasse `ModEnchantmentEffects` (oder wie immer du sie nennen willst) und eine Hilfsmethode zur Registrierung der Verzauberung hinzu. Stelle sicher, dass die Methode `registerModEnchantmentEffects()` in deiner Hauptklasse aufrufen wird, die die Methode `onInitialize()` enthält. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/enchantment/ModEnchantmentEffects.java) + +## Die Verzauberung erstellen {#creating-the-enchantment} + +Jetzt haben wir einen Verzauberungseffekt! Der letzte Schritt besteht darin, eine Verzauberung zu erstellen, die unseren benutzerdefinierten Effekt anwendet. Dies kann zwar durch die Erstellung einer JSON-Datei ähnlich der in Datenpaketen erfolgen, aber diese Anleitung zeigt dir, wie du das JSON dynamisch mit den Datengenerierungswerkzeugen von Fabric erzeugen kannst. Um zu beginnen, erstelle eine Klasse `EnchantmentGenerator`. + +In dieser Klasse werden wir zunächst eine neue Verzauberung registrieren und dann die Methode `configure()` verwenden, um unser JSON programmatisch zu erstellen. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java) + +Bevor du fortfährst, solltest du sicherstellen, dass dein Projekt für die Datengenerierung konfiguriert ist; wenn du dir unsicher bist, [sieh dir die entsprechende Dokumentations-Seite an](../data-generation/setup). + +Zum Schluss müssen wir unserem Mod sagen, dass er unseren `EnchantmentGenerator` zur Liste der Datenerzeugungsaufgaben hinzufügen soll. Um dies zu tun, füge einfach den `EnchantmentGenerator` innerhalb der Methode `onInitializeDataGenerator` zu dieser hinzu. + +@[code transclude={22-22}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +Wenn du nun die Datengenerierungsaufgabe deines Mods ausführst, werden die Verzauberungs-JSONs im Ordner `generated` generiert. Ein Beispiel ist unten zu sehen: + +@[code](@/reference/1.21/src/main/generated/data/fabric-docs-reference/enchantment/thundering.json) + +Du solltest auch Übersetzungen zu deiner `en_us.json` Datei hinzufügen, um deiner Verzauberung einen lesbaren Namen zu geben: + +```json +"enchantment.FabricDocsReference.thundering": "Thundering", +``` + +Du solltest jetzt einen funktionierenden, benutzerdefinierten Verzauberungseffekt haben! Teste es, indem du eine Waffe mit der Verzauberung verzauberst und einen Mob triffst. Ein Beispiel wird im folgenden Video gezeigt: + + diff --git a/versions/1.21/translated/de_de/develop/items/custom-item-groups.md b/versions/1.21/translated/de_de/develop/items/custom-item-groups.md new file mode 100644 index 000000000..a09eb887b --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/custom-item-groups.md @@ -0,0 +1,38 @@ +--- +title: Benutzerdefinierte Itemgruppen +description: Lerne, wie du deine eigenen Itemgruppen erstellst und Items hinzufügst. +authors: + - IMB11 +--- + +# Benutzerdefinierte Itemgruppen {#custom-item-groups} + +Itemgruppen sind die Registerkarten im kreativen Inventar, in denen Items gespeichert werden. Du kannst deine eigenen Itemgruppen erstellen und deine Items in einem speraten Tab speichern. Das ist ziemlich nützlich, wenn dein Mod viele Items hinzufügt und du sie an einem Ort organisieren möchtest, damit deine Spieler leicht darauf zugreifen können. + +## Die Itemgruppe erstellen {#creating-the-item-group} + +Es ist überaschend einfach eine Itemgruppe zu erstellen. Erstell einfach ein neues statisches finales Feld in deiner Itemklasse, um die Itemgruppe und einen Registrierungsschlüssel dafür zu speichern, dann kannst du das Itemgruppen-Ereignis ähnlich verwenden, wie du deine Items zu den Vanilla Itemgruppen hinzugefügt hast: + +@[code transcludeWith=:::9](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::_12](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +
+ +Du solltest sehen, dass die Itemgruppe jetzt im kreativen Inventar ist. Es ist jedoch unübersetzt - du musst deiner Übersetzungsdatei einen Übersetzungsschlüssel hinzufügen - ähnlich wie du dein erstes Item übersetzt hast. + +![Itemgruppe ohne Übersetzungsschlüssel im kreativen Menü](/assets/develop/items/itemgroups_0.png) + +## Einen Übersetzungsschlüssel hinzufügen {#adding-a-translation-key} + +Wenn du `Text.translatable` für die Methode `displayName` des Itemgruppen Builders verwendet hast, musst du die Übersetzung zu deiner Sprachdatei hinzufügen. + +```json +{ + "itemGroup.fabric_docs_reference": "Fabric Docs Reference" +} +``` + +Wie du sehen kannst, sollte die Itemgruppe nun korrekt benannt sein: + +![Vollständig fertiggestellte Itemgruppe mit Übersetzung und Items](/assets/develop/items/itemgroups_1.png) diff --git a/versions/1.21/translated/de_de/develop/items/custom-item-interactions.md b/versions/1.21/translated/de_de/develop/items/custom-item-interactions.md new file mode 100644 index 000000000..9cda5804c --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/custom-item-interactions.md @@ -0,0 +1,71 @@ +--- +title: Benutzerdefinierte Item-Interaktionen +description: Lerne, wie man ein Item erstellt, welches eingebaute Vanilla Events nutzt. +authors: + - IMB11 +--- + +# Benutzerdefinierte Item-Interaktionen {#custom-item-interactions} + +Mit einfachen Items ist es nicht getan - irgendwann braucht man ein Item, das mit der Welt interagiert, wenn es benutzt wird. + +Es gibt einige Schlüsselklassen, die du verstehen musst, bevor du einen Blick auf die Vanilla-Item-Events wirfst. + +## TypedActionResult {#typedactionresult} + +Bei Items ist das häufigste `TypedActionResult` für `ItemStacks` - diese Klasse sagt dem Spiel, was der Item-Stack ersetzen soll (oder nicht), nachdem das Event eingetreten ist. + +Wenn in dem Event nichts vorgefallen ist, solltest du die Methode `TypedActionResult#pass(stack)` verwenden, wobei `stack` der aktuelle Item-Stack ist. + +Du kannst den aktuellen Item-Stack ermitteln, indem du den Stack in der Hand des Spielers abrufst. Normalerweise übergeben Events, die ein `TypedActionResult` erfordern, die Hand an die Eventmethode. + +```java +TypedActionResult.pass(user.getStackInHand(hand)) +``` + +Wenn du den aktuellen Stack übergibst, wird sich nichts ändern, unabhängig davon, ob du das Event als fehlgeschlagen, bestanden/ignoriert oder erfolgreich deklarierst. + +Wenn du den aktuellen Stack löschen willst, solltest du einen leeren Stack übergeben. Dasselbe gilt für das Dekrementieren: Du holst den aktuellen Stapel und dekrementierst ihn um den gewünschten Betrag: + +```java +ItemStack heldStack = user.getStackInHand(hand); +heldStack.decrement(1); +TypedActionResult.success(heldStack); +``` + +## ActionResult {#actionresult} + +In ähnlicher Weise teilt ein `ActionResult` dem Spiel den Status des Events mit, ob es bestanden/ignoriert, fehlgeschlagen oder erfolgreich war. + +## Überschreibbare Events {#overridable-events} + +Glücklicherweise verfügt die Klasse Item über viele Methoden, die überschrieben werden können, um zusätzliche Funktionen zu deinen Items hinzuzufügen. + +:::info +Ein hervorragendes Beispiel für die Verwendung dieser Events findet sich auf der Seite [SoundEvents abspielen](../sounds/using-sounds), die das Ereignis `useOnBlock` verwendet, um einen Sound abzuspielen, wenn der Spieler mit der rechten Maustaste auf einen Block klickt. +::: + +| Methode | Informationen | +| --------------- | ----------------------------------------------------------------------------------------- | +| `postHit` | Ausgeführt, wenn ein Spieler eine Entität schlägt. | +| `postMine` | Ausgeführt, wenn ein Spieler einen Block abbaut. | +| `inventoryTick` | Jeden Tick ausgeführt, solange das Item im Inventar ist. | +| `onCraft` | Ausgeführt, wenn das Item hergestellt wurde. | +| `useOnBlock` | Ausgeführt, wenn der Spieler auf einen Block mit einem Item rechtsklickt. | +| `use` | Ausgeführt, wenn ein Spieler ein Item rechtsklickt. | + +## Das `use()` Event {#use-event} + +Angenommen, du möchtest ein Item erstellen, das einen Blitz vor dem Spieler herbeiruft - dann musst du eine benutzerdefinierte Klasse erstellen. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Das `use`-Event ist wahrscheinlich das nützlichste von allen - du kannst dieses Event benutzen, um unseren Blitz zu erschaffen, du solltest ihn 10 Blöcke vor dem Spieler spawnen, in dessen Richtung er schaut. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Wie üblich solltest du deine Items registrieren, ein Modell und eine Textur hinzufügen. + +Wie du sehen kannst, sollte der Blitz 10 Blöcke vor dir - dem Spieler - erscheinen. + + diff --git a/versions/1.21/translated/de_de/develop/items/custom-tools.md b/versions/1.21/translated/de_de/develop/items/custom-tools.md new file mode 100644 index 000000000..2f9f20538 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/custom-tools.md @@ -0,0 +1,104 @@ +--- +title: Werkzeuge und Waffen +description: Lerne, wie du deine eigenen Werkzeuge erstellst und deren Eigenschaften konfigurierst. +authors: + - IMB11 +--- + +# Werkzeuge {#tools} + +Werkzeuge sind für das Überleben und das Vorankommen unerlässlich, denn sie ermöglichen es den Spielern, Ressourcen zu sammeln, Gebäude zu bauen und sich zu verteidigen. + +## Ein Werkzeugmaterial erstellen {#creating-a-tool-material} + +::: info +If you're creating multiple tool materials, consider using an `Enum` to store them. Vanilla does this in the `ToolMaterials` class, which stores all the tool materials that are used in the game. + +Diese Klasse kann auch verwendet werden, um die Eigenschaften deines Werkzeugmaterials im Verhältnis zu Vanilla-Werkzeugmaterialien zu bestimmen. +::: + +Du kannst ein Werkzeugmaterial erstellen, indem du eine neue Klasse erstellst, die es erbt - in diesem Beispiel werde ich "Guidite"-Werkzeuge erstellen: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Sobald du dein Werkzeugmaterial erstellt und nach deinen Wünschen angepasst hast, kannst du eine Instanz davon erstellen, die in den Konstruktoren der Werkzeugitems verwendet werden kann. + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Das Werkzeugmaterial gibt dem Spiel die folgenden Informationen: + +### Haltbarkeit - `getDurability()` {#durability} + +Wie oft das Werkzeug verwendet werden kann, bevor es bricht: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Abbaugeschwindigkeit - `getMiningSpeedMultiplier()` {#mining-speed} + +Wenn das Werkzeug zum Brechen von Blöcken verwendet wird, wie schnell sollte es die Blöcke brechen? + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Zu Referenzzwecken hat das Diamantwerkzeugmaterial eine Abbaugeschwindigkeit von `8.0F`, während das Steinwerkzeugmaterial eine Abbaugeschwindigkeit von `4.0F` hat. + +### Angriffsschaden - `getAttackDamage()` {#attack-damage} + +Wie viele Schadenspunkte sollte das Werkzeug verursachen, wenn es als Waffe gegen eine andere Entität eingesetzt wird? + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Inverse Tag - `getMiningLevel()` {#inverse-tag} + +Das inverse Tag zeigt an, was das Werkzeug _**nicht**_ abbauen kann. Die Verwendung des Tags `BlockTags.INCORRECT_FOR_WOODEN_TOOL` verhindert beispielsweise, dass das Werkzeug bestimmte Blöcke abbaut: + +```json +{ + "values": [ + "#minecraft:needs_diamond_tool", + "#minecraft:needs_iron_tool", + "#minecraft:needs_stone_tool" + ] +} +``` + +Das bedeutet, dass das Werkzeug keine Blöcke abbauen kann, die ein Diamant-, Eisen- oder Steinwerkzeug benötigen. + +Lass das Eisenwerkzeug-Tag verwenden. Dies verhindert, dass Guidite-Werkzeuge Blöcke abbauen, die ein stärkeres Werkzeug als Eisen erfordern. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Du kannst `TagKey.of(...)` verwenden, um einen benutzerdefinierten Tag-Schlüssel zu erstellen, wenn du einen benutzerdefiniertes Tag verwenden willst. + +### Verzauberbarkeit - `getEnchantability()` {#enchantability} + +Wie einfach ist es, mit diesem Gegenstand bessere und höherstufige Verzauberungen zu erhalten? Zum Vergleich: Gold hat eine Verzauberungsfähigkeit von 22, während Netherit eine Verzauberungsfähigkeit von 15 hat. + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Reparatur-Zutat(en) - `getRepairIngredient()` {#repair-ingredient} + +Welche Items werden zur Reparatur des Werkzeugs verwendet? + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +## Werkzeugitems erstellen {#creating-tool-items} + +Mit der gleichen Hilfsfunktion wie in der Anleitung [Erstelle dein ersten Item](./first-item) kannst du deine Werkzeugitems erstellen: + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Vergiss nicht, sie zu einer Itemgruppe hinzuzufügen, wenn du vom Kreativ-Inventar aus auf sie zugreifen willst! + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Du musst auch eine Textur, eine Itemübersetzung und ein Itemmodell hinzufügen. Für das Itemmodell solltest du jedoch das Modell `item/handheld` als übergeordnetes Modell verwenden. + +In diesem Beispiel verwende ich das folgende Modell und die folgende Textur für den Gegenstand "Guidite Sword": + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json) + +Textur + +Das war's dann auch schon! Im Spiel solltest du deine Werkzeuge auf der Registerkarte Werkzeuge im Kreativ Inventar sehen. + +![Fertige Werkzeuge im Inventar](/assets/develop/items/tools_1.png) diff --git a/versions/1.21/translated/de_de/develop/items/first-item.md b/versions/1.21/translated/de_de/develop/items/first-item.md new file mode 100644 index 000000000..c318449ad --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/first-item.md @@ -0,0 +1,151 @@ +--- +title: Dein erstes Item erstellen +description: Lerne, wie man ein einfaches Item registriert und wie man es texturiert, modelliert und benennt. +authors: + - IMB11 + - dicedpixels +--- + +# Dein erstes Item erstellen {#creating-your-first-item} + +Diese Seite wird dich in einige Schlüssel-Konzepte von Items einführen und wie du sie registrierst, eine Textur, ein Model und einen Namen gibst. + +Falls du es nicht weißt, alles in Minecraft wird in Registern gespeichert, genauso wie Items. + +## Deine Item-Klasse vorbereiten {#preparing-your-items-class} + +Um die Registrierung von Items zu vereinfachen, kannst du eine Methode erstellen, die eine Instanz eines Items und einen String-Bezeichner akzeptiert. + +Diese Methode erstellt einen Item mit dem angegebenen Bezeichner und registriert ihn in der Item Registry des Spiels. + +Du kannst diese Methode in eine Klasse namens `ModItems` (oder wie immer du die Klasse nennen willst) einfügen. + +Mojang macht das auch mit ihren Items! Inspiriere dich von der Klasse `Items`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Ein Item registrieren {#registering-an-item} + +Mit der Methode kannst du nun ein Item registrieren. + +Der Item-Konstruktor nimmt eine Instanz der Klasse `Items.Settings` als Parameter entgegen. Mit dieser Klasse kannst du die Eigenschaften des Items mit Hilfe verschiedener Erstellungsmethoden konfigurieren. + +::: tip +If you want to change your item's stack size, you can use the `maxCount` method in the `Items.Settings`/`FabricItemSettings` class. + +Dies funktioniert nicht, wenn du das Item als beschädigungsfähig markiert hast, da die Stackgröße für beschädigungsfähige Gegenstände immer 1 ist, um Duplikations-Exploits zu verhindern. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Wenn du nun jedoch versuchst, den modifizierten Client auszuführen, kannst du sehen, dass unser Item im Spiel noch nicht existiert! Der Grund dafür ist, dass du die Klasse nicht statisch initialisiert hast. + +Um dies zu tun, kannst du eine öffentliche, statische Methode zur initialisierung deiner Klasse hinzufügen und diese in deiner [Mod-Initialisierer](./getting-started/project-structure#entrypoints) Klasse aufrufen. Derzeit braucht diese Methode nichts zu enthalten. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java) + +Der Aufruf einer Methode einer Klasse initialisiert diese statisch, wenn sie nicht vorher geladen wurde - das bedeutet, dass alle `static` Felder ausgewertet werden. Dafür ist diese Dummy-Methode `initialize` gedacht. + +## Ein Item zu einer Itemgruppe hinzufügen {#adding-the-item-to-an-item-group} + +:::info +Wenn du den Artikel einer benutzerdefinierten `ItemGroup` hinzufügen möchtest, findest du weitere Informationen auf der Seite [Benutzerdefinierte Itemgruppe](./custom-item-groups). +::: + +Für ein Beispiel, in dem wir dieses Element zu den Zutaten `ItemGroup` hinzufügen, musst du die Itemgruppen-Events der Fabric API verwenden - insbesondere `ItemGroupEvents.modifyEntriesEvent`. + +Dies kann in der Methode `initialize` deiner Itemklasse geschehen. + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Wenn du das Spiel lädst, kannst du sehen, dass unser Item registriert wurde und sich in der Gruppe der Zutaten befindet: + +![Item in der Zutatengruppe](/assets/develop/items/first_item_0.png) + +Es fehlen jedoch folgende Punkte: + +- Itemmodell +- Textur +- Übersetzung (Name) + +## Das Item benennen {#naming-the-item} + +Für das Item gibt es derzeit keine Übersetzung, du musst also eine hinzufügen. Der Übersetzungsschlüssel wurde bereits von Minecraft bereitgestellt: `item.mod_id.suspicious_substance`. + +Erstelle eine neue JSON-Datei unter dem Pfad `src/main/resources/assets//lang/en_us.json` und setze den Übersetzungsschlüssel und seinen Wert: + +```json +{ + "item.mod_id.suspicious_substance": "Suspicious Substance" +} +``` + +Du kannst entweder das Spiel neu starten oder deinen Mod bauen und F3+T drücken, um die Änderungen zu übernehmen. + +## Eine Textur und ein Modell hinzufügen {#adding-a-texture-and-model} + +Um deinem Item eine Textur und ein Modell zu geben, erstelle einfach ein 16x16 Texturbild für dein Item und speichere es im Ordner `assets//textures/item`. Benenne die Texturdatei genauso wie den Bezeichner des Items, aber mit der Erweiterung `.png`. + +Als Beispiel kannst du diese Textur für `suspicious_substance.png` verwenden. + +Textur + +Wenn du das Spiel neu startest/ladest, solltest du sehen, dass das Item immer noch keine Textur hat, weil du ein Modell hinzufügen musst, das diese Textur verwendet. + +Du wirst ein einfaches `item/generated`-Modell erstellen, das eine Eingabetextur und sonst nichts enthält. + +Erzeuge das Modell JSON im Ordner `assets//models/item`, mit dem gleichen Namen wie das Element; `suspicious_substance.json` + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) + +### Das Modell JSON niederbrechen {#breaking-down-the-model-json} + +- `parent`: Dies ist das Elternmodell von dem dieses Modell erben wird. In diesem Fall ist es das Modell `item/generated`. +- `textures`: Dies ist der Ort, wo du die Textur für das modell definierst. Der `layer0` Schlüssel ist die Textur, die das Modell nutzen wird. + +Die meisten Items werden das Modell `item/generated` als übergeordnetes Modell verwenden, da es ein einfaches Modell ist, das nur die Textur anzeigt. + +Es gibt Alternativen, z. B. `item/handheld`, das für Items verwendet wird, die der Spieler in der Hand hält, wie z. B. Werkzeuge. + +Dein Item sollte nun im Spiel wie folgt aussehen: + +![Item mit dem korrektem Modell](/assets/develop/items/first_item_2.png) + +## Das Item kompostierbar oder zu einem Brennstoff machen {#making-the-item-compostable-or-a-fuel} + +Die Fabric API bietet verschiedene Register, die verwendet werden können, um zusätzliche Eigenschaften zu deinen Items hinzuzufügen. + +Wenn du zum Beispiel dein Item kompostierbar machen willst, kannst du die `CompostableItemRegistry` verwenden: + +@[code transcludeWith=:::_10](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Alternativ, wenn du dein Item zu einem Brennstoff machen willst, kannst du alternativ die Klasse `FuelRegistry` verwenden: + +@[code transcludeWith=:::_11](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Hinzufügen eines einfachen Craftingrezepts {#adding-a-basic-crafting-recipe} + + + +Wenn du ein Crafting-Rezept für deine Items hinzufügen möchtest, musst du eine Rezept-JSON-Datei in den Ordner `data//recipe` legen. + +Weitere Informationen über das Rezeptformat findest du in diesen Ressourcen: + +- [Rezept JSON Generator](https://crafting.thedestruc7i0n.ca/) +- [Minecraft Wiki - Rezept JSON](https://minecraft.wiki/w/Recipe#JSON_Format) + +## Benutzerdefinierte Tooltips {#custom-tooltips} + +Wenn du möchtest, dass dein Item einen benutzerdefinierten Tooltip hat, musst du eine Klasse erstellen, die `Item` erbt und die Methode `appendTooltip` überschreibt. + +:::info +In diesem Beispiel wird die Klasse `LightningStick` verwendet, die auf der Seite [Benutzerdefinierte Iteminteraktionen](./custom-item-interactions) erstellt wurde. +::: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Jeder Aufruf von `add()` fügt dem Tooltip eine Zeile hinzu. + +![Tooltip Beispiel](/assets/develop/items/first_item_3.png) diff --git a/versions/1.21/translated/de_de/develop/items/food.md b/versions/1.21/translated/de_de/develop/items/food.md new file mode 100644 index 000000000..122656048 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/food.md @@ -0,0 +1,52 @@ +--- +title: Nahrungsmittel Items +description: Lerne, wie man einen FoodComponent zu einem Item hinzufügt, um es essbar zu machen, und wie man es konfiguriert. +authors: + - IMB11 +--- + +# Nahrungsmittel Items {#food-items} + +Nahrung ist ein zentraler Aspekt des Überlebens in Minecraft. Wenn du also essbare Items erstellst, musst du die Verwendung der Nahrung mit anderen essbaren Gegenständen berücksichtigen. + +Es sei denn, du machst einen Mod mit übermächtigen Gegenständen, solltest du folgendes in Betracht ziehen: + +- Wie viel Hunger dein Nahrungsmittel verursacht oder beseitigt. +- Welche Trankwirkung(en) gewährt es? +- Ist es im frühen Spiel oder im Endgame zugänglich? + +## Den Nahrungsmittel Component hinzufügen {#adding-the-food-component} + +Um einen Nahrungsmittel Component zu einem Item hinzuzufügen, können wir es an die `Item.Settings` Instanz übergeben: + +```java +new Item.Settings().food(new FoodComponent.Builder().build()) +``` + +Im Moment wird der Gegenstand dadurch nur essbar, mehr nicht. + +Die Klasse `FoodComponent.Builder` hat viele Methoden, mit denen du ändern kannst, was passiert, wenn ein Spieler dein Item isst: + +| Methode | Beschreibung | +| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `nutrition` | Legt die Menge an Hungerpunkten fest, die das Item wieder auffüllt. | +| `saturationModifier` | Legt die Anzahl der Sättigungspunkte fest, die das Item hinzufügen wird. | +| `alwaysEdible` | Ermöglicht es, dass dein Item unabhängig von dem Hungerlevel gegessen werden kann. | +| `snack` | Deklariert dein Item als Snack. | +| `statusEffect` | Fügt einen Statuseffekt hinzu, wenn du dein Item isst. Normalerweise wird dieser Methode eine Instanz des Statuseffekts und eine Chance übergeben, wobei die Chance ein dezimaler Prozentsatz ist (`1f = 100%`) | + +Wenn du den Builder nach deinen Wünschen verändert hast, kannst du die Methode `build()` aufrufen, um den `FoodComponent` zu erhalten. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Ähnlich wie in dem Beispiel auf der Seite [Dein erstes Item erstellen](./first-item) werde ich den obigen Component verwenden: + +@[code transcludeWith=:::poisonous_apple](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Dies macht das Item: + +- Immer essbar, es kann unabhängig vom Hungerlevel gegessen werden. +- Ein "snack". +- Immer den Effekt Vergiftung II für 6 Sekunden, wenn gegessen. + + diff --git a/versions/1.21/translated/de_de/develop/items/potions.md b/versions/1.21/translated/de_de/develop/items/potions.md new file mode 100644 index 000000000..f72a05c00 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/items/potions.md @@ -0,0 +1,49 @@ +--- +title: Tränke +description: Lerne, wie man neue Tränke für verschiedene Statuseffekte hinzufügt. +authors: + - dicedpixels + - PandoricaVi + - Drakonkinst + - JaaiDead +--- + +# Tränke {#potions} + +Tränke sind Verbrauchsmaterialien, die Entitäten Statuseffekte geben können. Spieler können Tränke mit einem Braustand brauen oder durch andere Spielmechaniken erhalten. + +## Benutzerdefinierte Tränke {#custom-potions} + +Genauso wie Items und Blöcke, müssen auch Tränke registriert werden. + +### Den Trank erstellen {#creating-the-potion} + +Als Erstes wird die `Potion` Instanz in einer Variable deklariert. Wir werden hierfür die `ModInitializer` implementierende Klasse nutzen. + +@[code lang=java transclude={18-27}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +Es wird eine Instanz der `StatusEffectInstance` benutzt, die drei Parameter besitzt: + +- `RegistryEntry type` - Einen Effekt. Hier verwenden wir unseren benutzerdefinierten Effekt. Alternativ kann man auch auf die vanilla Effekte durch die vanilla `StatusEffects` Klasse zugreifen. +- `int duration` - Länge des Effekts in Spielticks. +- `int amplifier` - Die Stärke des Effekts. Eile II hätte zum Beispiel einen amplifier-Wert von 1. + +:::info +Um deinen eigenen Effekt zu erstellen, schau bitte in den Leitfaden [Effekte](../entities/effects). +::: + +### Den Trank registrieren {#registering-the-potion} + +In unserer Initialisierungsmethode benutzen wir das `FabricBrewingRecipeRegistryBuilder.BUILD` Event um unseren Trank mithilfe der `BrewingRecipeRegistry.registerPotionRecipe` Methode zu registrieren. + +@[code lang=java transclude={29-42}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +Die `registerPotionRecipe` Methode besitzt 3 Parameter: + +- `RegistryEntry input` - Der Registereintrag für den Starttrank. In den meisten Fällen ist das eine Wasserflasche oder ein "Seltsamer Trank". +- `Item item` - Der Gegenstand, der die Hauptzutat bildet. +- `RegistryEntry output` -Der Registereintrag für den resultierenden Trank. + +Sobald der Trank registriert wurde, kannst du den Tater-Trank mit einer Kartoffel brauen. + +![Effekt im Inventar eines Spielers](/assets/develop/tater-potion.png) diff --git a/versions/1.21/translated/de_de/develop/rendering/basic-concepts.md b/versions/1.21/translated/de_de/develop/rendering/basic-concepts.md new file mode 100644 index 000000000..dd5b9b025 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/rendering/basic-concepts.md @@ -0,0 +1,162 @@ +--- +title: Grundlegende Rendering-Konzepte +description: Lerne, die grundlegenden Konzepte des Renderings mit der Rendering-Engine von Minecraft kennen. +authors: + - IMB11 + - "0x3C50" +--- + +# Grundlegende Rendering-Konzepte {#basic-rendering-concepts} + +::: warning +Although Minecraft is built using OpenGL, as of version 1.17+ you cannot use legacy OpenGL methods to render your own things. Instead, you must use the new `BufferBuilder` system, which formats rendering data and uploads it to OpenGL to draw. + +Zusammenfassend kann man sagen, dass man das Rendering-System von Minecraft benutzen muss, oder ein eigenes, das `GL.glDrawElements()` benutzt. +::: + +Auf dieser Seite werden die Grundlagen des Renderings mit dem neuen System behandelt, wobei die wichtigsten Begriffe und Konzepte erläutert werden. + +Obwohl ein Großteil des Renderings in Minecraft durch die verschiedenen `DrawContext`-Methoden abstrahiert wird und du wahrscheinlich nichts von dem, was hier erwähnt wird, anfassen musst, ist es trotzdem wichtig, die Grundlagen zu verstehen, wie Rendering funktioniert. + +## Der `Tessellator` {#the-tessellator} + +Der `Tessellator` ist die Hauptklasse, die zum Rendern von Dingen in Minecraft verwendet wird. Es ist ein Singleton, das heißt es gibt nur eine Instanz davon im Spiel. Du kannst die Instanz mit `Tessellator.getInstance()` erhalten. + +## Der `BufferBuilder` {#the-bufferbuilder} + +Der `BufferBuilder` ist die Klasse, die zum Formatieren und Hochladen von Rendering-Daten in OpenGL verwendet wird. Sie wird verwendet, um einen Puffer zu erstellen, der dann zum Zeichnen in OpenGL hochgeladen wird. + +Der `Tessellator` wird verwendet, um einen `BufferBuilder` zu erstellen, der zum Formatieren und Hochladen von Rendering-Daten in OpenGL verwendet wird. + +### Den `BufferBuilder` initialisieren {#initializing-the-bufferbuilder} + +Bevor du etwas in den `BufferBuilder` schreiben kannst, musst du ihn initialisieren. Dies geschieht mit der Methode `Tessellator#begin(...)`, die ein `VertexFormat` und einen Zeichenmodus entgegennimmt und einen `BufferBuilder` zurückgibt. + +#### Vertex Formate {#vertex-formats} + +Das `VertexFormat` definiert die Elemente, die wir in unseren Datenpuffer aufnehmen und umreißt, wie diese Elemente an OpenGL übertragen werden sollen. + +Die folgenden `VertexFormat` Elemente sind verfügbar: + +| Element | Format | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | +| `BLIT_SCREEN` | `{ position (3 floats: x, y and z), uv (2 floats), color (4 ubytes) }` | +| `POSITION_COLOR_TEXTURE_LIGHT_NORMAL` | `{ position, color, texture uv, texture light (2 shorts), texture normal (3 sbytes) }` | +| `POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL` | `{ position, color, texture uv, overlay (2 shorts), texture light, normal (3 sbytes) }` | +| `POSITION_TEXTURE_COLOR_LIGHT` | `{ position, texture uv, color, texture light }` | +| `POSITION` | `{ position }` | +| `POSITION_COLOR` | `{ position, color }` | +| `LINES` | `{ position, color, normal }` | +| `POSITION_COLOR_LIGHT` | `{ position, color, light }` | +| `POSITION_TEXTURE` | `{ position, uv }` | +| `POSITION_COLOR_TEXTURE` | `{ position, color, uv }` | +| `POSITION_TEXTURE_COLOR` | `{ position, uv, color }` | +| `POSITION_COLOR_TEXTURE_LIGHT` | `{ position, color, uv, light }` | +| `POSITION_TEXTURE_LIGHT_COLOR` | `{ position, uv, light, color }` | +| `POSITION_TEXTURE_COLOR_NORMAL` | `{ position, uv, color, normal }` | + +#### Zeichenmodi {#draw-modes} + +Der Zeichenmodus legt fest, wie die Daten gezeichnet werden. Die folgenden Zeichenmodi sind verfügbar: + +| Zeichenmodus | Beschreibung | +| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DrawMode.LINES` | Jedes Element besteht aus 2 Eckpunkten und wird als eine einzige Linie dargestellt. | +| `DrawMode.LINE_STRIP` | Das erste Element benötigt 2 Eckpunkte. Zusätzliche Elemente werden nur mit einem neuen Eckpunkt gezeichnet, wodurch eine durchgehende Linie entsteht. | +| `DrawMode.DEBUG_LINES` | Ähnlich wie `DrawMode.LINES`, aber die Linie ist immer genau ein Pixel breit auf dem Bildschirm. | +| `DrawMode.DEBUG_LINE_STRIP` | Wie `DrawMode.LINE_STRIP`, aber die Linien sind immer ein Pixel breit. | +| `DrawMode.TRIANGLES` | Jedes Element besteht aus 3 Eckpunkten, die ein Dreieck bilden. | +| `DrawMode.TRIANGLE_STRIP` | Beginnt mit 3 Eckpunkten für das erste Dreieck. Jeder weitere Eckpunkt bildet ein neues Dreieck mit den letzten beiden Eckpunkten. | +| `DrawMode.TRIANGLE_FAN` | Beginnt mit 3 Eckpunkten für das erste Dreieck. Jeder weitere Scheitelpunkt bildet ein neues Dreieck mit dem ersten und dem letzten Scheitelpunkt. | +| `DrawMode.QUADS` | Jedes Element besteht aus 4 Scheitelpunkten, die ein Viereck bilden. | + +### In den `BufferBuilder` schreiben {#writing-to-the-bufferbuilder} + +Sobald der `BufferBuilder` initialisiert ist, kannst du Daten in ihn schreiben. + +Der `BufferBuilder` erlaubt uns, unseren Puffer Punkt für Punkt zu konstruieren. Um einen Eckpunkt hinzuzufügen, verwenden wir die Methode `buffer.vertex(Matrix, float, float, float)`. Der Parameter `matrix` ist die Transformationsmatrix, auf die wir später noch näher eingehen werden. Die drei Float-Parameter stellen die (x, y, z) Koordinaten der Eckpunktposition dar. + +Diese Methode gibt einen Eckpunkt-Builder zurück, den wir verwenden können, um zusätzliche Informationen für den Eckpunkt anzugeben. Es ist wichtig, dass die Reihenfolge der von uns definierten `VertexFormat` beim Hinzufügen dieser Informationen eingehalten wird. Andernfalls könnte OpenGL unsere Daten nicht richtig interpretieren. Nachdem wir mit der Erstellung eines Scheitelpunktes fertig sind, füge einfach weitere Scheitelpunkte und Daten in den Puffer ein, bis du fertig bist. + +Es lohnt sich auch, das Konzept des Culling zu verstehen. Culling ist der Prozess, bei dem Flächen einer 3D-Form entfernt werden, die aus der Perspektive des Betrachters nicht sichtbar sind. Wenn die Eckpunkte für eine Fläche in der falschen Reihenfolge angegeben werden, wird die Fläche aufgrund von Culling möglicherweise nicht korrekt dargestellt. + +#### Was ist eine Transformationsmatrix? {#what-is-a-transformation-matrix} + +Eine Transformationsmatrix ist eine 4x4-Matrix, die zur Transformation eines Vektors verwendet wird. In Minecraft transformiert die Transformationsmatrix lediglich die Koordinaten, die wir in den Vertex-Aufruf hineingeben. Mit den Transformationen kann unser Modell skaliert, verschoben und gedreht werden. + +Sie wird manchmal auch als Positionsmatrix oder als Modellmatrix bezeichnet. + +Es wird normalerweise über die Klasse `MatrixStack` bezogen, die über das Objekt `DrawContext` bezogen werden kann: + +```java +drawContext.getMatrices().peek().getPositionMatrix(); +``` + +#### Ein praktisches Beispiel: Rendering eines Dreiecksstreifens {#rendering-a-triangle-strip} + +Es ist einfacher, anhand eines praktischen Beispiels zu erklären, wie man in den `BufferBuilder` schreibt. Nehmen wir an, wir wollen etwas mit dem Zeichenmodus `DrawMode.TRIANGLE_STRIP` und dem Vertexformat `POSITION_COLOR` rendern. + +Wir werden Eckpinkt an den folgenden Punkten auf dem HUD zeichnen (in dieser Reihenfolge): + +```txt +(20, 20) +(5, 40) +(35, 40) +(20, 60) +``` + +Dies sollte einen schönen Diamanten ergeben - da wir den Zeichenmodus `TRIANGLE_STRIP` verwenden, wird der Renderer die folgenden Schritte durchführen: + +![Vier Schritte, die die Platzierung der Eckpunkte auf der Oberfläche zeigen, um zwei Dreiecke zu formen](/assets/develop/rendering/concepts-practical-example-draw-process.png) + +Da wir in diesem Beispiel auf dem HUD zeichnen, verwenden wir das Event `HudRenderCallback`: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +Dies führt dazu, dass auf dem HUD folgendes gezeichnet wird: + +![Endergebnis](/assets/develop/rendering/concepts-practical-example-final-result.png) + +:::tip +Versuche, mit den Farben und Positionen der Eckpunkte herumzuspielen, um zu sehen, was passiert! Du kannst auch verschiedene Zeichenmodi und Vertex-Formate ausprobieren. +::: + +## Der `MatrixStack` {#the-matrixstack} + +Nachdem du gelernt hast, wie man in den `BufferBuilder` schreibt, fragst du dich vielleicht, wie du dein Modell transformieren oder sogar animieren kannst. Hier kommt die Klasse `MatrixStack` ins Spiel. + +Die Klasse `MatrixStack` hat folgende Methoden: + +- `push()` - Schiebt eine neue Matrix auf den Stack. +- `pop()` - Nimmt die oberste Matrix vom Stapel. +- `peek()` - Gibt die oberste Matrix auf dem Stapel zurück. +- `translate(x, y, z)` - Verschiebt die oberste Matrix auf dem Stapel. +- `scale(x, y, z)` - Skaliert die oberste Matrix auf dem Stapel. + +Du kannst auch die oberste Matrix auf dem Stapel mit Quaternionen multiplizieren, was wir im nächsten Abschnitt behandeln werden. + +Ausgehend von unserem obigen Beispiel können wir unseren Diamanten nach oben und unten skalieren, indem wir `MatrixStack` und `tickDelta` verwenden - das ist die Zeit, die seit dem letzten Frame vergangen ist. + +::: warning +You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. + +Stelle sicher, dass du den Matrixstapel verschiebst, bevor du eine Transformationsmatrix erhältst! +::: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +![Ein Video, das die Vergrößerung und Verkleinerung eines Diamanten zeigt](/assets/develop/rendering/concepts-matrix-stack.webp) + +## Quaternionen (rotierende Dinge) {#quaternions-rotating-things} + +Quaternionen sind eine Methode zur Darstellung von Drehungen im 3D-Raum. Sie werden verwendet, um die oberste Matrix auf dem `MatrixStack` über die Methode `multiply(Quaternion, x, y, z)` zu drehen. + +Es ist sehr unwahrscheinlich, dass du jemals eine Quaternion-Klasse direkt benutzen musst, da Minecraft verschiedene vorgefertigte Quaternion-Instanzen in seiner `RotationAxis` Utility-Klasse bereitstellt. + +Nehmen wir an, wir wollen unseren Diamanten um die Z-Achse drehen. Wir können dies tun, indem wir den `MatrixStack` und die Methode `multiply(Quaternion, x, y, z)` verwenden. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +Daraus ergibt sich Folgendes: + +![Ein Video, das die Drehung des Diamanten um die Z-Achse zeigt](/assets/develop/rendering/concepts-quaternions.webp) diff --git a/versions/1.21/translated/de_de/develop/rendering/draw-context.md b/versions/1.21/translated/de_de/develop/rendering/draw-context.md new file mode 100644 index 000000000..093ff4403 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/rendering/draw-context.md @@ -0,0 +1,94 @@ +--- +title: Den Zeichenkontext verwenden +description: Lerne, wie man die Klasse DrawContext verwendet, um verschiedene Formen, Texte und Texturen zu rendern. +authors: + - IMB11 +--- + +# Den Zeichenkontext verwenden {#using-the-drawing-context} + +Diese Seite setzt voraus, dass du einen Blick auf die Seite [Grundlegende Rendering-Konzepte](./basic-concepts) geworfen hast. + +Die Klasse `DrawContext` ist die Hauptklasse, die für das Rendering im Spiel verwendet wird. Sie wird für das Rendern von Formen, Text und Texturen verwendet und, wie zuvor gesehen, für die Bearbeitung von `MatrixStack`s und die Verwendung von `BufferBuilder`n. + +## Formen zeichnen {#drawing-shapes} + +Die Klasse `DrawContext` kann verwendet werden, um auf einfache Weise **quadratische** Formen zu zeichnen. Wenn du Dreiecke oder andere nicht-quadratische Formen zeichnen willst, musst du einen `BufferBuilder` verwenden. + +### Zeichnen von Dreiecken {#drawing-rectangles} + +Du kannst die Methode `DrawContext.fill(...)` verwenden, um ein gefülltes Rechteck zu zeichnen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Ein Rechteck](/assets/develop/rendering/draw-context-rectangle.png) + +### Zeichnen von Umrissen/Rahmen {#drawing-outlines-borders} + +Nehmen wir an, wir wollen das Rechteck, das wir gerade gezeichnet haben, umreißen. Wir können die Methode `DrawContext.drawBorder(...)` verwenden, um einen Umriss zu zeichnen. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Ein Rechteck mit einer Umrandung](/assets/develop/rendering/draw-context-rectangle-border.png) + +### Zeichnen von individuellen Linien {#drawing-individual-lines} + +Wir können die Methoden `DrawContext.drawHorizontalLine(...)` und `DrawContext.drawVerticalLine(...)` verwenden, um Linien zu zeichnen. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Linien](/assets/develop/rendering/draw-context-lines.png) + +## Der Scheren-Manager {#the-scissor-manager} + +Die Klasse `DrawContext` hat einen eingebauten Scheren-Manager. So kannst du dein Rendering ganz einfach auf einen bestimmten Bereich beschränken. Dies ist nützlich für das Rendern von Dingen wie Tooltips oder anderen Elementen, die nicht außerhalb eines bestimmten Bereichs gerendert werden sollen. + +### Den Scheren-Manager nutzen {#using-the-scissor-manager} + +:::tip +Scheren-Regionen können verschachtelt werden! Stelle sicher, dass du den Scheren-Manager genauso oft deaktivierst, wie du ihn aktiviert hast. +::: + +Um den Scheren-Manager zu aktivieren, verwende einfach die Methode `DrawContext.enableScissor(...)`. Um den Scheren-Manager zu deaktivieren, verwende die Methode `DrawContext.disableScissor()`. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +[Scheren-Region in Aktion](/assets/develop/rendering/draw-context-scissor.png) + +Wie du siehst, wird der Farbverlauf nur innerhalb der Scheren-Region gerendert, obwohl wir der Oberfläche sagen, dass sie den Farbverlauf über die gesamte Oberfläche rendern soll. + +## Zeichnen von Texturen {#drawing-textures} + +Es gibt nicht den einen "richtigen" Weg, um Texturen auf einen Bildschirm zu zeichnen, da die Methode `drawTexture(...)` viele verschiedene Überladungen hat. In diesem Abschnitt werden die häufigsten Anwendungsfälle behandelt. + +### Zeichnen einer ganzen Textur {#drawing-an-entire-texture} + +Im Allgemeinen wird empfohlen, dass man die Überladung verwendet, die die Parameter `textureWidth` und `textureHeight` angibt. Der Grund dafür ist, dass die Klasse `DrawContext` diese Werte entgegennimmt, wenn du sie nicht angibst, was manchmal falsch sein kann. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Beispiel für das Zeichnen einer ganzen Textur](/assets/develop/rendering/draw-context-whole-texture.png) + +### Zeichnen eines Teils einer Textur {#drawing-a-portion-of-a-texture} + +Hier kommen `u` und `v` ins Spiel. Diese Parameter geben die obere linke Ecke der zu zeichnenden Textur an, und die Parameter `regionWidth` und `regionHeight` geben die Größe des zu zeichnenden Teils der Textur an. + +Nehmen wir diese Textur als Beispiel. + +![Textur des Rezeptbuchs](/assets/develop/rendering/draw-context-recipe-book-background.png) + +Wenn wir nur einen Bereich zeichnen wollen, der die Lupe enthält, können wir die folgenden Werte `u`, `v`, `regionWidth` und `regionHeight` verwenden: + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Textur der Region](/assets/develop/rendering/draw-context-region-texture.png) + +## Zeichnen von Text {#drawing-text} + +Die Klasse `DrawContext` verfügt über verschiedene selbsterklärende Methoden zum Rendern von Texten, die hier aus Gründen der Kürze nicht behandelt werden. + +Nehmen wir an, wir wollen "Hello World" auf die Oberfläche zeichnen. Wir können dazu die Methode `DrawContext.drawText(...)` verwenden. + +@[code lang=java transcludeWith=:::7](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Einen Text zeichnen](/assets/develop/rendering/draw-context-text.png) diff --git a/versions/1.21/translated/de_de/develop/rendering/gui/custom-screens.md b/versions/1.21/translated/de_de/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..e39e212a6 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/rendering/gui/custom-screens.md @@ -0,0 +1,64 @@ +--- +title: Benutzerdefinierte Oberflächen +description: Lerne, wie man benutzerdefinierte Oberflächen für deinen Mod erstellt. +authors: + - IMB11 +--- + +# Benutzerdefinierte Oberflächen {#custom-screens} + +:::info +Diese Seite bezieht sich auf normale Oberflächen, nicht auf solche, die vom Spieler auf dem Client geöffnet werden, und nicht auf solche, die vom Server bearbeitet werden. +::: + +Oberflächen sind im Wesentlichen die grafischen Oberflächen, mit denen der Spieler interagiert, zum Beispiel der Titelbildschirm, der Pausenbildschirm usw. + +Du kannst deine eigenen Oberflächen erstellen, um benutzerdefinierte Inhalte, ein benutzerdefiniertes Einstellungsmenü und vieles mehr anzuzeigen. + +## Eine Oberfläche erstellen {#creating-a-screen} + +Um eine Oberfläche zu erstellen, musst du die `Screen`-Klasse erweitern und die `init`-Methode überschreiben. + +Folgendes solltest du beachten: + +- Widgets werden nicht im Konstruktor erstellt, weil die Oberfläche zu diesem Zeitpunkt noch nicht initialisiert ist - und bestimmte Variablen, wie `width` (Breite) und `height` (Höhe), sind noch nicht verfügbar oder noch nicht genau. +- Die `init`-Methode wird aufgerufen, wenn die Oberfläche initialisiert wird, und sie ist der beste Ort, um Widgets zu erstellen. + - Du kannst Widgets mit der Methode `addDrawableChild` hinzufügen, die jedes zeichenbare Widget akzeptiert. +- Die Methode `render` wird bei jedem Frame aufgerufen - du kannst von dieser Methode aus auf den Zeichenkontext und die Mausposition zugreifen. + +Als Beispiel können wir eine einfache Oberfläche erstellen, der eine Schaltfläche und eine Beschriftung darüber enthält. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Benutzerdefinierte Oberfläche 1](/assets/develop/rendering/gui/custom-1-example.png) + +## Die Oberfläche öffnen {#opening-the-screen} + +Du kannst die Oberfläche mit der `setScreen`-Methode des `MinecraftClient` öffnen - du kannst dies von vielen Stellen aus tun, wie zum Beispiel einer Tastenbindung, einem Befehl oder einem Client-Paket-Handler. + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## Die Oberfläche schließen {#closing-the-screen} + +Wenn du eine Oberfläche schließen möchtest, setze die Oberfläche einfach auf `null`: + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +Wenn du ausgefallen sein und zum vorherigen Bildschirm zurückkehren willst, kannst du die aktuelle Oberfläche an den `CustomScreen`-Konstruktor übergeben und ihn in einem Attribut speichern und ihn dann verwenden, um zum vorherigen Bildschirm zurückzukehren, wenn die Methode `close` aufgerufen wird. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +Jetzt kannst du beim Öffnen der benutzerdefinierten Oberfläche den aktuellen Bildschirm als zweites Argument übergeben - wenn du also `CustomScreen#close` aufrufst, wird er zur vorherigen Oberfläche zurückkehren. + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/translated/de_de/develop/rendering/gui/custom-widgets.md b/versions/1.21/translated/de_de/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..b1c64922e --- /dev/null +++ b/versions/1.21/translated/de_de/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,39 @@ +--- +title: Benutzerdefinierte Widgets +description: Lerne, wie man benutzerdefinierte Widgets für deine Oberfläche erstellt. +authors: + - IMB11 +--- + +# Benutzerdefinierte Widgets {#custom-widgets} + +Widgets sind im Wesentlichen in Containern untergebrachte Rendering-Komponenten, die zu einer Oberfläche hinzugefügt werden können und mit denen der Spieler durch verschiedene Ereignisse wie Mausklicks, Tastendruck usw. + +## Ein Widget erstellen {#creating-a-widget} + +Es gibt mehrere Möglichkeiten, eine Widget-Klasse zu erstellen, beispielsweise durch die Erweiterung von `ClickableWidget`. Diese Klasse bietet viele nützliche Funktionen, wie beispielsweise die Verwaltung von Breite, Höhe und Position sowie die Behandlung von Events. + +- `Drawable` - zum Rendern - Erforderlich, um das Widget über die Methode `addDrawableChild` in der Oberfläche zu registrieren. +- `Element` - für Events - Erforderlich, wenn du Events wie Mausklicks, Tastendrücke usw. +- `Narratable` - für die Barrierefreiheit - Erforderlich, um dein Widget für Bildschirmleser und andere Barrierefreiheitstools zugänglich zu machen. +- `Selectable` - für die Auswahl - Erforderlich, wenn du dein Widget mit der Tab-Taste auswählbar machen willst - dies hilft auch bei der Barrierefreiheit. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## Das Widget zur Oberfläche hinzufügen {#adding-the-widget-to-the-screen} + +Wie alle Widgets musst du es mit der Methode `addDrawableChild`, die von der Klasse `Screen` bereitgestellt wird, zur Oberfläche hinzufügen. Stelle sicher, dass du dies in der Methode `init` machst. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![Ein benutzerdefiniertes Widget in einer Oberfläche](/assets/develop/rendering/gui/custom-widget-example.png) + +## Widget Events {#widget-events} + +Du kannst Events wie Mausklicks und Tastendrücke behandeln, indem du die Methoden `onMouseClicked`, `onMouseReleased`, `onKeyPressed` und andere Methoden überschreibst. + +Du kannst zum Beispiel dafür sorgen, dass das Widget die Farbe wechselt, wenn man mit dem Mauszeiger darüber fährt, indem du die Methode `isHovered()` verwendest, die von der Klasse `ClickableWidget` bereitgestellt wird: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![Hover-Event Beispiel](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/translated/de_de/develop/rendering/hud.md b/versions/1.21/translated/de_de/develop/rendering/hud.md new file mode 100644 index 000000000..f5778b416 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/rendering/hud.md @@ -0,0 +1,30 @@ +--- +title: Rendering im Hud +description: Lerne, wie man das Event HudRenderCallback nutzt, um im Hud zu rendern. +authors: + - IMB11 +--- + +# Rendering im Hud {#rendering-in-the-hud} + +Wir haben bereits auf der Seite [Grundlegende Rendering-Konzepte](./basic-concepts) und [Den Zeichenkontext verwenden](./draw-context) kurz über das Rendern von Dingen auf dem Hud gesprochen, daher beschränken wir uns auf dieser Seite auf das Event `HudRenderCallback` und den Parameter `deltaTick`. + +## HudRenderCallback {#hudrendercallback} + +Das Event `HudRenderCallback`, das von der Fabric API bereitgestellt wird, wird bei jedem Frame aufgerufen und wird zum Rendern von Dingen auf dem HUD verwendet. + +Um dieses Event zu registrieren, kannst du einfach `HudRenderCallback.EVENT.register` aufgrufen und ein Lambda übergeben, welches einen `DrawContext` und einen `float` (deltaTick) als Parameter benötigt. + +Der Zeichenkontext kann verwendet werden, um auf die verschiedenen Rendering-Utilities zuzugreifen, die vom Spiel zur Verfügung gestellt werden, und um auf den Rohmatrix-Stapel zuzugreifen. + +Du solltest dir die Seite [Den Zeichenkontext verwenden](./draw-context) ansehen, um mehr über den Zeichenkontext zu erfahren. + +### DeltaTick {#deltatick} + +Der `deltaTick` bezieht sich auf die Zeit seit dem letzten Frame in Sekunden. Dies kann für Animationen und andere zeitbasierte Effekte verwendet werden. + +Nehmen wir an, du möchtest eine Farbe im Laufe der Zeit auslöschen. Du kannst den `deltaTickManager` verwenden, um den deltaTick zu erhalten und ihn über die Zeit zu speichern, um die Farbe zu lerpen: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java) + +![](/assets/develop/rendering/hud-rendering-deltatick.webp) diff --git a/versions/1.21/translated/de_de/develop/rendering/particles/creating-particles.md b/versions/1.21/translated/de_de/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..d0147bb0e --- /dev/null +++ b/versions/1.21/translated/de_de/develop/rendering/particles/creating-particles.md @@ -0,0 +1,72 @@ +--- +title: Benutzerdefinierte Partikel erstellen +description: Lerne, wie man benutzerdefinierte Partikel mit der Fabric API erstellt. +authors: + - Superkat32 +--- + +# Benutzerdefinierte Partikel erstellen {#creating-custom-particles} + +Partikel sind ein mächtiges Werkzeug. Sie können einer schönen Szene Atmosphäre oder einem spannenden Kampf gegen einen Endgegner mehr Spannung verleihen. Lasst uns einen hinzufügen! + +## Einen benutzerdefinierten Partikel registrieren {#register-a-custom-particle} + +Wir werden einen neuen Glitzerpartikel hinzufügen, der die Bewegung eines Partikels des Endstabs nachahmt. + +Wir müssen zuerst einen `ParticleType` in deiner [Mod-Initialisierer](./getting-started/project-structure#entrypoints) Klasse unter Verwendung deiner Mod ID registrieren. + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +Der "sparkle_particle" in Kleinbuchstaben ist der JSON-Pfad für die Textur des Partikels. Du wirst später eine neue JSON-Datei mit genau diesem Namen erstellen. + +## Client-seitige Registrierung {#client-side-registration} + +Nachdem du den Partikel in dem Mod-Initialisierer registriert hast, musst du den Partikel auch in dem clientseitigen Initialisierer registrieren. + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +In diesem Beispiel registrieren wir unseren Partikel Client-seitig. Dann geben wir dem Partikel ein wenig Bewegung, indem wir die Factory des Endstabpartikels benutzen. Das bedeutet, dass sich unser Partikel genau wie ein Partikel eines Endstabs bewegt. + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- IntelliJ's Tastaturkürzel: Strg+Alt+B +- Visual Studio Codes Hotkey: Strg+F12 + ::: + +## Eine JSON Datei erstellen und Texturen hinzufügen {#creating-a-json-file-and-adding-textures} + +Du musst 2 Ordner in deinem `resources/assets//` Ordner erstellen. + +| Ordnerpfad | Erklärung | +| -------------------- | ---------------------------------------------------------------------------------------------------- | +| `/textures/particle` | Der Ordner `particle` wird jegliche Texturen für alle deine Partikel enthalten. | +| `/particles` | Der Ordner `particles` wird jegliche JSON-Dateien für alle deine Partikel enthalten. | + +Für dieses Beispiel werden wir nur eine Textur in `textures/particle` haben, die "sparkle_particle_texture.png" heißt. + +Als nächstes erstelle eine neue JSON-Datei in `particles` mit demselben Namen wie der JSON-Pfad, den du bei der Registrierung deines ParticleType verwendet hast. Für dieses Beispiel müssen wir `sparkle_particle.json` erstellen. Diese Datei ist wichtig, weil sie Minecraft wissen lässt, welche Texturen unsere Partikel verwenden sollen. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +:::tip +Du kannst weitere Texturen in das Array `textures` einfügen, um eine Partikelanimation zu erstellen. Der Partikel durchläuft die Texturen im Array, beginnend mit der ersten Textur. +::: + +## Den neuen Partikel testen {#testing-the-new-particle} + +Sobald du die JSON-Datei fertiggestellt und deine Arbeit gespeichert hast, kannst du Minecraft starten und alles testen! + +Du kannst überprüfen, ob alles funktioniert hat, indem du den folgenden Befehl eingibst: + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![Vorführung des Partikels](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +:::info +Mit diesem Befehl wird der Partikel im Spieler erzeugt. Du wirst möglicherweise rückwärts gehen müssen, um ihn zu sehen. +::: + +Alternativ kannst du auch einen Befehlsblock verwenden, um den Partikel mit genau demselben Befehl zu erzeugen. diff --git a/versions/1.21/translated/de_de/develop/sounds/custom.md b/versions/1.21/translated/de_de/develop/sounds/custom.md new file mode 100644 index 000000000..744b8db57 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/sounds/custom.md @@ -0,0 +1,63 @@ +--- +title: Benutzerdefinierte Sounds erstellen +description: Lerne, wie man neue Sounds mit einer Registry hinzufügt und nutzt. +authors: + - JR1811 +--- + +# Benutzerdefinierte Sounds erstellen {#creating-custom-sounds} + +## Vorbereitung der Audio-Datei {#preparing-the-audio-file} + +Deine Audio-Dateien müssen auf eine bestimmte Weise formatiert werden. OGG Vorbis ist ein offenes Containerformat für Multimediadaten, wie zum Beispiel Audio, und wird für die Sounddateien von Minecraft verwendet. Um Probleme mit der Distanzierung in Minecraft zu vermeiden, darf deine Audio nur einen einzigen Kanal besitzen (Mono). + +Viele moderne DAWs (Digital Audio Workstation) können dieses Dateiformat importieren und exportieren. Im folgenden Beispiel wird die freie und Open Source Software "[Audacity](https://www.audacityteam.org/)" verwendet, um die Audio-Datei in das richtige Format zu bringen, aber auch jede andere DAW sollte ausreichen. + +![Unvorbereitete Audiodatei in Audacity](/assets/develop/sounds/custom_sounds_0.png) + +In diesem Beispiel wird ein [Pfeifton](https://freesound.org/people/strongbot/sounds/568995/) in Audacity importiert. Sie ist derzeit als `.wav`-Datei gespeichert und hat zwei Audiokanäle (Stereo). Bearbeite den Sound nach deinem Geschmack und stelle sicher, dass du einen der Kanäle mit dem Dropdown-Element oben im "Spurkopf" löschst. + +![Aufteilung der Stereospur](/assets/develop/sounds/custom_sounds_1.png) + +![Löschen von einem der Kanäle](/assets/develop/sounds/custom_sounds_2.png) + +Achte beim Exportieren oder Rendern der Audio-Datei darauf, dass du das Dateiformat OGG wählst. REAPER, unterstützen mehrere OGG-Audio-Layer-Formate. In diesem Fall sollte OGG Vorbis sehr gut funktionieren. + +![Export als OGG-Datei](/assets/develop/sounds/custom_sounds_3.png) + +Denke auch daran, dass Audio-Dateien die Dateigröße deines Mods drastisch erhöhen können. Falls erforderlich, komprimiere die Audiodaten beim Bearbeiten und Exportieren der Datei, um die Dateigröße des fertigen Produkts so gering wie möglich zu halten. + +## Laden der Audio-Datei {#loading-the-audio-file} + +Füge das neue Verzeichnis `resources/assets//sounds` für die Sounds in deinem Mod hinzu, und lege die exportierte Audio-Datei `metal_whistle.ogg` dort hinein. + +Fahre mit der Erstellung der Datei `resources/assets//sounds.json` fort, falls sie noch nicht existiert und füge deinen Sound zu den Sound-Einträgen hinzu. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json) + +Der Untertiteleintrag bietet dem Spieler mehr Kontext. Der Name des Untertitels wird in den Sprachdateien im Verzeichnis `resources/assets//lang` verwendet und wird angezeigt, wenn die Untertitel-Einstellung im Spiel aktiviert ist und dieser benutzerdefinierte Sound abgespielt wird. + +## Registrieren des benutzerdefinierten Sounds {#registering-the-custom-sound} + +Um den benutzerdefinierten Sound zu dem Mod hinzuzufügen, registriere ein SoundEvent in deinem [Mod-Initialisierer](./getting-started/project-structure#entrypoints). + +```java +Registry.register(Registries.SOUND_EVENT, Identifier.of(MOD_ID, "metal_whistle"), + SoundEvent.of(Identifier.of(MOD_ID, "metal_whistle"))); +``` + +## Das Chaos aufräumen {#cleaning-up-the-mess} + +Je nachdem, wie viele Einträge in der Registry vorhanden sind, kann dies schnell unübersichtlich werden. Um dies zu vermeiden, können wir eine neue Hilfsklasse verwenden. + +Füge zwei neue Methoden zu der neu erstellten Hilfsklasse hinzu. Eine, die alle Sounds registriert, und eine, die dazu dient, diese Klasse überhaupt erst zu initialisieren. Danach kannst du bequem neue benutzerdefinierte statische Klassenvariablen der Klasse `SoundEvent` nach Bedarf hinzufügen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java) + +Auf diese Weise, muss der Mod-Initialisierer nur eine Zeile zur Registrierung aller benutzerdefinierten SoundEvents implementieren. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java) + +## Das benutzerdefinierte SoundEvent nutzen {#using-the-custom-soundevent} + +Verwende die Hilfsklasse, um auf das benutzerdefinierte SoundEvent zuzugreifen. Auf der Seite [SoundEvents abspielen](./using-sounds) erfährst du, wie man Sounds abspielt. diff --git a/versions/1.21/translated/de_de/develop/sounds/dynamic-sounds.md b/versions/1.21/translated/de_de/develop/sounds/dynamic-sounds.md new file mode 100644 index 000000000..acc8e2de5 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/sounds/dynamic-sounds.md @@ -0,0 +1,355 @@ +--- +title: Dynamische Sounds +description: Erstelle mehr dynamische und interaktive Sounds +authors: + - JR1811 +--- + +# Erstelle dynamische und interaktive Sounds {#create-dynamic-and-interactive-sounds} + +:::info +Diese Seite baut auf den Seiten [Sounds abspielen](../sounds/using-sounds) und [Benutzerdefinierte Sounds erstellen](../sounds/custom) auf! +::: + +## Probleme mit `SoundEvents` {#problems-with-soundevents} + +Wie wir auf der Seite [Sounds verwenden](../sounds/using-sounds) gelernt haben, ist es vorzuziehen, `SoundEvent` auf einer logischen Serverseite zu verwenden, auch wenn es ein wenig kontraintuitiv ist. Schließlich muss ein Client den Ton verarbeiten, der an Ihre Kopfhörer übertragen wird, nicht wahr? + +Diese Denkweise ist richtig. Technisch gesehen muss clientseitig der Ton verarbeitet werden. Für das einfache Abspielen von `SoundEvent` hat die Serverseite jedoch einen großen Zwischenschritt vorbereitet, der auf den ersten Blick vielleicht nicht offensichtlich ist. Welche Clients sollten diesen Ton hören können? + +Die Verwendung des Sounds auf der logischen Serverseite löst das Problem der Übertragung von `SoundEvent`s. Einfach ausgedrückt: Jeder Client (`ClientPlayerEntity`), der sich im Verfolgungsbereich befindet, bekommt ein Netzwerkpaket geschickt, um diesen speziellen Sound abzuspielen. Das Sound-Ereignis wird im Grunde von der logischen Serverseite an jeden teilnehmenden Client übertragen, ohne dass du dich darum kümmern musst. Der Sound wird einmal mit den angegebenen Lautstärke- und Tonhöhenwerten abgespielt. + +Was aber, wenn dies nicht ausreicht? Was ist, wenn der Sound in einer Schleife laufen, die Lautstärke und die Tonhöhe während des Abspielens dynamisch ändern muss und all das auf der Grundlage von Werten, die von Dingen wie `Entities` oder `BlockEntities` stammen? + +Die einfache Verwendung von `SoundEvent` auf der logischen Serverseite ist für diesen Anwendungsfall nicht ausreichend. + +## Vorbereitung der Audio-Datei {#preparing-the-audio-file} + +Wir werden eine neue **Wiederholende**-Audio für ein anderes `SoundEvent` erstellen. Wenn du eine Audiodatei findest, die bereits nahtlos in einer Schleife läuft, kannst du einfach die Schritte unter [Benutzerdefinierte Sounds erstellen](../sounds/custom) ausführen. Wenn sich der Sound noch nicht perfekt wiederholt, müssen wir ihn darauf vorbereiten. + +Auch hier sollten die meisten modernen DAWs (Digital Audio Workstation Software) dazu in der Lage sein, aber ich verwende gerne [Reaper](https://www.reaper.fm/), wenn die Audiobearbeitung etwas aufwendiger ist. + +### Einrichten {#set-up} + +Unser [Startsound](https://freesound.org/people/el-bee/sounds/644881/) wird von einem Motor kommen. + + + +Laden wir die Datei in die DAW unserer Wahl. + +![Reaper mit der geladenen Audiodatei](/assets/develop/sounds/dynamic-sounds/step_0.png) + +Wir können hören und sehen, dass der Motor am Anfang gestartet und am Ende gestoppt wird, was für wiederholende Sounds nicht gut ist. Schneiden wir diese raus und passen wir die Zeitauswahlgriffe an die neue Länge an. Aktiviere auch den Modus `Toggle Repeat`, damit der Ton in einer Schleife abgespielt wird, während wir ihn anpassen. + +![Gekürzte Audiodatei](/assets/develop/sounds/dynamic-sounds/step_1.png) + +### Störende Audioelemente entfernen {#removing-disruptive-audio-elements} + +Wenn wir genau hinhören, ist im Hintergrund ein Piepen zu hören, das von der Maschine stammen könnte. Ich denke, dass dies im Spiel nicht gut klingen würde, also sollten wir versuchen, es zu entfernen. + +Es handelt sich um einen konstanten Klang, der seine Frequenz über die gesamte Dauer des Tons beibehält. Ein einfacher EQ-Filter sollte also ausreichen, um es herauszufiltern. + +Reaper ist bereits mit einem EQ-Filter ausgestattet, dem "ReaEQ". In anderen DAWs mag dieser an anderer Stelle liegen und anders benannt sein, aber in den meisten DAWs ist die Verwendung von EQ heutzutage Standard. + +Wenn du sicher bist, dass dein DAW keinen EQ-Filter zur Verfügung stellt, suche online nach kostenlosen VST-Alternativen, die du möglicherweise in der DAW deiner Wahl installieren kannst. + +Verwende in Reaper das Effektfenster, um den Audioeffekt "ReaEQ" oder einen anderen EQ hinzuzufügen. + +![Einen EQ-Filter hinzufügen](/assets/develop/sounds/dynamic-sounds/step_2.png) + +Wenn wir die Audio jetzt abspielen, während das EQ-Filter-Fenster geöffnet bleibt, zeigt der EQ-Filter das eingehende Audio in seiner Anzeige an. +Wir können dort viele Unebenheiten sehen. + +![Das Problem identifizieren](/assets/develop/sounds/dynamic-sounds/step_3.png) + +Wenn du kein ausgebildeter Tontechniker bist, geht es in diesem Teil vor allem um Experimente und "Versuch und Irrtum". Zwischen den Knoten 2 und 3 gibt es einen ziemlich harten Sprung. Verschieben wir die Knoten so, dass wir die Frequenz nur für diesen Teil senken. + +![Die schlechte Frequenz gesenkt](/assets/develop/sounds/dynamic-sounds/step_4.png) + +Auch andere Effekte können mit einem einfachen EQ-Filter erzielt werden. So kann z. B. durch das Abschneiden hoher und/oder niedriger Frequenzen der Eindruck von über Funk übertragenen Sounds entstehen. + +Du kannst auch mehrere Audiodateien übereinanderlegen, die Tonhöhe ändern, etwas Hall hinzufügen oder aufwändigere Soundeffekte wie "Bit-Crusher" verwenden. Sounddesign kann Spaß machen, vor allem, wenn man zufällig gut klingende Variationen seines Tons findet. Experimentieren ist angesagt, und vielleicht wird dein Sound am Ende sogar besser als zuvor. + +Wir fahren nur mit dem EQ-Filter fort, mit dem wir die problematische Frequenz herausgeschnitten haben. + +### Vergleich {#comparison} + +Vergleichen wir nun die Originaldatei mit der bereinigten Version. + +Im Originalton ist ein deutliches Brummen und Piepen zu hören, das möglicherweise von einem elektrischen Element des Motors stammt. + + + +Mit einem EQ-Filter konnten wir ihn fast vollständig entfernen. Es ist auf jeden Fall angenehmer anzuhören. + + + +### Eine Audioschleife erstellen {#making-it-loop} + +Wenn wir den Sound bis zum Ende abspielen lassen und dann wieder von vorne beginnen, können wir den Übergang deutlich hören. Ziel ist es, dies durch einen sanften Übergang zu beseitigen. + +Schneide zunächst ein Stück vom Ende aus, das so groß ist, wie der Übergang sein soll, und setze es an den Anfang einer neuen Audiospur. +In Reaper kannst du das Audiomaterial teilen, indem du einfach den Mauszeiger an die Position des Schnitts bewegst und S drückst. + +![Das Ende abschneiden und zur neuen Spur bewegen](/assets/develop/sounds/dynamic-sounds/step_6.png) + +Möglicherweise musst du den EQ-Audioeffekt der ersten Audiospur auch auf die zweite kopieren. + +Lass nun das Endstück der neuen Spur ausblenden und den Anfang der ersten Audiospur einblenden. + +![Wiederholung mit Überblendung von Audiospuren](/assets/develop/sounds/dynamic-sounds/step_7.png) + +### Exportieren {#exporting} + +Exportiere die Audio mit den zwei Audiospuren, aber mit nur einem Audiokanal (Mono) und erstelle ein neues `SoundEvent` für diese `.ogg` Datei in deinem Mod. +Wenn du dir nicht sicher bist, wie das geht, sieh dir die Seite [Benutzerdefinierte Sounds erstellen](../sounds/custom) an. + +Dies ist nun die fertige Audioschleife des Motors für das `SoundEvent` namens `ENGINE_LOOP`. + + + +## Eine `SoundInstance` nutzen {#using-a-soundinstance} + +Um Sounds auf der Client-Seite abzuspielen, wird eine `SoundInstance` benötigt. Diese verwenden jedoch weiterhin `SoundEvent`. + +Wenn du nur so etwas wie einen Klick auf ein UI-Element abspielen willst, gibt es bereits die bestehende Klasse `PositionedSoundInstance`. + +Beachte, dass dies nur auf dem spezifischen Client abgespielt wird, der diesen Teil des Codes ausgeführt hat. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java) + +:::warning +Bitte beachte, dass die Klasse `AbstractSoundInstance`, von der `SoundInstance` erbt, die Annotation `@Environment(EnvType.CLIENT)` hat. + +Dies bedeutet, dass diese Klasse (und alle ihre Unterklassen) nur auf der Client-Seite zur Verfügung stehen werden. + +Wenn du versuchst, das in einem logischen serverseitigen Kontext zu verwenden, wirst du das Problem im Einzelspielermodus vielleicht zunächst nicht bemerken, aber ein Server in einer Multiplayer-Umgebung wird abstürzen, da er diesen Teil des Codes überhaupt nicht finden kann. + +Wenn du mit diesen Problemen zu kämpfen hast, ist es empfehlenswert, deinen Mod mit dem [Online Vorlagen-Generator](https://fabricmc.net/develop/template/) +zu erstellen, wobei die Option `Split client and common sources` aktiviert ist. +::: + +--- + +Eine `SoundInstance` kann mächtiger sein als nur das einmalige Abspielen von Sounds. + +Sieh dir die Klasse `AbstractSoundInstance` an und welche Art von Werten sie speichern kann. +Neben den üblichen Lautstärke- und Tonhöhenvariablen enthält sie auch XYZ-Koordinaten und gibt an, ob dieser sich nach Beendigung des `SoundEvent` wiederholen soll. + +Wenn wir dann einen Blick auf die Unterklasse `MovingSoundInstance` werfen, sehen wir, dass auch das Interface `TickableSoundInstance` eingeführt wurde, die der `SoundInstance` eine Tickfunktionalität hinzufügt. + +Um diese Hilfsmittel zu nutzen, erstelle einfach eine neue Klasse für deine benutzerdefinierte `SoundInstance` und lass sie von `MovingSoundInstance` erben. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/CustomSoundInstance.java) + +Die Verwendung einer eigenen `Entity` oder `BlockEntity` anstelle der grundlegenden `LivingEntity`-Instanz kann dir noch mehr Kontrolle geben, z.B. in der `tick()`-Methode, die auf Accessor-Methoden basiert, aber du benötigst nicht unbedingt einen Verweis auf eine solche Soundquelle. Stattdessen könntest du auch von irgendwo anders auf eine `BlockPos` zugreifen oder sogar nur einmal im Konstruktor von Hand setzen. + +Denke nur daran, dass alle referenzierten Objekte in der `SoundInstance` die Versionen von der Client-Seite sind. +In bestimmten Situationen können sich die Eigenschaft einer Entität auf der logischen Serverseite von der ihres Gegenstücks auf der Clientseite unterscheiden. +Wenn du feststellst, dass deine Werte nicht übereinstimmen, stelle sicher, dass deine Werte entweder mit den S2C-Paketen `TrackedData`, `BlockEntity` der Entität oder mit vollständigen benutzerdefinierten S2C-Netzwerkpaketen synchronisiert werden. + +Nachdem du deine benutzerdefinierte `SoundInstance` erstellt hast, kann sie überall verwendet werden, solange sie auf der Client-Seite mit dem Sound-Manager ausgeführt wurde. +Auf die gleiche Weise kannst du die benutzerdefinierte `SoundInstance` auch manuell stoppen, falls erforderlich. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java) + +Die Audioschleife wird nun nur noch für den Client abgespielt, der diese SoundInstance ausgeführt hat. In diesem Fall folgt der Ton dem `ClientPlayerEntity` selbst. + +Damit ist die Erklärung zur Erstellung und Verwendung einer einfachen benutzerdefinierten `SoundInstance` abgeschlossen. + +## Fortgeschrittene SoundInstances {#advanced-soundinstances} + +:::warning +Der folgende Inhalt behandelt ein fortgeschrittenes Thema. + +Zu diesem Zeitpunkt solltest du über ein solides Verständnis von Java, objektorientierter Programmierung, generischen Typen und Callback-Systemen verfügen. + +Kenntnisse über `Entities`, `BlockEntities` und benutzerdefinierte Vernetzung sind ebenfalls sehr hilfreich für das Verständnis des Anwendungsfalls und der Anwendungen von fortgeschrittenen Sounds. +::: + +Um ein Beispiel dafür zu geben, wie komplexere `SoundInstance`-Systeme erstellt werden können, werden wir zusätzliche Funktionen, Abstraktionen und Hilfsmethoden hinzufügen, um die Arbeit mit solchen Sounds in einem größeren Rahmen einfacher, dynamischer und flexibler zu gestalten. + +### Theorie {#theory} + +Lass uns darüber nachdenken, was unser Ziel mit der `SoundInstance` ist. + +- Der Sound sollte in einer Schleife laufen, solange die verknüpfte benutzerdefinierte `EngineBlockEntity` läuft +- Die `SoundInstance` sollte sich bewegen, indem sie der Position ihres benutzerdefinierten `EngineBlockEntity` folgt _(Die `BlockEntity` wird sich nicht bewegen, daher könnte dies bei `Entities` nützlicher sein)_ +- Wir brauchen sanfte Übergänge. Das Ein- und Ausschalten sollte so gut wie nie sofort erfolgen. +- Änderung von Lautstärke und Tonhöhe in Abhängigkeit von externen Faktoren (z. B. von der Soundquelle) + +Zusammenfassend lässt sich sagen, dass wir eine Instanz einer benutzerdefinierten `BlockEntity` verfolgen, Lautstärke- und Tonhöhenwerte anpassen müssen, während die `SoundInstance` auf der Grundlage von Werten aus dieser benutzerdefinierten `BlockEntity` läuft, und "Übergangszustände" implementieren müssen. + +Wenn du vorhast, mehrere verschiedene `SoundInstances` zu erstellen, die sich unterschiedlich verhalten, würde ich empfehlen, eine neue abstrakte `AbstractDynamicSoundInstance`-Klasse zu erstellen, die das Standardverhalten implementiert und die eigentlichen benutzerdefinierten `SoundInstance`-Klassen von dieser Klasse erben zu lassen. + +Wenn du nur eine einzige verwenden willst, kannst du die abstrakte Superklasse weglassen und stattdessen diese Funktionalität direkt in deiner eigenen `SoundInstance`-Klasse implementieren. + +Außerdem ist es eine gute Idee, einen zentralen Ort zu haben, an dem die `SoundInstance`'s verfolgt, abgespielt und gestoppt werden. Das bedeutet, dass es eingehende Signale, z.B. von benutzerdefinierten S2C-Netzwerkpaketen, verarbeiten muss, alle aktuell laufenden Instanzen auflisten und Sonderfälle behandeln muss, z.B. welche Sounds gleichzeitig abgespielt werden dürfen und welche Sounds bei Aktivierung möglicherweise andere Sounds deaktivieren könnten. +Dazu kann eine neue Klasse `DynamicSoundManager` erstellt werden, um einfach mit diesem Soundsystem zu interagieren. + +Insgesamt könnte unser Soundsystem so aussehen, wenn wir fertig sind. + +![Struktur des benutzerdefinierten Sound Systems](/assets/develop/sounds/dynamic-sounds/custom-dynamic-sound-handling.jpg) + +:::info +Alle diese Enums, interfaces und Klassen werden neu erstellt. Passe das System und die Hilfsmittel an deinen speziellen Anwendungsfall an, wie du es für richtig hältst. +Dies ist nur ein Beispiel dafür, wie du dich solchen Themen annähern kannst. +::: + +### `DynamicSoundSource` Interface {#dynamicsoundsource-interface} + +Wenn du dich dafür entscheidest, eine neue, modularer, benutzerdefinierte `AbstractDynamicSoundInstance`-Klasse als Superklasse zu erstellen, möchtest du vielleicht nicht nur auf einen einzigen Typ von `Entity` verweisen, sondern auf verschiedene, oder sogar auch auf eine `BlockEntity`. + +In diesem Fall ist das Nutzen von Abstraktion der Schlüssel. +Anstatt z.B. eine benutzerdefinierte `BlockEntity` direkt zu referenzieren, reicht es aus, ein Interface zu verfolgen, das die Daten bereitstellt, um dieses Problem zu lösen. + +In Zukunft werden wir ein benutzerdefiniertes Interface namens `DynamicSoundSource` verwenden. Es wird in allen Klassen implementiert, die diese dynamische Soundfunktionalität nutzen wollen, wie z. B. deine benutzerdefinierte `BlockEntity`, Entities oder sogar, unter Verwendung von Mixins, auf bereits existierenden Klassen, wie `ZombieEntity`. Sie stellt im Grunde nur die notwendigen Daten der Soundquelle dar. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/DynamicSoundSource.java) + +Nachdem du dieses Interface erstellt hast, stelle sicher, dass du es auch in den notwendigen Klassen implementierst. + +:::info +Dies ist ein Hilfsmittel, das sowohl auf der Client- als auch auf der logischen Serverseite verwendet werden kann. + +Daher sollte dieses Interface in den allgemeinen Paketen statt in den reinen Client-Paketen gespeichert werden, wenn du die +Option "geteilte Quellen" verwendest +::: + +### `TransitionState` Enum {#transitionstate-enum} + +Wie bereits erwähnt, könnte man mit dem `SoundManager` des Clients die Ausführung von `SoundInstance` stoppen, aber das führt dazu, dass die SoundInstance sofort verstummt. +Unser Ziel ist es, bei einem Stoppsignal den Sound nicht zu stoppen, sondern eine Endphase seines "Übergangszustands" auszuführen. Erst wenn die Endphase abgeschlossen ist, sollte die benutzerdefinierte `SoundInstance` beendet werden. + +Ein `TransitionState` ist ein neu erstelltes Enum, das drei Werte enthält. Sie werden verwendet, um zu verfolgen, in welcher Phase sich der Ton befinden sollte. + +- `STARTING` Phase: Der Sound startet leiste, aber steigert langsam seine Lautstärke +- `RUNNING` Phase: Sound läuft normal +- `ENDING` Phase: Der Sound startet mit der ursprünglichen Lautstärke und wird langsam leister, bis er verstummt + +Technisch gesehen kann ein einfaches Enum mit den Phasen ausreichen. + +```java +public enum TransitionState { + STARTING, RUNNING, ENDING +} +``` + +Aber wenn diese Werte über das Netzwerk gesendet werden, möchtest du vielleicht einen `Identifier` für sie definieren oder sogar andere benutzerdefinierte Werte hinzufügen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/TransitionState.java) + +:::info +Auch hier gilt: Wenn du "geteilte Quellen" verwendest, musst du überlegen, wo du dieses Enum einsetzen willst. +Technisch gesehen verwenden nur die benutzerdefinierten `SoundInstance`s, die nur auf der Client-Seite verfügbar sind, diese Enum-Werte. + +Wenn dieses Enum jedoch an anderer Stelle verwendet wird, z. B. in benutzerdefinierten Netzwerkpaketen, musst du dieses Enum möglicherweise auch in die allgemeinen Pakete anstelle der reinen Client-Pakete aufnehmen. +::: + +### `SoundInstanceCallback` Interface {#soundinstancecallback-interface} + +Dieses Interface wird als Callback genutzt. Im Moment brauchen wir nur eine `onFinished`-Methode, aber du kannst deine eigenen Methoden hinzufügen, wenn du auch andere Signale vom `SoundInstance`-Objekt senden musst. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/SoundInstanceCallback.java) + +Implementiere dieses Interface in jeder Klasse, die in der Lage sein sollte, die eingehenden Signale zu verarbeiten, z. B. in der `AbstractDynamicSoundInstance`, die wir in Kürze erstellen werden, um die Funktionalität in der benutzerdefinierten `SoundInstance` selbst zu erzeugen. + +### `AbstractDynamicSoundInstance` Klasse {#abstractdynamicsoundinstance-class} + +Fangen wir nun endlich mit dem Kern des dynamischen `SoundInstance`-Systems an. `AbstractDynamicSoundInstance` ist eine kürzlich neu erstellte Klasse des Typs `abstract`. +Es implementiert die standardmäßigen Funktionen und Hilfsmittel unserer benutzerdefinierten `SoundInstances`, die von ihr erben werden. + +Wir können die `CustomSoundInstance` von [früher](#using-a-soundinstance) verwenden und diese verbessern. +Anstelle der `LivingEntity` verweisen wir nun auf unsere `DynamicSoundSource`. +Zusätzlich, werden wir mehr Eigenschaften definieren. + +- `TransitionState`, um die aktuelle Phase zu verfolgen +- Tick-Dauer, wie lange die Start- und Endphasen dauern sollen +- minimum und maximum Werte für die Lautstärke und Tonhöhe +- boolescher Wert, um mitzuteilen, ob diese Instanz beendet wurde und aufgeräumt werden kann +- Tick-Halter, um den Fortschritt des aktuellen Sounds zu verfolgen. +- ein Callback, welcher für das finale Aufräumen ein Signal zurück zu dem `DynamicSoundManager` sendet, wenn die `SoundInstance` tatsächlich fertig ist + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Lege dann die Standard-Startwerte für die benutzerdefinierte `SoundInstance` im Konstruktor der abstrakten Klasse fest. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Nachdem der Konstruktor fertig ist, musst du der `SoundInstance` erlauben, zu spielen. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Jetzt kommt der wichtige Teil für diese dynamische `SoundInstance`. Je nachdem, wie die Instanz gerade tickt, kann sie verschiedene Werte und Verhaltensweisen anwenden. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Wie du sehen kannst, haben wir die Lautstärke- und Tonhöhenmodulation hier noch nicht angewendet. Wir wenden nur das gemeinsame Verhalten an. +In dieser `AbstractDynamicSoundInstance` Klasse stellen wir also nur die Grundstruktur und die Werkzeuge für die Unterklassen zur Verfügung, die selbst entscheiden können, welche Art der Klangmodulation sie tatsächlich anwenden wollen. + +Werfen wir also einen Blick auf einige Beispiele für solche Klangmodulationsmethoden. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Wie du sehen kannst, helfen normalisierte Werte in Kombination mit linearer Interpolation (lerp) dabei, die Werte an die bevorzugten Audio-Grenzwerte anzupassen. +Denk daran, dass du, wenn du mehrere Methoden hinzufügst, die denselben Wert ändern, beobachten und anpassen musst, wie sie miteinander zusammenarbeiten. + +Jetzt müssen wir nur noch die verbleibenden Hilfsmethoden hinzufügen und wir sind fertig mit der Klasse `AbstractDynamicSoundInstance`. + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +### Beispiel `SoundInstance` Implementation {#example-soundinstance-implementation} + +Wenn wir uns die eigentliche benutzerdefinierte Klasse `SoundInstance` ansehen, die von der neu erstellten Klasse `AbstractDynamicSoundInstance` abgeleitet ist, müssen wir uns nur überlegen, unter welchen Bedingungen der Klang zum Stillstand kommt und welche Klangmodulation wir anwenden wollen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/EngineSoundInstance.java) + +### `DynamicSoundManager` Klasse {#dynamicsoundmanager-class} + +Wir haben [früher](#using-a-soundinstance) besprochen, wie man eine `SoundInstance` abspielt und stoppt. Um diese Interaktionen zu bereinigen, zu zentralisieren und zu verwalten, kannst du deinen eigenen `SoundInstance`-Handler erstellen, der auf dieser aufbaut. + +Diese neue Klasse `DynamicSoundManager` wird die benutzerdefinierten `SoundInstances` verwalten, so dass sie auch nur auf der Client-Seite zur Verfügung stehen wird. Darüber hinaus sollte ein Client immer nur eine Instanz dieser Klasse zulassen. Mehrere Soundmanager für einen einzigen Client wären nicht sehr sinnvoll und würden die Interaktionen noch komplizierter machen. +Lasst uns ein ["Singleton Design Pattern"](https://refactoring.guru/design-patterns/singleton/java/example) nutzen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java) + +Wenn die Grundstruktur stimmt, kannst du die Methoden hinzufügen, die für die Interaktion mit dem Soundsystem erforderlich sind. + +- Sounds abspielen +- Sounds stoppen +- Prüfen, ob ein Sound gerade abgespielt wird + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java) + +Anstatt nur eine Liste aller aktuell spielenden `SoundInstances` zu haben, könnte man auch verfolgen, welche Soundquellen welche Sounds spielen. +So würde es beispielsweise keinen Sinn machen, wenn ein Motor zwei Motorengeräusche gleichzeitig abspielt, während mehrere Motoren, die ihre jeweiligen Motorengeräusche abspielen, einen zulässigen Sonderfall darstellen. Der Einfachheit halber haben wir nur eine `Liste` erstellt, aber in vielen Fällen könnte eine `HashMap` aus `DynamicSoundSource` und einer AbstractDynamicSoundInstance\` eine bessere Wahl sein. + +### Ein fortgeschrittenes Sound System nutzen {#using-the-advanced-sound-system} + +Um dieses Soundsystem zu verwenden, musst du entweder die Methoden von `DynamicSoundManager` oder die Methoden von `SoundInstance` verwenden. Mit Hilfe von `onStartedTrackingBy` und `onStoppedTrackingBy` von Entitäten oder einfach nur benutzerdefinierten S2C-Netzwerkpacketen kannst du jetzt deine benutzerdefinierten dynamischen `SoundInstance`s starten und stoppen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/network/ReceiveS2C.java) + +Das Endprodukt kann seine Lautstärke auf der Grundlage der Soundphase anpassen, um die Übergänge zu glätten, und die Tonhöhe auf der Grundlage eines Stresswertes ändern, der von der Soundquelle stammt. + + + +Du könntest einen weiteren Wert zu deiner Soundquelle hinzufügen, der einen "Überhitzungs"-Wert verfolgt und zusätzlich eine zischende `SoundInstance` langsam einblenden lässt, wenn der Wert über 0 liegt, oder ein neues Interface zu deiner benutzerdefinierten dynamischen `SoundInstance` hinzufügen, die den Soundtypen einen Prioritätswert zuweist, der bei der Auswahl des abzuspielenden Sounds hilft, wenn sie miteinander kollidieren. + +Mit dem aktuellen System kannst du problemlos mehrere `SoundInstance`s auf einmal verwalten und den Ton nach deinen Bedürfnissen gestalten. diff --git a/versions/1.21/translated/de_de/develop/sounds/using-sounds.md b/versions/1.21/translated/de_de/develop/sounds/using-sounds.md new file mode 100644 index 000000000..5b1524563 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/sounds/using-sounds.md @@ -0,0 +1,34 @@ +--- +title: SoundEvents abspielen +description: Lerne, wie man Sound Events abspielt. +authors: + - JR1811 +--- + +# SoundEvents abspielen {#playing-sounds} + +Minecraft hat eine große Auswahl an Sounds, aus denen du wählen kannst. Schau dir die Klasse `SoundEvents` an, um alle von Mojang bereitgestellten SoundEvent Instanzen zu sehen. + +## Sounds in deinem Mod verwenden {#using-sounds} + +Stelle sicher, dass du die Methode `playSound()` auf der logischen Serverseite ausführst, wenn du Sounds verwendest! + +In diesem Beispiel werden die Methoden `useOnEntity()` und `useOnBlock()` für ein benutzerdefiniertes interaktives Item verwendet, um einen "platzierenden Kupferblock" und einen Plünderer-Sound abzuspielen. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +Die Methode `playSound()` wird mit dem `LivingEntity` Objekt verwendet. Nur das SoundEvent, die Lautstärke und die Tonhöhe müssen angegeben werden. Es kann auch die Methode `playSound()` aus der Weltinstanz verwenden werden, um mehr Möglichkeiten bei der Parameterauswahl zu haben. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +### SoundEvent und SoundCategory {#soundevent-and-soundcategory} + +Das SoundEvent legt fest, welcher Sound abgespielt wird. Du kannst auch [deine eigenen SoundEvents registrieren](./custom), um deinen eigenen Sound einzubinden. + +Minecraft hat mehrere Audioregler in den Spieleinstellungen. Das Enum `SoundCategory` wird verwendet, um zu bestimmen, mit welchem Schieberegler die Lautstärke des Sounds eingestellt wird. + +### Lautstärke und Tonhöhe {#volume-and-pitch} + +Der Lautstärke-Parameter kann ein wenig irreführend sein. Im Bereich von `0.0f - 1.0f` kann die aktuelle Lautstärke des Tons verändert werden. Wenn der Wert größer ist, wird die Lautstärke von `1.0f` verwendet und nur die Reichweite, in der der Ton zu hören ist, wird angepasst. Die Blockdistanz kann grob durch `Lautstärke * 16` berechnet werden. + +Der Pitch-Parameter erhöht oder verringert den Wert der Tonhöhe und ändert auch die Dauer des Sounds. Im Bereich von `(0.5f - 1.0f)` wird die Tonhöhe und die Geschwindigkeit verringert, während größere Werte die Tonhöhe und die Geschwindigkeit erhöhen. Werte unter `0.5f` bleiben auf dem Wert der Tonhöhe von `0.5f`. diff --git a/versions/1.21/translated/de_de/develop/text-and-translations.md b/versions/1.21/translated/de_de/develop/text-and-translations.md new file mode 100644 index 000000000..56e2cfb24 --- /dev/null +++ b/versions/1.21/translated/de_de/develop/text-and-translations.md @@ -0,0 +1,132 @@ +--- +title: Text und Übersetzungen +description: Umfassende Dokumentation für Minecraft's Umgang mit formatiertem Text und Übersetzungen. +authors: + - IMB11 + - LordEnder-Kitty +--- + +# Text und Übersetzungen {#text-and-translations} + +Wann immer Minecraft Text im Spiel anzeigt, wird dieser wahrscheinlich mit einem `Text`-Objekt definiert. +Dieser benutzerdefinierte Typ wird anstelle eines `String` verwendet, um eine erweiterte Formatierung zu ermöglichen, einschließlich Farben, Fettdruck, Verschleierung und Klickereignisse. Sie ermöglichen auch einen einfachen Zugriff auf das Übersetzungssystem, so dass beliebige Elemente der Benutzeroberfläche problemlos in verschiedene Sprachen übersetzt werden können. + +Wenn du schon einmal mit Datapacks oder Funktionen gearbeitet hast, siehst du vielleicht Parallelen zum JSON-Textformat, das unter anderem für Displaynamen, Bücher und Schilder verwendet wird. Wie du vermutlich denken kannst, handelt es sich dabei um eine Json-Darstellung eines `Text`-Objekts, welche mit Hilfe eines `Text.Serializer` umgewandelt werden kann. + +Bei der Erstellung eines Mods ist es im Allgemeinen vorzuziehen, die `Text`-Objekte direkt im Code zu konstruieren und dabei nach Möglichkeit Übersetzungen zu verwenden. + +## Text-Literale {#text-literals} + +Der einfachste Weg, ein `Text`-Objekt zu erzeugen, ist die Erstellung eines Literals. Dies ist nur eine Zeichenkette, die standardmäßig ohne Formatierung angezeigt wird. + +Diese werden mit den Methoden `Text.of` oder `Text.literal` erstellt, die beide leicht unterschiedlich funktionieren. `Text.of` akzeptiert null als Eingabe, und wird eine `Text` Instanz zurückgeben. Im Gegensatz dazu sollte `Text.literal` keine Nulleingabe erhalten, sondern einen `MutableText` zurückgeben, der eine Unterklasse von `Text` ist, die leicht gestylt und verkettet werden kann. Mehr darüber später. + +```java +Text literal = Text.of("Hello, world!"); +MutableText mutable = Text.literal("Hello, world!"); +// Keep in mind that a MutableText can be used as a Text, making this valid: +Text mutableAsText = mutable; +``` + +## Übersetzbarer Text {#translatable-text} + +Wenn du mehrere Übersetzungen für dieselbe Textzeichenfolge bereitstellen willst, kannst du die Methode `Text.translatable` verwenden, um auf einen Übersetzungsschlüssel in einer beliebigen Sprachdatei zu verweisen. Wenn der Schlüssel nicht existiert, wird der Übersetzungsschlüssel in ein Literal umgewandelt. + +```java +Text translatable = Text.translatable("my_mod.text.hello"); + +// Similarly to literals, translatable text can be easily made mutable. +MutableText mutable = Text.translatable("my_mod.text.bye"); +``` + +Die Sprachdatei `en_us.json` sieht wie folgt aus: + +```json +{ + "my_mod.text.hello": "Hello!", + "my_mod.text.bye": "Goodbye :(" +} +``` + +Wenn du in der Lage sein willst, Variablen in der Übersetzung zu verwenden, ähnlich wie Todesnachrichten es erlauben, die beteiligten Spieler und Gegenstände in der Übersetzung zu verwenden, kannst du diese Variablen als Parameter hinzufügen. Du kannst so viele Parameter hinzufügen, wie du willst. + +```java +Text translatable = Text.translatable("my_mod.text.hello", player.getDisplayName()); +``` + +Du kannst diese Variablen in der Übersetzung wie folgt referenzieren: + +```json +{ + "my_mod.text.hello": "%1$s said hello!" +} +``` + +Im Spiel wird %1\$s durch den Namen des Spielers ersetzt, auf den du im Code verwiesen hast. Die Verwendung von `player.getDisplayName()` bewirkt, dass zusätzliche Informationen über die Entität in einem Tooltip erscheinen, wenn der Mauszeiger über den Namen in der Chat-Nachricht bewegt wird, im Gegensatz zur Verwendung von `player.getName()`, die zwar den Namen ermittelt, aber keine zusätzlichen Details anzeigt. Ähnliches kann mit ItemStacks gemacht werden, indem `stack.toHoverableText()` verwendet wird. + +Was %1\$s überhaupt bedeutet, musst du nur wissen, dass die Zahl der Variablen entspricht, die du zu verwenden versuchst. Nehmen wir an, du hast drei Variablen, die du verwendest. + +```java +Text translatable = Text.translatable("my_mod.text.whack.item", victim.getDisplayName(), attacker.getDisplayName(), itemStack.toHoverableText()); +``` + +Wenn du auf den Angreifer verweisen möchtest, würdest du %2\$s verwenden, weil es die zweite Variable ist, die wir übergeben haben. Ebenso bezieht sich %3\$s auf den ItemStack. Eine Übersetzung mit so vielen zusätzlichen Parametern könnte wie folgt aussehen: + +```json +{ + "my_mod.text.whack.item": "%1$s was whacked by %2$s using %3$s" +} +``` + +## Text serialisieren {#serializing-text} + + + +Wie bereits erwähnt, kann Text mit dem Text Codec in JSON serialisiert werden. Weitere Informationen über Codecs findest du auf der Seite [Codec](./codecs). + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +Dadurch wird JSON erzeugt, das in Datenpaketen, Befehlen und an anderen Stellen verwendet werden kann, die das JSON-Format von Text anstelle von literalen oder übersetzbarem Text akzeptieren. + +## Text deserialisieren {#deserializing-text} + +Um ein JSON-Textobjekt in eine tatsächliche `Text`-Klasse zu deserialisieren, ist ebenfalls der Codec zu verwenden. + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +## Text formatieren {#formatting-text} + +Du bist vielleicht mit den Formatierungsstandards von Minecraft vertraut: + +Du kannst diese Formatierungen mit Hilfe des Enum `Formatting` auf die Klasse `MutableText` anwenden: + +```java +MutableText result = Text.literal("Hello World!") + .formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE); +``` + + + + + + + + + + + + + + + + + + + + + + + + + +
FarbeNameChat CodeMOTD CodeHec Code
Schwarz (black)§0\u00A70#000000
Dunkelblau (dark_blue)§1\u00A71#0000AA
Dunkengrün (dark_green)§2\u00A72#00AA00
Dunkles Aquamarin (dark_aqua)§3\u00A73#00AAAA
Dunkelrot (dark_red)§4\u00A74#AA0000
Dunkelviolett (dark_purple)§5\u00A75#AA00AA
Gold (gold)§6\u00A76#FFAA00
Grau (gray)§7\u00A77#AAAAAA
Dunkelgrau (dark_gray)§8\u00A78#555555
Blau (blue)§9\u00A79#5555FF
Grün (green)§a\u00A7a#55FF55
Aquamarin (aqua)§b\u00A7b#55FFFF
Rot (red)§c\u00A7c#FF5555
Hellviolett (light_purple)§d\u00A7d#FF55FF
Gelb (yellow)§e\u00A7e#FFFF55
Weiß (white)§f\u00A7f#FFFFFF
Zurücksetzen§r
Fett§l
Durchgestrichen§m
Unterstrichen§n
Kursiv§o
Verschleiert§k
diff --git a/versions/1.21/translated/de_de/index.md b/versions/1.21/translated/de_de/index.md new file mode 100644 index 000000000..03ad5c2c4 --- /dev/null +++ b/versions/1.21/translated/de_de/index.md @@ -0,0 +1,21 @@ +--- +title: Fabric Dokumentation +description: Die offizielle kuratierte Dokumentation für Fabric, einer Modding-Toolchain für Minecraft. +layout: home +hero: + name: Fabric Dokumentation + tagline: Die offizielle kuratierte Dokumentation für Fabric, einer Modding-Toolchain für Minecraft. +features: + - title: Leitfäden für Spieler + icon: 📚 + details: Bist du ein Spieler, der Mods verwenden möchte, die von Fabric unterstützt werden? Unsere Spieler-Leitfäden decken alles ab. Diese Anleitungen werden dir beim Herunterladen, Installieren und Beheben von Problemen mit Fabric-Mods helfen. + link: /de_de/players/ + linkText: Weiterlesen + - title: Leitfäden für Entwickler + icon: 🛠️ + details: Unsere von der Community verfassten Leitfäden für Entwickler decken alles ab, von der Einrichtung deiner Entwicklungsumgebung bis hin zu fortgeschrittenen Themen wie Rendering und Networking. + link: /de_de/develop/ + linkText: Loslegen +--- + +Wenn du zur Fabric-Dokumentation beitragen möchtest, findest du den Quellcode auf [GitHub](https://github.com/FabricMC/fabric-docs), und die entsprechenden [Beitragsrichtlinien](./contributing) diff --git a/versions/1.21/translated/de_de/navbar_translations.json b/versions/1.21/translated/de_de/navbar_translations.json new file mode 100644 index 000000000..789db58b8 --- /dev/null +++ b/versions/1.21/translated/de_de/navbar_translations.json @@ -0,0 +1,8 @@ +{ + "title": "Fabric Dokumentation", + "home": "Startseite", + "download": "Herunterladen", + "contribute": "Mitwirken", + "contribute.api": "Fabric API", + "version_switcher": "Version wechseln" +} \ No newline at end of file diff --git a/versions/1.21/translated/de_de/players/faq.md b/versions/1.21/translated/de_de/players/faq.md new file mode 100644 index 000000000..31f245f75 --- /dev/null +++ b/versions/1.21/translated/de_de/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Häufig gestellte Fragen für Spieler +description: Häufig gestellte Fragen für Spieler und Serveradministratoren in Bezug auf Fabric. +--- + +# Häufig gestellte Fragen {#faq} + +Es gibt viele Fragen, die häufig gestellt werden, deshalb haben wir hier eine Liste dieser Fragen zusammengestellt. + +## Welche Minecraft Versionen werden von Fabric unterstützt? {#what-minecraft-versions-does-fabric-support} + +Offiziell unterstützt Fabric alle Minecraft-Versionen, beginnend mit Snapshot `18w43b` und höher, sowie Vollversionen beginnend mit Version `1.14` und höher. + +## Wo kann ich veröffentlichte Fabric-Mods herunterladen? {#where-can-i-download-published-fabric-mods} + +:::info +Du solltest immer prüfen, ob Mods aus einer vertrauenswürdigen Quelle stammen. Weitere Informationen zum Finden von Mods findest du in dem Leitfaden [Vertrauenswürdige Mods finden](./finding-mods). +::: + +Die meisten Autoren veröffentlichen ihre Mods auf [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) und [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\\&gameVersionTypeId=4), manche laden sie jedoch auch auf ihre persönliche Website oder auf andere Plattformen wie GitHub hoch. + +## Wo kann ich vorgemachte Fabric-Modpacks herunterladen? {#where-can-i-find-premade-fabric-modpacks} + +Du kannst vorgefertigte Fabric-Modpacks auf einer Vielzahl von Plattformen finden, beispielsweise: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/de_de/players/finding-mods.md b/versions/1.21/translated/de_de/players/finding-mods.md new file mode 100644 index 000000000..bb891f6b9 --- /dev/null +++ b/versions/1.21/translated/de_de/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Vertrauenswürdige Mods finden +description: Eine Anleitung, wie man Fabric-Mods in vertrauenswürdigen Quellen findet. +authors: + - IMB11 +--- + +# Vertrauenswürdige Mods finden {#finding-mods} + +Zu Beginn, Vertrauen ist subjektiv, du solltest beim Herunterladen von Mods immer nach eigenem Ermessen handeln. Hier sind ein paar Dinge, die dir helfen können, vertrauenswürdige Mods zu finden. + +## 1. Nutze eine Quelle, die bekanntermaßen vertrauenswürdig ist {#trustworthy-source} + +Die meisten Autoren veröffentlichen ihre Mods auf [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) und [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\\&gameVersionTypeId=4). + +Diese Webseiten prüfen, dass die Mods tun, was sie versprechen und, dass sie keinen bösartigen Code enthalten. Du kannst auf diesen Webseiten auch bösartige Mods melden, und sie werden ziemlich schnell Maßnahmen ergreifen. + +## 2. Frage bei Anderen nach! {#with-others} + +Wenn du eine Mod von einer nicht bekanntermaßen vertrauenswürdigen Quelle herunterlädst, solltest du bei Anderen nachfragen, um zu prüfen, ob sie die Mod vorher von der gleichen Seite heruntergeladen haben und ob sie Probleme damit hatten. + +Frag im Zweifel gerne im [Fabric Discord](https://discord.gg/v6v4pMv) im Kanal `#player-support` nach. + +## 3. Vermeide bekannte Schadware-Seiten! {#avoid-malware} + +:::info +Schadware-Seiten sind nicht für jeden offensichtlich. Falls du dir unsicher bist, solltest du dich nach Meinungen Anderer erkunden, oder die Seite meiden und dich nur auf vertrauenswürdige Quellen verlassen, wie Modrinth und CurseForge. +::: + +Es gibt viele Webseiten, die behaupten, sie hätten Mods für Minecraft, obwohl sie in Wirklichkeit nur Schadware-Seiten sind. Diese Seiten solltest du in jedem Fall vermeiden. + +Du kannst Antiviren-Software und Websites wie [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) oder [VirusTotal](https://www.virustotal.com/) verwenden, um die heruntergeladenen Mods zu überprüfen. Verlass dich aber nicht vollständig auf diese Methoden, da sie manchmal falsche Ergebnisse liefern. + +Nochmal, frag im Zweifel gerne im [Fabric Discord](https://discord.gg/v6v4pMv) im Kanal `#player-support` nach der Meinung Anderer. diff --git a/versions/1.21/translated/de_de/players/index.md b/versions/1.21/translated/de_de/players/index.md new file mode 100644 index 000000000..2e05275e8 --- /dev/null +++ b/versions/1.21/translated/de_de/players/index.md @@ -0,0 +1,12 @@ +--- +title: Leitfäden für Spieler +description: Eine Sammlung von Anleitungen für Spieler und Serveradministratoren über die Installation und Nutzung von Fabric. +--- + +# Leitfäden für Spieler {#player-guides} + +Dieser Abschnitt der Fabric-Dokumentation ist an Spieler und Serveradministratoren gerichtet, die lernen wollen, wie Fabric installiert und genutzt wird und wie Probleme mit Fabric behoben werden können. + +Die Seitenleiste enthält eine Liste mit allen verfügbaren Anleitungen. + +Falls dir Fehler mit der Dokumentation auffallen, bitte melde sie [auf GitHub](https://github.com/FabricMC/fabric-docs) oder falls Fehler auftreten sollten, frage im [Fabric-Discord](https://discord.gg/v6v4pMv) im Kanal `#player-support` oder `#server-admin-support` nach Hilfe. diff --git a/versions/1.21/translated/de_de/players/installing-fabric.md b/versions/1.21/translated/de_de/players/installing-fabric.md new file mode 100644 index 000000000..af6ecf5ba --- /dev/null +++ b/versions/1.21/translated/de_de/players/installing-fabric.md @@ -0,0 +1,59 @@ +--- +title: Installation von Fabric +description: Eine Schritt-für-Schritt-Anleitung zur Installation von Fabric. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Installation von Fabric {#installing-fabric} + + + +Dieser Leitfaden bezieht sich ausschließlich auf den offiziellen Minecraft Launcher. Für die Launcher von Drittanbietern solltest du deren Dokumentation verwenden. + +## 1. Herunterladen des Fabric-Installers {#1-download-the-fabric-installer} + +Der Fabric-Installer kann von der [Fabric-Webseite](https://fabricmc.net/use/) heruntergeladen werden. + +Wenn du Windows verwendest, lade die `.exe`-Version (`Download For Windows`) herunter, da sie keine Java-Installation auf dem System benötigt. Stattdessen wird die Java-Installation des offiziellen Launchers verwendet. + +Für macOS und Linux solltest du die `.jar`-Version verwenden. Manchmal musst du Java vor diesem Schritt installieren. + +## 2. Ausführen des Fabric-Installers {#2-run-the-fabric-installer} + +:::warning +Schließe vor dem Ausführen des Installers zuerst Minecraft und den Minecraft Launcher. +::: + +:::details Informationen für macOS-Nutzer + +Auf macOS musst du möglicherweise zuerst einen Rechtsklick auf die `.jar`-Datei im Downloads-Verzeichnis machen, und `Öffnen` zum Ausführen klicken. + +![MacOS Kontextmenü im Fabric-Installer](/assets/players/installing-fabric/macos-downloads.png) + +Bei der Frage "Möchten Sie es wirklich öffnen?", klicke erneut auf `Öffnen`. +::: + +Wenn du den Installer geöffnet hast, sollte diese Oberfläche erscheinen: + +![Fabric-Installer mit "Installieren" hervorgehoben](/assets/players/installing-fabric/installer-screen.png) + + + +Um Fabric zu installieren, wähle einfach die Spielversion aus der Liste und klicke `Installieren`. + +:::warning WICHTIG +Stelle sicher, dass die Option 'Profil erstellen' aktiviert ist. +::: + +## 3. Du hast es geschafft! {#3-you-re-done} + +Sobald das Installationsprogramm fertig ist, kannst du den Minecraft-Launcher öffnen und das Fabric-Profil aus der Liste in der unteren linken Ecke auswählen und spielen! + +![Minecraft-Launcher mit ausgewähltem Fabric-Profil](/assets/players/installing-fabric/launcher-screen.png) + +Jetzt, nachdem du Fabric installiert hast, kannst du dem Spiel Mods hinzufügen! Weitere Informationen zum Finden von Mods findest du in dem Leitfaden [Vertrauenswürdige Mods finden](./finding-mods). + +Fall dir beim Folgen dieser Anleitungen irgendwelche Fehler auftreten, kannst du nach Hilfe im [Fabric-Discord](https://discord.gg/v6v4pMv) im Kanal `#player-support` fragen. diff --git a/versions/1.21/translated/de_de/players/installing-java/linux.md b/versions/1.21/translated/de_de/players/installing-java/linux.md new file mode 100644 index 000000000..ed6e90848 --- /dev/null +++ b/versions/1.21/translated/de_de/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Java auf Linux installieren +description: Eine Schritt-für-Schritt-Anleitung zur Installation von Java auf Linux. +authors: + - IMB11 +--- + +# Java auf Linux installieren {#installing-java-on-linux} + +Diese Anleitung führt Sie durch die Installation von Java 21 auf Linux. + +## 1. Überprüfen, ob Java bereits installiert ist {#1-check-if-java-is-already-installed} + +Öffne ein Terminal und gib `java -version` ein, drücke anschließend Enter. + +![Kommandozeile mit "java -version"](/assets/players/installing-java/linux-java-version.png) + +:::warning +Um Minecraft 1.21 zu verwenden, muss mindestens Java 21 installiert sein. Wenn dieser Befehl eine niedrigere Version als 21 anzeigt, musst du deine bestehende Java-Installation aktualisieren. +::: + +## 2. Herunterladen und Installieren von Java 21 {#2-downloading-and-installing-java} + +Wir empfehlen die Verwendung von OpenJDK 21, das für die meisten Linux-Distributionen verfügbar ist. + +### Arch Linux {#arch-linux} + +:::info +Für mehr Informationen über die Installation von Java auf Arch Linux, schaue in das [Arch Linux Wiki](https://wiki.archlinux.org/title/Java). +::: + +Du kannst die aktuellste JRE aus den offiziellen Repositories installieren: + +```sh +sudo pacman -S jre-openjdk +``` + +Wenn du einen Server betreibst, der keine grafische Benutzeroberfläche benötigt, kannst du stattdessen die Headless-Version installieren: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Wenn du planst Mods zu entwickeln, brauchst du stattdessen die JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu {#debian-ubuntu} + +Du kannst Java 21 mit `apt` mit den folgenden Befehlen installieren: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora {#fedora} + +Du kannst Java 21 über `dnf` mit dem folgenden Befehlen installieren: + +```sh +sudo dnf install java-21-openjdk +``` + +Wenn du keine grafische Benutzeroberfläche benötigst, kannst du die Headless-Version installieren: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +Wenn du planst Mods zu entwickeln, brauchst du stattdessen die JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Andere Linux Distributionen {#other-linux-distributions} + +Wenn deine Distribution oben nicht gelistet ist, kannst du die aktuellste JRE von [Adoptium](https://adoptium.net/temurin/) herunterladen + +Du solltest einen alternativen Leitfaden für deine Distribution verwenden, wenn du Mods entwickeln willst. + +## 3. Verifiziere, dass Java 21 installiert ist {#3-verify-that-java-is-installed} + +Sobald die Installation abgeschlossen ist, kannst du überprüfen, ob Java 21 installiert ist, indem du ein Terminal öffnest und `java -version` eingibst. + +Wenn der Befehl erfolgreich ausgeführt wird, wird die Java-Version wie zuvor gezeigt angezeigt: + +![Kommandozeile mit "java -version"](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/de_de/players/installing-java/windows.md b/versions/1.21/translated/de_de/players/installing-java/windows.md new file mode 100644 index 000000000..7465ca384 --- /dev/null +++ b/versions/1.21/translated/de_de/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Java auf Windows installieren +description: Eine Schritt-für-Schritt-Anleitung zur Installation von Java auf Windows. +authors: + - IMB11 +--- + +# Java auf Windows installieren {#installing-java-on-windows} + +Diese Anleitung führt Sie durch die Installation von Java 21 auf Windows. + +Der Minecraft Launcher kommt bereits mit seiner eigenen Java Installation, diese Sektion ist also nur relevant, wenn Sie den Fabric `.jar` basierten Installer verwenden möchten oder wenn Sie die Minecraft Server `.jar` verwenden möchten. + +## 1. Überprüfen, ob Java bereits installiert ist {#1-check-if-java-is-already-installed} + +Um zu überprüfen, ob Java bereits installiert ist, öffnen Sie die Kommandozeile. + +Drücken Sie Win + R und geben Sie `cmd.exe` in das Feld ein. + +![Windows-Ausführungsdialog mit "cmd.exe" in der Ausführungsleiste](/assets/players/installing-java/windows-run-dialog.png) + +Wenn Sie die Kommandozeile geöffnet haben, geben Sie `java -version` ein und drücken Enter. + +Wenn der Befehl erfolgreich ausgeführt wird, sollten Sie folgendes sehen. Wenn der Befehl fehlgeschlagen ist, fahren Sie mit dem nächsten Schritt fort. + +![Kommandozeile mit "java -version"](/assets/players/installing-java/windows-java-version.png) + +:::warning +Um Minecraft 1.21 zu nutzen, muss mindestens Java 21 installiert sein. Wenn der Befehl eine Version niedriger als 21 anzeigt, musst du deine bestehende Java-Installation aktualisieren. +::: + +## 2. Herunterladen des Java 21 Installer {#2-download-the-java-installer} + +Um Java 21 zu installieren, musst du das Installationsprogramm von [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21) herunterladen. + +Sie müssen die Version "Windows Installer (.msi)" herunterladen: + +![Adoptium Download-Seite mit hervorgehobenem Windows Installer (.msi)](/assets/players/installing-java/windows-download-java.png) + +Sie sollten `x86` wählen, wenn Sie ein 32-Bit-Betriebssystem haben, oder `x64`, wenn Sie ein 64-Bit-Betriebssystem haben. + +Die meisten modernen Computer sind mit einem 64-Bit-Betriebssystem ausgestattet. Wenn Sie sich unsicher sind, versuchen Sie es mit dem 64-Bit-Download. + +## 3. Installer starten! {#3-run-the-installer} + +Folge den Schritten des Installationsprogramms, um Java 21 zu installieren. Wenn Sie diese Seite erreichen, sollten Sie die folgenden Funktionen auf "Die gesamte Funktion wird auf der lokalen Festplatte installiert" einstellen: + +- `JAVA_HOME Umgebungsvariable setzen` - Diese wird zu Ihrem PATH hinzugefügt. +- JavaSoft (Oracle)-Registrierungsschlüssel + +![Java 21-Installationsprogramm mit "JAVA\_HOME-Variable setzen" und "JavaSoft (Oracle) Registrierungsschlüssel" hervorgehoben](/assets/players/installing-java/windows-wizard-screenshot.png) + +Wenn Sie das getan haben, können Sie `Weiter` klicken und mit der Installation fortfahren. + +## 4. Verifiziere, dass Java 21 installiert ist {#4-verify-that-java-is-installed} + +Sobald die Installation abgeschlossen ist, kannst du überprüfen, ob Java 21 installiert ist, indem du die Kommandozeile erneut öffnest und `java -version` eingibst. + +Wenn der Befehl erfolgreich ausgeführt wird, wird die Java-Version wie zuvor gezeigt angezeigt: + +![Kommandozeile mit "java -version"](/assets/players/installing-java/windows-java-version.png) + +--- + +Sollten Sie auf Probleme stoßen, können Sie im [Fabric Discord](https://discord.gg/v6v4pMv) im Channel `#player-support` um Hilfe bitten. diff --git a/versions/1.21/translated/de_de/players/installing-mods.md b/versions/1.21/translated/de_de/players/installing-mods.md new file mode 100644 index 000000000..a4e27ce04 --- /dev/null +++ b/versions/1.21/translated/de_de/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Mods installieren +description: Eine Schritt-für-Schritt-Anleitung zur Installation von Mods für Fabric. +authors: + - IMB11 +--- + +# Mods installieren {#installing-mods} + +Diese Anleitung wird die Installation von Mods für Fabric detailliert für den Minecraft-Launcher erklären. + +Für die Launcher von Drittanbietern solltest du deren Dokumentation verwenden. + +## 1. Herunterladen der Mod {#1-download-the-mod} + +:::warning +Du solltest Mods nur aus Quellen herunterladen, denen du vertraust. Weitere Informationen zum Finden von Mods findest du iim Leitfaden [Vertrauenswürdige Mods finden](./finding-mods). +::: + +Die meisten Mods benötigen auch die Fabric API, die von [Modrinth](https://modrinth.com/mod/fabric-api) oder [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api) heruntergeladen werden kann. + +Stelle beim Herunterladen von Mods sicher, dass: + +- Sie auf der Version von Minecraft funktionieren, auf der du spielen möchtest. Eine Mod, die beispielsweise auf der Version 1.20 funktioniert, muss nicht auf der Version 1.20.2 funktionieren. +- Sie für Fabric sind und nicht für einen anderen Mod-Loader. +- Sie für die korrekte Edition von Minecraft sind (Java Edition). + +## 2. Verschieben der Mod in das Verzeichnis `mods` {#2-move-the-mod-to-the-mods-folder} + +Das Mods-Verzeichnis kann, abhängig vom Betriebssystem, an den folgenden Stellen gefunden werden. + +Normalerweise können die Pfade direkt in der Adressleiste des Dateiexplorers eingefügt werden, um schnell zum Verzeichnis zu navigieren. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Sobald du das `mods`-Verzeichnis gefunden hast, kannst du die `.jar`-Dateien der Mods dorthin verschieben. + +![Installierte Mods im mods-Verzeichnis](/assets/players/installing-mods.png) + +## 3. Du hast es geschafft! {#3-you-re-done} + +Sobald du die Mods in das `mods`-Verzeichnis verschoben hast, kannst du den Minecraft-Launcher öffnen und das Fabric-Profil aus der Liste in der unteren linken Ecke auswählen und spielen! + +![Minecraft-Launcher mit ausgewähltem Fabric-Profil](/assets/players/installing-fabric/launcher-screen.png) + +## Problembehandlung {#troubleshooting} + +Fall dir beim Folgen dieser Anleitungen irgendwelche Fehler auftreten, kannst du nach Hilfe im [Fabric-Discord](https://discord.gg/v6v4pMv) im Kanal `#player-support` fragen. + +Du kannst auch versuchen, das Problem mit diesen Fehlerbehebungs-Seiten selbst zu lösen: + +- [Absturzberichte](./troubleshooting/crash-reports) +- [Logs hochladen](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/de_de/players/troubleshooting/crash-reports.md b/versions/1.21/translated/de_de/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..b942eb697 --- /dev/null +++ b/versions/1.21/translated/de_de/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: Absturzberichte +description: Erfahre, wie mit Absturzberichten umzugehen ist, und wie man sie liest. +authors: + - IMB11 +--- + +# Absturzberichte {#crash-reports} + +:::tip +Falls du Schwierigkeiten hast, den Grund für einen Absturz herauszufinden, frage im [Fabric Discord](https://discord.gg/v6v4pMv) im Kanal `#player-support` oder `#server-admin-support` nach Hilfe. +::: + +Absturzberichte sind ein sehr wichtiger Teil, um Probleme mit deinem Spiel oder Server zu beheben. Sie enthalten viele Informationen über den Absturz und können beim Finden der Ursache für den Absturz hilfreich sein. + +## Absturzberichte Absturzberichte finden {#finding-crash-reports} + +Absturzberichte werden im `crash-reports`-Verzeichnis in deinem Spiel-Verzeichnis gespeichert. Falls du einen Server nutzt, sind sie im `crash-reports`-Verzeichnis im Server-Verzeichnis. + +Für Launcher von Drittanbietern solltest du deren Dokumentation verwenden, um den Ort der Absturzberichte zu finden. + +Absturzberichte befinden sich an den folgenden Orten: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Absturzberichte lesen {#reading-crash-reports} + +Absturzberichte sind sehr lang und können verwirrend zu lesen sein. Allerdings enthalten sie viele Informationen über den Absturz, die beim Finden der Ursache sehr hilfreich sind. + +Für diesen Leitfaden werden wir [diesen Crash-Report](/assets/players/crash-report-example.txt) nutzen. + +:::details Absturzbericht anzeigen + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Abschnitte des Absturzberichts {#crash-report-sections} + +Absturzberichte bestehen aus mehreren Abschnitten, jeder ist mit einer Überschrift getrennt: + +- `---- Minecraft Crash Report ----`, die Zusammenfassung des Berichts. Dieser Abschnitt enthält den Hauptfehler, der den Absturz verursacht hat, den Zeitpunkt an dem das Problem aufgetreten ist und den relevanten Stacktrace. Dies ist der wichtigste Abschnitt des Absturzberichts, da der Stacktrace normalerweise Referenzen zu der Mod enthält, die den Absturz verursacht hat. +- `-- Last Reload --`, dieser Abschnitt ist nicht wirklich hilfreich, es sei denn, der Absturz ist während dem Neu-Laden von Resourcen (F3+T) aufgetreten. Dieser Abschnitt enthält den Zeitpunkt des letzten Neu-Ladens, den relevanten Stacktrace und alle Fehler, die währenddessen aufgetreten sind. Diese Fehler werden normalerweise durch Ressourcenpakete ausgelöst und können ignoriert werden, wenn sie keine Probleme mit dem Spiel verursachen. +- `-- System Details --`, dieser Abschnitt enthält Informationen über dein System, wie das Betriebssystem, die Java-Version, und die Speichermenge, die dem Spiel zugewiesen wurde. Dieser Abschnitt ist nützlich, um festzustellen, ob du die korrekte Java-Version verwendest und ob du dem Spiel genug Speicher zugewiesen hast. + - In diesem Abschnitt fügt Fabric eine eigene Zeile ein, die mit `Fabric Mods:` beginnt und darauf folgend alle installierten Mods auflistet. Dieser Abschnitt ist nützlich, um festzustellen, ob Konflikte zwischen Mods aufgetreten sein könnten. + +### Den Absturzbericht herunterbrechen {#breaking-down-the-crash-report} + +Da wir jetzt alle Abschnitte des Absturzberichts kennengelernt haben, können wir nun beginnen, den Absturzbericht herunterzubrechen und die Ursache des Absturzes zu finden. + +Mit dem obigen verwiesenen Beispiel können wir den Absturzbericht analysieren und die Ursache für den Absturz herausfinden und welche Mods den Absturz verursachen. + +Der Stack-Trace im Abschnitt `---- Minecraft Crash Report ----` ist in diesem Fall am wichtigsten, da er den Hauptfehler enthält, der den Absturz verursacht hat. + +:::details Fehler anzeigen + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +Mit der Anzahl an Mods, die sich in diesem Stacktrace befinden, kann es schwierig sein, den Schuldigen zu finden, aber das Erste, was zu tun ist, ist die Mod zu finden, die den Absturz verursacht. + +In diesem Fall ist der Mod, der den Absturz verursacht hat, `snownee`, da es der erste Mod ist, der im Stack-Trace erwähnt wird. + +Bei der Menge an Mods, die erwähnt wurden, könnte es jedoch bedeuten, dass es Kompatibilitätsprobleme zwischen den Mods gibt, und dass der Mod, der den Absturz verursacht hat, nicht unbedingt derjenige ist, der den Fehler verursacht hat. In diesem Fall ist es am besten, den Absturz dem Mod-Autor zu melden und ihn den Absturz untersuchen zu lassen. + +## Mixin Abstürze {#mixin-crashes} + +:::info +Mixins sind eine Möglichkeit für Mods, das Spiel zu verändern, ohne den Quellcode des Spiels ändern zu müssen. Sie werden von vielen Mods verwendet und sind ein sehr mächtiges Werkzeug für Mod-Entwickler. +::: + +Wenn ein Mixin abstürzt, wird in der Regel das Mixin im Stacktrace erwähnt und die Klasse, die das Mixin ändert. + +Methoden-Mixins enthalten `modid$handlerName` in dem Stack-Trace, wobei `modid` die ID des Mods und `handlerName` der Name des Mixin-Handlers ist. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +Anhand dieser Informationen kannst du den Mod, der den Absturz verursacht hat, ausfindig machen und den Absturz an den Autor des Mods melden. + +## Was macht man mit Absturzberichten {#what-to-do-with-crash-reports} + +Am besten ist es, Absturzberichte auf eine Paste-Seite hochzuladen und dann den Link mit dem Mod-Autor zu teilen, entweder auf dessen Issue-Tracker oder über eine andere Form der Kommunikation (Discord usw.). + +Dies ermöglicht es dem Mod-Autor, den Absturz zu untersuchen, ihn möglicherweise zu reproduzieren und das Problem zu lösen, das ihn verursacht hat. + +Häufig genutzte Websites für Absturzberichte sind die folgenden: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/de_de/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/de_de/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..cb7d6c31e --- /dev/null +++ b/versions/1.21/translated/de_de/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Logs hochladen +description: Wie man Logs zur Fehlerbehebung hochlädt. +authors: + - IMB11 +--- + +# Logs hochladen {#uploading-logs} + +Wenn man versucht, Fehler zu beheben, ist es oft nötig, Logs bereitzustellen, die beim Identifizieren der Ursache des Fehlers helfen. + +## Warum sollte ich Logs hochladen? {#why-should-i-upload-logs} + +Das Hochladen von Logs ermöglicht es anderen, dir bei der Fehlersuche schneller zu helfen, als wenn die Logs in den Chat oder Forenbeiträge eingefügt werden. Es ermöglicht dir auch, die Logs mit anderen zu teilen, ohne sie zu Kopieren oder Einfügen zu müssen. + +Manche Paste-Seiten stellen Syntaxhervorhebung für Logs bereit, was sie deutlich einfacher zu lesen macht und zensieren sensible Daten, wie Benutzernamen oder Systeminformationen. + +## Absturzberichte {#crash-reports} + +Absturzberichte werden automatisch generiert, wenn das Spiel abstürzt. Sie enthalten nur Absturzinformationen, aber nicht die eigentlichen Logs des Spiels. Sie befinden sich im `crash-reports`-Verzeichnis im Spiel-Verzeichnis. + +Für weitere Informationen über Absturzberichte, siehe [Absturzberichte](./crash-reports). + +## Logs finden {#locating-logs} + +Diese Anleitung behandelt den offiziellen Minecraft-Launcher (oft auch "Vanilla-Launcher" genannt) - für Launcher von Drittanbietern solltest du deren Dokumentation verwenden. + +Logs befinden sich im `logs`-Verzeichnis innerhalb des Spiel-Verzeichnisses, das Spiel-Verzeichnis kann sich, abhängig von deinem Betriebssystem, an den folgenden Orten befinden: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +Das neueste Log hat den Dateinamen `latest.log` und vorherige Logs nutzen das Muster `JJJJ-MM-TT_Nummer.log.gz` zur Benennung. + +## Logs hochladen {#uploading-logs-online} + +Logs können bei einer Vielzahl von Diensten hochgeladen werden, zum Beispiel: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/de_de/players/updating-fabric.md b/versions/1.21/translated/de_de/players/updating-fabric.md new file mode 100644 index 000000000..073710e3c --- /dev/null +++ b/versions/1.21/translated/de_de/players/updating-fabric.md @@ -0,0 +1,41 @@ +--- +title: Aktualisieren von Fabric +description: Eine Schritt-für-Schritt-Anleitung zum Aktualisieren von Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Aktualisieren von Fabric {#updating-fabric} + +Diese Anleitung wird das Aktualisieren von Fabric detailliert für den Minecraft-Launcher erklären. + +Für die Launcher von Drittanbietern solltest du deren Dokumentation verwenden. + +Das Vorgehen beim Aktualisieren von Fabric ist der Installation ähnlich, deshalb werden sich Teile dieser Anleitung mit der Anleitung [Installation von Fabric](./installing-fabric) überschneiden. + +## Warum sollte ich den Fabric-Loader aktualisieren? {#why-should-i-update-fabric-loader} + +Neuere Mods können eine neuere Version des Fabric-Loaders benötigen, um zu funktionieren, weshalb es wichtig ist, ihn auf dem neuesten Stand zu halten, um immer die neuesten Mods benutzen zu können. + + + +Um Fabric zu aktualisieren, vergewissere dich einfach, dass die Spielversion und die Loader-Version korrekt sind, und klicke dann auf `Installieren`. + +:::warning WICHTIG +Stelle sicher, dass du die Option `Profil erstellen` deaktivierst, wenn du das Installationsprogramm ausführst, da sonst ein neues Profil erstellt wird, das wir in diesem Fall nicht benötigen. +::: + +## 3. Öffne das Profil im Minecraft Launcher {#3-open-the-profile-in-the-minecraft-launcher} + +Sobald der Installer fertig ist, kannst du den Minecraft Launcher öffnen und auf die Registerkarte `Installationen` gehen. Gehe zu deinem Fabric-Profil und öffne den Bearbeitungsbildschirm. + +Ersetze die Version durch die neue Version von Fabric Loader, die du gerade installiert hast, und drücke `Speichern`. + +![Aktualisieren der Fabric Loader Version im Minecraft Launcher](/assets/players/updating-fabric.png) + +## 4. Du hast es geschafft! {#4-you-re-done} + +Sobald du die Schritte abgeschlossen hast, kannst du zur Registerkarte `Spielen` zurückkehren, das Fabric-Profil aus dem Dropdown-Menü in der linken unteren Ecke auswählen und auf `Spielen` drücken! + +Wenn du beim Befolgen dieses Leitfadens auf Probleme stößt, kannst du im [Fabric Discord](https://discord.gg/v6v4pMv) im Kanal ´#player-support\` um Hilfe bitten. diff --git a/versions/1.21/translated/de_de/sidebar_translations.json b/versions/1.21/translated/de_de/sidebar_translations.json new file mode 100644 index 000000000..4a9073202 --- /dev/null +++ b/versions/1.21/translated/de_de/sidebar_translations.json @@ -0,0 +1,71 @@ +{ + "players.title": "Leitfäden für Spieler", + "players.faq": "Häufig gestellte Fragen", + "players.installingJava": "Installation von Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Installation von Fabric", + "players.findingMods": "Vertrauenswürdige Mods finden", + "players.installingMods": "Mods installieren", + "players.troubleshooting": "Problembehandlung", + "players.troubleshooting.uploadingLogs": "Deine Logs hochladen", + "players.troubleshooting.crashReports": "Absturzberichte", + "players.updatingFabric": "Aktualisieren von Fabric", + "develop.title": "Leitfäden für Entwickler", + "develop.gettingStarted": "Erste Schritte", + "develop.gettingStarted.introduction": "Einführung in Fabric und Modding", + "develop.gettingStarted.devEnvSetup": "Einrichten deiner Entwicklungsumgebung", + "develop.gettingStarted.creatingProject": "Ein Projekt erstellen", + "develop.gettingStarted.projectStructure": "Projektstruktur", + "develop.gettingStarted.launchGame": "Starten des Spiels", + "develop.gettingStarted.solvingProblems": "Grundlegende Problemlösungsstrategien", + "develop.items": "Gegenstände", + "develop.items.first-item": "Dein erstes Item erstellen", + "develop.items.food": "Nahrungsmittel", + "develop.items.custom-armor": "Benutzerdefinierte Rüstung", + "develop.items.custom-tools": "Benutzerdefinierte Werkzeuge", + "develop.items.custom-item-groups": "Benutzerdefinierte Itemgruppen", + "develop.items.custom-item-interactions": "Benutzerdefinierte Iteminteraktionen", + "develop.items.custom-enchantment-effects": "Benutzerdefinierte Verzauberungseffekte", + "develop.items.potions": "Tränke", + "develop.items.custom-data-components": "Benutzerdefinierte Data Components", + "develop.blocks": "Blöcke", + "develop.blocks.first-block": "Deinen ersten Block erstellen", + "develop.blocks.blockstates": "Blockzustände", + "develop.blocks.block-entities": "Block Entitäten", + "develop.blocks.block-entity-renderer": "Block Entitäten Renderer", + "develop.entities": "Entitäten", + "develop.entities.effects": "Statuseffekte", + "develop.entities.damage-types": "Schadensarten", + "develop.commands": "Befehle", + "develop.commands.basics": "Befehle erstellen", + "develop.commands.arguments": "Argumente", + "develop.commands.suggestions": "Vorschläge", + "develop.dataGeneration": "Datengenerierung", + "develop.dataGeneration.setup": "Einrichtung der Datengenerierung", + "develop.dataGeneration.tags": "Generierung von Tags", + "develop.dataGeneration.translations": "Generierung von Übersetzungen", + "develop.dataGeneration.advancements": "Generierung von Fortschritten", + "develop.dataGeneration.recipes": "Generierung von Rezepten", + "develop.dataGeneration.lootTables": "Generierung von Beutetabellen", + "develop.rendering": "Rendering", + "develop.rendering.basicConcepts": "Grundlegende Rendering-Konzepte", + "develop.rendering.drawContext": "Den Zeichenkontext verwenden", + "develop.rendering.hud": "Rendering im Hud", + "develop.rendering.gui": "GUIs und Oberflächen", + "develop.rendering.gui.customScreens": "Benutzerdefinierte Oberflächen", + "develop.rendering.gui.customWidgets": "Benutzerdefinierte Widgets", + "develop.rendering.particles": "Partikel", + "develop.rendering.particles.creatingParticles": "Erstellen von benutzerdefinierten Partikeln", + "develop.misc": "Diverse Seiten", + "develop.misc.codecs": "Codecs", + "develop.misc.events": "Events", + "develop.misc.text-and-translations": "Text und Übersetzungen", + "develop.misc.ideTipsAndTricks": "Tipps und Tricks für die Entwicklungsumgebung", + "develop.misc.automatic-testing": "Automatisiertes Testen", + "develop.sounds": "Sounds", + "develop.sounds.using-sounds": "SoundEvents abspielen", + "develop.sounds.custom": "Benutzerdefinierte Sounds erstellen", + "develop.sounds.dynamic-sounds": "Dynamische Sounds" +} diff --git a/versions/1.21/translated/de_de/website_translations.json b/versions/1.21/translated/de_de/website_translations.json new file mode 100644 index 000000000..f99df86d9 --- /dev/null +++ b/versions/1.21/translated/de_de/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "Seitenautoren", + "authors.nogithub": "%s (nicht auf GitHub)", + "banner": "Die Fabric-Dokumentation ist in Arbeit. Melde Probleme auf %s oder auf %s.", + "description": "Umfassende Dokumentation für Fabric, die Modding-Toolchain für Minecraft.", + "download": "%s herunterladen", + "footer.next": "Nächste Seite", + "footer.prev": "Vorherige Seite", + "github_edit": "Diese Seite auf GitHub bearbeiten", + "lang_switcher": "Sprache ändern", + "last_updated": "Zuletzt aktualisiert", + "mode_dark": "Dunkles Erscheinungsbild aktivieren", + "mode_light": "Helles Erscheinungsbild aktivieren", + "mode_switcher": "Erscheinungsbild", + "nav.contribute": "Beitragen", + "nav.contribute.api": "Fabric API", + "nav.download": "Herunterladen", + "nav.home": "Startseite", + "outline": "Auf dieser Seite", + "return_to_top": "Zum Anfang zurückkehren", + "search.back": "Suche schließen", + "search.button": "Suchen", + "search.display_details": "Detaillierte Liste anzeigen", + "search.footer.close": "zu schließen", + "search.footer.close.key": "Escape", + "search.footer.down.key": "Pfeil nach unten", + "search.footer.navigate": "zum Navigieren", + "search.footer.up.key": "Pfeil nach oben", + "search.footer.select": "zum Auswählen", + "search.footer.select.key": "Enter", + "search.no_results": "Keine Treffer für", + "search.reset": "Suche zurücksetzen", + "sidebar_menu": "Menü", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Fabric Dokumentation", + "version.reminder": "Diese Seite ist für folgende Version geschrieben:", + "version.switcher": "Version wechseln", + "404.code": "404", + "404.crowdin_link": "Übersetzen auf Crowdin", + "404.crowdin_link.label": "Den Crowdin Editor öffnen", + "404.english_link": "Auf Englisch lesen", + "404.english_link.label": "Die Englische Version öffnen", + "404.link": "Zurück zur Startseite", + "404.link.label": "Zurück zur Startseite gehen", + "404.quote": "Diese Seite hat versucht, in Lava zu schwimmen", + "404.title": "Seite nicht gefunden" +} diff --git a/versions/1.21/translated/es_es/contributing.md b/versions/1.21/translated/es_es/contributing.md new file mode 100644 index 000000000..5b775b571 --- /dev/null +++ b/versions/1.21/translated/es_es/contributing.md @@ -0,0 +1,181 @@ +# Pautas de Contribución para la Documentación de Fabric + +Esta página web utiliza [VitePress](https://vitepress.dev/) para generar HTML estático a partir de varios archivos markdown. Debes familiarizarte con las extensiones de markdown que VitePress soporta [aquí](https://vitepress.dev/guide/markdown#features). + +## Índice de Contenido + +- [Pautas de Contribución para la Documentación de Fabric](#fabric-documentation-contribution-guidelines) + - [Como Contribuir](#how-to-contribute) + - [Estructura de Contribuciones](#contributing-framework) + - [Contribuir Contenido](#contributing-content) + - [Pautas de Estilo](#style-guidelines) + - [Guias para Expansiones](#guidance-for-expansion) + - [Verificación de Contenido](#content-verification) + - [Limpieza](#cleanup) + - [Traducir la Documentación](#translating-documentation) + +## Como Contribuir + +Es recomendado que crees una nueva rama en tu bifurcación del repositorio por cada solicitud de extracción que crees. Esto facilita el manejo de multiples solicitudes de extracción al mismo tiempo. + +**Si quieres tener una vista previa de tus cambios localmente, necesitarás instalar [Node.js 18+](https://nodejs.org/en/)** + +Antes de correr cualquiera de estos comandos, asegúrate de correr `npm install` para instalar todas las dependencias. + +**Ejecutar el servidor de desarrollo:** + +Esto te permitirá ver una vista previa de tus cambios localmente en `localhost:3000`. + +```sh +npm run dev +``` + +**Construyendo la página web:** + +Esto compilará todos los archivos markdown en archivos HTML estáticos, los cuales estarán en `.vitepress/dist` + +```sh +npm run build +``` + +**Viendo la vista previa de la página web:** + +Esto ejecutará un servidor local en el puerto 3000 usando el contenido encontrado en `.vitepress/dist` + +```sh +npm run preview +``` + +## Estructura de Contribuciones + +Cualquier solicitud de extracción que modifique la estructura interna de la página web debe ser etiquetada con la etiqueta `framework`. + +En realidad solo deberías realizar solicitudes de extracción para la estructura después de consultar con el equipo de documentación en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv) o mediante una propuesta. + +**Nota: Modificar la configuración de los archivos de la barra lateral o la barra de navegación no cuenta como una solicitud de extracción de estructura.** + +## Contribuir Contenido + +La contribución de contenido es la manera principal para contribuir a la Documentación de Fabric. + +Todo el contenido debe seguir nuestras pautas de estilo. + +### Pautas de Estilo + +Todas las páginas de la Documentación de Fabric deben seguir las pautas de estilo. Si no estás seguro sobre cualquier cosa, puedes preguntar en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv) o mediante las Discusiones de Github. + +La guía de estilo es la siguiente: + +1. Todas las páginas deben tener un título y una descripción como o en el asunto. + + ```md + --- + title: Este es el título de la página + description: Esta es la descripción de la página + authors: + - UsuarioDeGithubAquí + --- + + # ... + ``` + +2. Si quieres crear o modificar páginas que contengan código, debes colocar el código en un lugar apropiado dentro del mod de referencia (localizado en el folder `/reference` del repositorio). Luego, utiliza la [funcionalidad de fragmentos de código ofrecida por VitePress](https://vitepress.dev/guide/markdown#import-code-snippets) para adjuntar el código, o si necesitas mayor control, puedes usar la [funcionalidad de transcluir de `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + + **Por ejemplo:** + + ```md + <<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21 java} + ``` + + Esto adjuntará las líneas 15-21 del archivo `FabricDocsReference.java` del mod de referencia. + + El fragmento de código resultante se verá así: + + ```java + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + LOGGER.info("Hello Fabric world!"); + } + ``` + + **Ejemplo de translcuir:** + + ```md + @[code transcludeWith=#test_transclude](@/reference/.../blah.java) + ``` + + Esto adjuntará las secciones de `blah.java` marcadas con la etiqueta `#test_transclude`. + + Por ejemplo: + + ```java + public final String test = "Bye World!" + + // #test_transclude + public void test() { + System.out.println("Hello World!"); + } + // #test_transclude + ``` + + Solo se adjuntará el código entre las etiquetas de `#test_transclude`. + + ```java + public void test() { + System.out.println("Hello World!"); + } + ``` + +3. Toda la documentación original está escrita en Inglés, usando las reglas gramáticas del dialecto Estadounidense. Aunque puedes usar [LanguageTool](https://languagetool.org/) para verificar tu gramática mientras que escribes, no te estreses mucho por ello. Nuestro equipo de documentación verificará y corregirá la gramática durante la etapa de limpieza. Sin embargo, puedes ahorrarnos tiempo tomando esfuerzo en escribir bien. + +4. Si estás creando una nueva sección, debes crear una nueva barra lateral en el folder de `.vitepress/sidebars` y agregarla en el archivo `config.mts`. Si necesitas ayuda con esto, puedes preguntar en el canal de `#docs` en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv). + +5. Cuando crees una nueva página, debes agregarla a la barra lateral correspondiente en el folder de `.vitepress/sidebars`. De nuevo, si necesitas ayuda, pregunta en el servidor de Discord de Fabric, en el canal de `#docs`. + +6. Cualquier imagen debe ser colocada en un lugar apropiado en el folder de `/assets`. + +7. ⚠️ **Cuando enlaces a otras páginas, usa links relativos.** ⚠️ + + Esto es debido al sistema de versiones presente, el cual procesará los links para agregar la versión antes. Si usas links absolutos, el número de versión no será agregado al link. + + Por ejemplo, para una página en el folder de `/players`, enlazar a la página de `installing-fabric` encontrada en `/players/installing-fabric.md` requerirá de lo siguiente: + + ```md + [Esto es un link a otra página](./installing-fabric) + ``` + + **NO** hagas lo siguiente: + + ```md + [Esto es un link a otra página](/players/installing-fabric) + ``` + +Todas las contribuciones de contenido pasa por tres etapas: + +1. Guías para expansiones (si es posible) +2. Verificación de Contenido +3. Limpieza (Gramática etc.) + +### Guías para Expansiones + +Si el equipo de documentación piensa que puedes expandir tu solicitud de extracción en cuanto al contenido, un miembro del equipo añadirá la etiqueta `expansion` a tu solicitud de extracción junto con un comentario explicando lo que el miembro de equipo piensa que puedes hacer para expandir tu solicitud. Si estás de acuerdo con la sugerencia, puedes expandir tu solicitud de extracción. + +**No te sientas presionado en expandir tu solicitud de extracción.** Si no quieres expandirla, simplemente puedes pedir que se te remueva la etiqueta de `expansion`. + +Si no quieres expandir tu solicitud de extracción, pero quisieras que otra persona lo expanda después, es mejor crear una propuesta en la [Página de Propuestas](https://github.com/FabricMC/fabric-docs/issues) y explicar lo que quisieras que se expanda. + +### Verificación de Contenido + +Esta etapa es la más importante, ya que asegura que el contenido es correcto y sigue las Pautas de Estilo de Documentación de Fabric. + +### Limpieza + +¡En esta etapa, el equipo de documentación arreglará problemas con la gramática y hará cualquier otros cambios lingüísticos necesarios antes de aceptar la solicitud de extracción! + +## Traducir la Documentación + +Si quieres traducir esta documentación a tu idioma, puedes hacer esto en la [página de Crowdin de Fabric](https://crowdin.com/project/fabricmc). diff --git a/versions/1.21/translated/es_es/develop/codecs.md b/versions/1.21/translated/es_es/develop/codecs.md new file mode 100644 index 000000000..909d757c6 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/codecs.md @@ -0,0 +1,398 @@ +--- +title: Codecs +description: Una guía completa para entender y usar el sistema de codecs de Mojang para la serialización y deserialización de objetos. +authors: + - enjarai + - Syst3ms +--- + +# Codecs + +Los Codecs es un sistema para la fácil serialización de objetos de Java, el cual viene incluido en la librería de DataFixerUpper (DFU) de Mojang, el cual es incluido en Minecraft. En el contexto de desarrollo de mods, pueden ser usados como una alternativa a GSON y Jankson a la hora de leer y escribir archivos json, aunque se están haciendo cada vez más y más relevantes, a medida que Mojang reescribe bastante código viejo para que use Codecs. + +Los codecs son usandos en conjunto con otro API de DFU, llamado `DynamicOps` (Operaciones Dinámicas). Un codec define la estructura de un objeto, mientras que un "dynamic ops" es usado para definir un formato con el cual (de) serializar, como json o NBT. Esto quiere decir que un codec puede user usado con cualquier "dynamic ops" y vice versa, permitiendo mayor flexibilidad. + +## Usando Codecs + +### Serializando y Deserializando + +La manera básica de usar un codec es para serializar y deserializar objetos desde y a un formato en específico. + +Ya que algunas clases vanila ya tienen codecs definidos, podemos usarlos como ejemplo. Mojang también nos ha dado dos clases de "dynamic ops" por defecto, llamadas `JsonOps` y `NbtOps`, las cuales tienden a ser usadas en la mayoría de los casos. + +Digamos que queremos serializar un `BlockPos` a json y de vuelta. Podemos hacer esto mediante el codec guardado estáticamente en `BlockPos.CODEC` con los métodos `Codec#encodeStart` y `Codec#parse`, respectivamente. + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// Serializamos el BlockPos a un JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +Cuando usamos codecs, los valores retornados vienen en la forma de un `DataResult` ("Resultado de Dato"). Esto es una envoltura que puede representar o un éxito o un fracaso. Podemos usarlo de varias maneras: Si solo queremos nuestro valor serializado, entonces `DataResult#result` simplemente nos dará un `Optional` que contiene nuestro valor, mientras que `DataResult#resultOrPartial` también nos deja suplír una función para manejar cualquier error que pudo haber ocurrido. Esto último es particularmente útil para recursos de datapacks ("paquetes de datos"), donde querríamos escribir o "loggear" errores sin causar problemas en otros lugares. + +Ahora podemos obtener nuestro valor serializado y convertirlo de vuelta a un `BlockPos`: + +```java +// Cuando desarrolles un mod, querrás obviamente manejar Opcionales vaciós apropiadamente +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Aquí tenemos nuestro valor json, que debería corresponder a `[1, 2, 3]`, +// ya que es el formato usado por el codec de BlockPos. +LOGGER.info("Serialized BlockPos: {}", json); + +// Ahora deserializaremos nuestro el JsonElement de vuelta a un BlockPos +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// Una vez más solo agarraremos nuestro valor del resultado +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// ¡Y ahora podemos ver que hemos serializado y deserializado nuestro BlockPos exitósamente! +LOGGER.info("Deserialized BlockPos: {}", pos); +``` + +### Codecs Incluidos + +Como hemos mencionado anterioramente, Mojang ya tiene definido varios codecs para varias clases vanila y clases de Java estándares, como por ejemplo, `BlockPos`, `BlockState`, `ItemStack`, `Identifier`, `Text`, y regex `Pattern`s (patrones regex). Los Codecs para las clases propias de Mojang usualmente se pueden encontrar como miembros estáticos con el nombre de `CODEC` en la clase misma, mientras que la mayoría de los demás se encuentran en la clase `Codecs`. Es importante saber que todos los registros vanila tienen un método `getCodec()`, por ejemplo, puedes usar `Registries.BLOCK.getCodec()` para tener un `Codec` el cual (de)serializa IDs de bloques. + +La API de Codec también tiene codecs para tipos de variable primitivos, como `Codec.INT` y `Codec.STRING`. Estos se pueden encontrar como miembros estáticos en la clase `Codec`, y usualmente son la base de Codecs más complejos, como explicado a continuación. + +## Construyendo Codecs + +Ahora que hemos visto como usar codecs, veamos como podemos hacer nuestros propios codecs. Supongamos que tenemos la siguiente clase, y queremos deserializar instancias de ella desde archivos json: + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +El archivo json correspondiente puede verse algo así: + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +Podemos hacer un codec para esta clase integrando varios codecs más pequeños en uno más grande. En este caso, necesitaremos uno para cada miembro: + +- un `Codec` +- un `Codec` +- un `Codec>` + +Podemos obtener el primero usando los codecs primitivos ya mencionados, mediante la clase `Codec`, específicamente `Codec.INT`. Mientras que el segundo se puede obtener mediante el registro `Registries.ITEM`, el cuando tiene un método `getCodec()`, el cual retorna un `Codec`. No tenemos un codec por defecto para `List`, pero podemos crear uno a partir de `BlockPos.CODEC`. + +### Listas + +`Codec#listOf` puede ser usado para crear una versión lista de cualquier codec: + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +Debe ser recalcado que los codecs creados de esta manera siempre se deserializarán a un `ImmutableList` (lista inmutable o no modificable). Si en cambio necesitas una lista mutable, puedes usar [xmap](#mutually-convertible-types-and-you) para convertir a una durante la deserialización. + +### Combinar Codecs para Clases como Records + +Ahora que tenemos codecs separados para cada miembro, podemos combinarlos en un solo codec usando un `RecordCodecBuilder`. Esto asume que nuestra clase tiene un constructor que contiene cada miembro que queremos serializar, y que cada miembro tiene su propio método adquiridor (getter method). Esto lo hace perfecto para usar en conjunto con records, pero también pueden ser usados con clases normales. + +Veamos como podemos crear un codec para nuestra clase `CoolBeansClass`: + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // El máximo de miembros que se pueden declarar aquí es 16 +).apply(instance, CoolBeansClass::new)); +``` + +Cada línea en el grupo especifica un codec, un nombre para el miembro, y el método adquiridor. El llamado a `Codec#fieldOf` es usado para convertir el codec a un [map codec](#mapcodec), y el llamado a `forGetter` especifica el método adquiridor que se usará para obtener el valor del miembro a partir de una instancia de la clase. Mientras tanto, el llamado a `apply` especifica que el constructor usado para crear nuevas instancias. Es importante saber que el orden de los miembros en el grupo debe ser el mismo que el orden de los argumentos del constructor. + +También puedes usar `Codec#optionalFieldOf` en este contexto para hacer un miembro opcional, como explicado en la sección de [Miembros Opcionales](#optional-fields). + +### MapCodec, sin ser confundido con Codec<Map> {#mapcodec} + +Llamar `Codec#fieldOf` convertirá un `Codec` a un `MapCodec`, el cual es una implementación variante, pero no directa de `Codec`. Como su nombre lo indica, los `MapCodec`s garantizan la serialización a una asociación (map) llave a valor, o su equivalente en el `DynamicOps` usado. Algunas funciones pueden requerir una, en vez de un codec regular. + +Esta manea particular de crear un `MapCodec` esencialmente empaqueta los valores del codec fuente dentro de una asociación (map), usando el nombre del miembro proveído como la llave. Por ejemplo, un `Codec`, cuando es serializado a json, puede verse así: + +```json +[1, 2, 3] +``` + +Pero cuando es convertido a un `MapCodec` usando `BlockPos.CODEC.fieldOf("pos")`, se verá así: + +```json +{ + "pos": [1, 2, 3] +} +``` + +Aunque el uso más común para los map codecs es para que se combinen con otros map codecs para construir un codec para una clase completa con varios miemros, como fue explicado en la sección [Combinar Codecs para Clases como Records](#merging-codecs-for-record-like-classes), también pueden ser convertidos de vuelta a codecs regulares usando `MapCodec#codec`, el cual mantendrá el mismo comportamiento para empaquetar sus valores de entrada. + +#### Codecs Opcionales + +`Codec#optionalFieldOf` puede ser usado para crear un map codec opcional. Esto hará que, cuando el miembro especificado no esté presente en el contenedor durante la deserialización, se deserialize a un `Optional` vacío, o a un valor por defecto especificado. + +```java +// Sin valor por defecto +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// Con valor por defecto +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +Ten en cuenta que los miembros opcionales ignorarán silenciosamente cualquier error que ocurra durante la deserialización. Esto significa que si el miembro está presente, pero el valor es inválido, el miembro siempre se deserializará al valor por defecto. + +**Desde la 1.20.2**, debido a Minecraft (no DFU!) en cambio si provee `Codecs#createStrictOptionalFieldCodec`, el cual falla en la deserialización si el valor del miembro es inválido. + +### Constantes, Restricciones, y Composición + +#### Unidad + +`Codec.unit` puede usarse para crear un codec el cual siempre deserializará a un valor constante, independiente del valor dado. Cuando se serialice, no hará nada. + +```java +Codec theMeaningOfCodec = Codec.unit(42); +``` + +#### Rangos Numéricos + +`Codec.intRange` y sus amigos, `Codec.floatRange` y `Codec.doubleRange` pueden ser usados para crear un codec que solo acepta valores numéricos dentro de un rango **inclusivo**. Esto se aplica tanto en la serialización y deserialización. + +```java +// No puede ser mayor a 2 +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Pares + +`Codec.pair` combina dos codecs, `Codec
` y `Codec`, a un `Codec>`. Ten en cuenta que solo funciona bien con codecs que serializan a un miembro específico, como un [`MapCodec`s convertidos](#mapcodec) o +[codecs de record](#merging-codecs-for-record-like-classes). +El codec resultante será serializado a una asociación (map) que combina los miembros de ambos codecs usados. + +Por ejemplo, al correr este código: + +```java +// Crea dos codecs empaquetados +Codec firstCodec = Codec.INT.fieldOf("i_am_number").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("this_statement_is_false").codec(); + +// Combinalos a un codec par +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// Usalo para serializar datos +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +Producirá este json: + +```json +{ + "i_am_number": 23, + "this_statement_is_false": true +} +``` + +#### Cualquiera (Either) + +`Codec.either` combina dos codecs, `Codec` y `Codec`, a un `Codec>`. El codec resultante intentará, durante la deserialización, usar el primer codec, y _solo si eso falla_, entonces intentará usar el segundo. +Si el segundo también falla, el error del _segundo_ codec será retornado. + +#### Asociaciones (Maps) + +Para procesar asociaciones con llaves arbitrarias, como `HashMap`s, se puede usar `Codec.unboundedMap`. Esto nos dá un `Codec>`, para un `Codec` y un `Codec` dado. El codec resultante será serializado a un objeto json o el equivalente disponible en el dynamic ops actual. + +Debido a las limitaciones de json y nbt, los codecs para las llaves _deben_ ser serializados a una cadena de caracteres (string). Esto incluye codecs para tipos que no son cadenas de caracteres por su cuenta, pero si se serializan a ellas, como `Identifier.CODEC`. Vea el ejemplo a continuación: + +```java +// Crea un codec para un mapa de identificadores a numeros enteros +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// Usalo para serializar datos +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "number"), 23, + new Identifier("example", "the_cooler_number"), 42 +)); +``` + +Esto producirá este json: + +```json +{ + "example:number": 23, + "example:the_cooler_number": 42 +} +``` + +Como puedes ver, esto funciona porque `Identifier.CODEC` se serializa directamente a una cadena de caracteres. Un efecto similar puede ser logrado para objetos simples que no se serializan a cadenas de caracteres usando [xmap y sus amigos](#mutually-convertible-types-and-you) para convertirlos. + +### Tipos Mutuamente Convertibles y Tú + +#### xmap + +Digamos que tenemos dos clases que pueden ser convertidas una a la otra, pero no tienen una relación pariente-hijo. Por ejemplo un `BlockPos`y `Vec3d` vanila. Si tenemos un codec para uno, podemos usar `Codec#xmap` para crear un codec para el otro especificando una función convertidora en ambas direcciones. + +`BlockPos` ya tiene un codec, pero pretendamos que no lo tiene. Podemos crear uno para él basándolo en el codec de `Vec3d` así: + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // Convierte Vec3d a Blockpos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // Convierte BlockPos a Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// Cuando convertimos una clase ya existente (`X` por ejemplo) +// a tu propia clase (`Y`) de esta manera, puede ser útil tener +// métodos `toX` y un método estático `fromX` en la clase `Y` y usar +// referencias a métodos en tu llamado a `xmap`. +``` + +#### flatComapMap, comapFlatMap, and flatXMap + +`Codec#flatComapMap`, `Codec#comapFlatMap` y `flatXMap` son similares a xmap, pero permiten que una o ambass de las funciones convertidoras retornen un DataResult. En práctica esto es útil porque una instancia de un objeto puede no ser válida para conversión. + +Toma por ejemplo `Identifier`s vanila. Aunque todos los identificadores pueden ser convertidos a cadenas de caracteres, no todas las cadenas de caracteres son identificadores válidos, así que usar xmap significaría tirar excepciones si la conversión falla. +Debido a esto, su codec incluído es en realidad un `comapFlatMap` en `Codec.STRING`, ilustrando como se pueden usar: + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Not a valid resource location: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +Aunque estos métodos son muy útiles, sus nombres son un poco confusos, así que aquí hay una tabla para que puedas recordar mejor cuál usar: + +| Método | ¿A -> B siempre válido? | ¿B -> A siempre válido? | +| ----------------------- | ----------------------- | ----------------------- | +| `Codec#xmap` | Sí | Sí | +| `Codec#comapFlatMap` | No | Sí | +| `Codec#flatComapMap` | Sí | No | +| `Codec#flatXMap` | No | No | + +### Despachador de Registros + +`Codec#dispatch` nos permite definir un registro de codecs y despachar a uno en específico basado en el valor de un miembro en los datos serializados. Esto es muy útil cuando deserializamos objetos que tienen diferentes miembros dependiendo de su tipo, pero que igual representan la misma cosa. + +Por ejemplo, digamos que tenemos una interfaz abstracta `Bean`, con dos clases implementadoras: `StringyBean` y `CountingBean`. Para serializarlas con un despachador de registros, necesitaremos algunas cosas: + +- Codecs separados para cada tipo de bean. +- Una clase `BeanType` o un record que represente el tipo de bean, y que pueda retornar un codec para él. +- Una función en `Bean` para obtener su `BeanType`. +- Una asociación o registro para asociar `Identifier`s a `BeanType`s. +- Un `Codec>` basado en este registro. Si usas un `net.minecraft.registry.Registry`, puedes hacer una fácilmente con `Registry#getCodec`. + +Con todo esto, puedes crear un despacho de registros para beans: + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// Ahora podemos crear un codec para los tipos de bean +// basado en el registro previamente creado +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// ¡Y basado en esto, aquí esta nuestro codec de despacho de registros para beans! +// El primer argumento es el nombre del miembro para el tipo de bean. +// Cuando no se especifica, se usa el valor por defecto "type". +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::getCodec); +``` + +Nuestro nuevo codec serializará beans a json de esta manera, usando solo los campos relevantes a su tipo especificado: + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "This bean is stringy!" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### Codecs Recursivos + +A veces es útil tener un codec que se use a _sí mismo_ para decodificar ciertos miembros, por ejemplo cuando estamos lidiando con ciertas estructuras de datos recursivas. En el código vanilla, esto es usado para objetos `Text` (Texto), los cuales tienen otros objetos `Text` como hijos. Tal codec puede ser construido usando `Codec#recursive`. + +Por ejemplo, tratemos de serializar una lista enlazada. Esta manera de representar listas consiste en varios nodos que contienen un valor y una referencia al siguiente nodo en la lista. La lista es entonces representada mediante el primer nodo, y para caminar por la lista se sigue el siguiente nodo hasta que no quede ninguno. Aquí está una implementación simple de los nodos que guardan números enteros. + +```java +public record ListNode(int value, ListNode next) {} +``` + +No podemos construir un codec para esto mediante métodos ordinarios, porque ¿qué codec usaríamos para el miembro de `next`? ¡Tendríamos que usar un `Codec`, que es lo que estamos construyendo actualmente! `Codec#recursive` nos permite lograr eso con una expresión lambda mágica: + +```java +Codec codec = Codec.recursive( + "ListNode", // a name for the codec + selfCodec -> { + // Here, `selfCodec` represents the `Codec`, as if it was already constructed + // This lambda should return the codec we wanted to use from the start, + // that refers to itself through `selfCodec` + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // the `next` field will be handled recursively with the self-codec + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +Un `ListNode` serializado se podría ver algo así: + +```json +{ + "value": 2, + "next": { + "value": 3, + "next" : { + "value": 5 + } + } +} +``` + +## Fuentes y Referencias + +- Puedes encontrar una documentación más completa sobre codecs y los APIs relacionados en los [Javadocs de DFU no oficiales](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec). +- La estructura general de esta guía fue inspirada en gran medida por la [página Wiki de Forge sobre codecs](https://forge.gemwire.uk/wiki/Codecs), una versión de esta página más enfocada para Forge. diff --git a/versions/1.21/translated/es_es/develop/commands/arguments.md b/versions/1.21/translated/es_es/develop/commands/arguments.md new file mode 100644 index 000000000..d128cf4be --- /dev/null +++ b/versions/1.21/translated/es_es/develop/commands/arguments.md @@ -0,0 +1,56 @@ +--- +title: Argumentos de Comandos +description: Aprende a crear comandos con argumentos complejos. +--- + +# Argumentos de Comandos + +Los argumentos son usados en la mayoría de los comandos. Algunas veces pueden ser opcionales, lo que significa que el usuario no tiene que dar un argumento para que el comando corra. Un nodo puede tener múltiples tipos de argumentos, pero ten cuidado de no crear ambigüedades. + +@[code lang=java highlight={3} transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +En este caso, después del texto del comando `/argtater`, debes escribir un número entero. Por ejemplo, si corres `/argtater 3`, obtendrás el mensaje de respuesta `Called /argtater with value = 3`. Si escribes `/argtater` sin argumentos, el comando no puede ser leído y analizado correctamente. + +Ahora añadimos un segundo argumento opcional: + +@[code lang=java highlight={3,13} transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Ahora puedes escribir uno o dós números enteros. Si le das un número entero, se mostrará un mensaje de respuesta con un solo valor. Si das dos números enteros, se mostrará un mensaje de respuesta con dos valores. + +Puede que sientas que sea innecesario tener que especificar ejecuciones similares dos veces. Para ello, crearemos un método que se usará para ambas ejecuciones. + +@[code lang=java highlight={3,5,6,7} transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Tipos de Argumentos Personalizados + +Si el juego vanilla no tiene el tipo de argumento que necesitas, puedes crear tu propio tipo de argumento. Para esto, puedes crear una clase que implemente la interfaz `ArgumentType`, donde `T` es el tipo del argumento. + +Necesitarás implementar el método `parse`, el cual leerá y analizará la cadena de caracteres entrada por el usuario a el tipo de argumento deseado. + +Por ejemplo, puedes crear un tipo de argumento que lea un `BlockPos` a partir de una cadena de caracteres con el siguiente formato: `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Registrar Tipos de Argumentos Personalizados + +:::warning +¡Necesitas registrar el tipo de comando personalizado tanto en el servidor como en el cliente, de lo contrario, el comando no funcionará! +::: + +Puedes registrar tu propio tipo de argumento personalizado en el método `onInitialize` del inicializador de tu mod usando la clase `ArgumentTypeRegistry`: + +@[code lang=java transcludeWith=:::11](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Usar Argumentos de Comandos Personalizados + +Podemos usar nuestro tipo de argumento personalizado en un comando pasando una instancia de él al método `.argument` en el constructor del comando. + +@[code lang=java transcludeWith=:::10 highlight={3}](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Al correr el comando, podemos verificar que el tipo de argumento funciona: + +![Argumento inválido](/assets/develop/commands/custom-arguments_fail.png) + +![Argumento válido](/assets/develop/commands/custom-arguments_valid.png) + +![Resultado del comando](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/es_es/develop/commands/basics.md b/versions/1.21/translated/es_es/develop/commands/basics.md new file mode 100644 index 000000000..21cd4e671 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/commands/basics.md @@ -0,0 +1,161 @@ +--- +title: Crear Comandos +description: Crea comandos con argumentos y acciones complejas. +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple +--- + +# Crear Comandos + +La creación de comandos le permite a desarrolladores de mods añadir funcionalidad que puede ser usada mediante un comando. Este tutorial te enseñará como registrar comandos y la estructura general de comandos de Brigadier. + +:::info +Brigadier es un analizador y despachador de comandos escrito por Mojang para Minecraft. Es una libraría basada en un una estructura de árbol de comandos, donde construyes un árbol de comandos y argumentos. Brigadier es de fuente abierta: +::: + +## La interfaz `Comand` (Comando) + +`com.mojang.brigadier.Command` es una interfaz funcional, la cual corre un código específico, y tira una excepción de `CommandSyntaxException` (Excepción de Syntax de Comando) en algunos casos. Tiene un tipo genérico `S`, el cual define el tipo de la _fuente de comando_. +La fuente de comando nos dá el contexto en el que se corrió un comando. En Minecraft, la fuente de comando es típicamente un `ServerCommandSource` (Fuente de Comando de Servidor) el cual puede representar un servidor, un bloque de comandos, una conexión remota (RCON), un jugador o una entidad. + +El método `run(CommandContext)` en `Command` tiene un `CommandContext` como el único parámetro y retorna un número entero. El contexto del comando contiene la fuente de comando de `S` y te permite obtener los argumentos, ver los nodos de comando analizados y ver el valor entrado en este comando. + +Al igual que otras interfaces funcionales, puedes usar una expresión Lambda o una referencia de método: + +```java +Command command = context -> { + return 0; +}; +``` + +El número entero retornado puede ser considerado el resultado del comando. Los valores iguales o menores a 0 típicamente significan que el comando ha fallado y no hará nada. Valores positivos indican que el comando fue exitoso e hizo algo. Brigadier provee una constante para indicar éxito; `Command#SINGLE_SUCCESS` (Éxito Único). + +### ¿Qué puede hacer el `ServerCommandSource`? + +Un `ServerCommandSource` nos da contexto específico de implementación adicional cuando el comando es corrido. Esto incluye la habilidad de obtener la entidad que ejecutó el comando, el mundo o el servidor en el que el comando fue ejecutado. + +Puedes acceder la fuente del comando desde un contexto de comando llamando `getSource()` en la instancia de `CommandContext`. + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## Registrar un Comando Básico + +Los comandos son registrados mediante la clase `CommandRegistrationCallback` (Callback de Registración de Comandos) proveída por el Fabric API. + +:::info +Para información sobre como registrar callbacks, por favor visita la guía de [Eventos](../events). +::: + +El evento debería ser registrado en tu inicializador de mod. + +El callback tiene tres parámetros: + +- `CommandDispatcher dispatcher` (Despachador de comandos) - Usado para registrar, analizar y ejecutar comandos. `S` es el tipo de la fuente del comando que el despachador usa. +- `CommandRegistryAccess registryAccess` (Acceso de registro de comandos) - Provee una abstracción sobre los registros que pueden ser dados a ciertos métodos de argumentos de comandos +- `CommandManager.RegistrationEnvironment environment` (Ambiente de Registración) - Identifica el tipo de servidor en el que los comandos se están registrando en. + +En el inicializador de mod, solo registramos un comando simple: + +@[code lang=java transcludeWith=:::_1](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +En el método `sendFeedback()`, el primer parámetro es el texto a ser enviado, el cual está en un `Supplier` (Proveedor) para no tener que instanciar nuevos objetos `Text` (Texto) cuando no es necesario. + +El segundo parámetro determina si deberíamos transmitir el feedback a otros operadores. Generalmente, si el comando solo es para verificar o consultar algo sin afectar realmente el mundo, como verificar el tiempo actual o el puntaje de un jugador, este parametro debería ser `false` (falso). Si el comando hace algo, como cambiar el tiempo o modificar el puntaje de alguien, entonces debería ser `true` (verdadero). + +Si el comando falla, en vez de llamar `sendFeedback()`, puedes directamente tirar una excepción y el servidor o cliente lo manejará apropiadamente. + +`CommandSyntaxException` es generalmente tirada para indicar errores en la sintaxis del comando o sus argumentos. También puedes implementar tus propias excepciones. + +Para ejecutar este comando, debes escribir `/foo`; aquí importan las mayúsculas y minúsculas. + +### Ambiente de Registración + +Si se desea, también puedes asegurarte que un comando solo es registrado bajo ciertas circunstancias específicas, por ejemplo, solo en el ambiente dedicado: + +@[code lang=java highlight={2} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Requerimientos de Comandos + +Digamos que tienes un comando y que quieres que solo los operadores puedan ejecutarlo. Aquí entra el método `requires()`. El método `requieres()` tiene un argumento de un `Predicate` (Condición) el cual proveerá un `ServerCommandSource` el cual será probado con la condición data para determinar si el `CommandSource` puede ejecutar el comando. + +@[code lang=java highlight={3} transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Este comando solo se ejecutará si la fuente del comando es un operador nivel 2 como mínimo, incluyendo bloques de comandos. De lo contrario, el comando no es registrado. + +Esto tiene el efecto secundario de que el comando no se muestra con la auto completación con la tecla Tab a personas que no tienen operador nivel 2. Esta también es la razón por la cual no puedes autocompletar comandos cuando no tienes los trucos activados. + +### Sub Comandos + +Para agregar un sub comando, registras el primer nodo de comando normalmente. Para tener un sub comando, tienes que adjuntar el siguiente literal de nodo de comando al nodo existente. + +@[code lang=java highlight={3} transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Similarmente a los argumentos, los nodos de sub comandos pueden ser opcionales. En el siguiente caso ambos comandos `/subtater` y `/subtater subcommand` serán válidos. + +@[code lang=java highlight={2,8} transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Comandos de Cliente + +El Fabric API tiene una clase `ClientCommandManager` en el paquete de `net.fabricmc.fabric.api.client.command.v2` que puede ser usado para registrar comandos en el lado del cliente. Este código solo debe existir en el lado del cliente. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## Redireccionando Comandos + +Redireccionadores de comandos - también llamados aliases - son una manea de redireccionar la funcionalidad de un comando a otro. Esto es útil cuando quieres cambiar el nombre de un comando, pero todavía quieres mantener soporte para el nombre viejo. + +@[code lang=java transcludeWith=:::12](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## Preguntas Frequentes + +
+ +### ¿Por qué mi código no compila? + +- Atrapa o tira una excepción `CommandSyntaxException` - `CommandSyntaxException` no es una `RuntimeException` (Excepción en Tiempo de Ejecución). Si la tiras, debe ser en métodos que tiren un `CommandSyntaxException` en el signature (firma) del método, o ser atrapadas. + Brigadier manejará las excepciones checked (comprobadas) y mandará el mensaje de error correspondiente en el juego para ti. + +- Problemas con genéricos - Puede que tengas problemas con genéricos de vez en cuando. Si estás registrando comandos de servidor (el cual es mayormente el caso), asegúrate de usar `CommandManager.literal` o `CommandManager.argument` en vez de `LiteralArgumentBuilder.literal` o `RequiredArgumentBuilder.argument`. + +- Verifica el método de `sendFeedback()` - Puede que te hayas olvidado de dar el valor booleano al segundo argumento. También recurda que, a partir de Minecraft 1.20, el primer parámetro es un `Supplier` en vez de `Text`. + +- Un comando debería retornar un número entero - Cuando registres comandos, el método `executes()` acepta un objeto `Command`, el cual usualmente es una expresión Lambda. El Lambda debería retornar un número entero, en lugar de otros tipos de valores. + +### ¿Puedo registrar comandos durante la ejecución? + +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +Después de eso, debes enviar el árbol de comandos a cada jugador de nuevo usando `CommandManager.sendCommandTree(ServerPlayerEntity)`. + +Esto es necesario porque el cliente almacena en un caché el árbol de comandos que recibe durante inicio de sesión (o cuando paquetes de operador son enviados) para mensajes de error con completaciones locales. +::: + +### ¿Puedo des-registrar comandos durante la ejecución? + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +Para mantener las cosas simples, vas a tener que usar reflexión en Brigadier para remover nodos. Después de esto, necesitas enviar el árbol de comandos de nuevo a cada jugador usando `sendCommandTree(ServerPlayerEntity)`. + +Si no envias el árbol de comandos actualizado, el cliente pensará que un comando existe, aunque el servidor no podrá ejecutarlo. +::: diff --git a/versions/1.21/translated/es_es/develop/commands/suggestions.md b/versions/1.21/translated/es_es/develop/commands/suggestions.md new file mode 100644 index 000000000..544d1093d --- /dev/null +++ b/versions/1.21/translated/es_es/develop/commands/suggestions.md @@ -0,0 +1,45 @@ +--- +title: Sugerencias de Comandos +description: Aprende a sugerir valores para argumentos de comandos a usuarios. +authors: + - IMB11 +--- + +# Sugerencias de Comandos + +Minecraft tiene un poderoso sistema de sugerencias de comandos que es usado en muchos lugares, como en el comanado de `/give`. Este sistema te permite sugerir valores para argumentos de comandos al usuario, donde este puede escoger de estos valores - es una buena manera de hacer tus comandos más ergonómicos y amigables al usuario. + +## Proveedores de Sugerencias + +Un `SuggestionProvider` (Proveedor de Sugerencias) es usado para crear una lista de sugerencias que serán enviadas al cliente. Un proveedor de sugerencias es una interfaz funcional que tiene un parámetro de `CommandContext` y un `SuggestionBuilder` (Constructor de Sugerencias), y retorna algunos `Suggestions` (Sugerencias). El `SuggestionProvider` retorna un `CompletableFuture` (Completador a Futuro) ya que las sugerencias pueden no estar disponibles inmediatamente. + +## Usar Proveedores de Sugerencias + +Para usar un proveedor de sugerencias, tienes que llamar el método `suggests` en el constructor del argumento. Este método tiene un parámetro `SuggestionProvider` y retorna un nuevo constructor de argumento con el proveedor de sugerencias adjuntado. + +@[code java transcludeWith=:::9 highlight={4}](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Proveedores de Sugerencias Incluidos + +Hay algunos proveedores de sugerencias incluidos que puedes usar: + +| Proveedor de Sugerencias | Descripción | +| ----------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | Sugiere todas las entidades que pueden ser convocadas. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | Sugiere todos los efectos de sonido que pueden ser reproducidos. | +| `LootCommand.SUGGESTION_PROVIDER` | Sugiere todas las loot tables (tablas de loot) que están disponibles. | +| `SuggestionProviders.ALL_BIOMES` | Sugiere todos los biomas disponibles. | + +## Crear un Proveedor de Sugerencias Personalizado + +Si un proveedor incluido no suficiente para tus necesidades, puedes crear tu propio proveedor de sugerencias. Para esto, debes crear una clase que implemente la interfaz `SuggestionProvider` y que anule el método `getSuggestions`. + +Para este ejemplo, haremos un proveedor de sugerencias que sugiere todos los nombres de usuario de los jugadores en el servidor. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +Para usar este proveedor de sugerencias, simplemente pasa una instancia de él en el método `.suggests` en el constructor del argumento. + +Obviamente, los proveedores de sugerencias pueden ser más complejos, ya que también el contexto del comando para proveer sugerencias basadas en el estado del comando - como los argumentos que ya han sido dados. + +Esto puede ser en la forma de leer el inventario del jugador y sugerir items, o entidades que estén cerca del jugador. diff --git a/versions/1.21/translated/es_es/develop/entities/damage-types.md b/versions/1.21/translated/es_es/develop/entities/damage-types.md new file mode 100644 index 000000000..42018b2c5 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/entities/damage-types.md @@ -0,0 +1,96 @@ +--- +title: Tipos de Daño +description: Aprende a agregar tipos de daño personalizados. +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# Tipos de Daño + +Los tipos de daño definen los tipos de daño que pueden tomar las entidades. Desde Minecraft 1.19.4, la creación de nuevos tipos de daño se ha vuelto basada en datos, lo que significa que se crean mediante archivos JSON. + +## Creando un Tipo de Daño + +Procedamos a crear un nuevo tipo de daño llamado _Tater_. Empezaremos creando el archivo JSON para tu tipo de daño. Este archivo será puesto en el folder de `data` de tu mod, en un sub-folder llamado `damage_types`. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +Tiene la siguiente estructura: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +Este tipo de daño personalizado causa un aumento de 0.1 en [cansancio de hambre](https://minecraft.wiki/w/Hunger#Exhaustion_level_increase) cada vez que el jugador toma daño, cuando el daño es ocasionado por una fuente viviente que no sea otro jugador (por ejemplo, un bloque). Adicionalmente, la cantidad de daño dado dependerá de la dificultad del mundo + +::: info + +Verifica la [Wiki de Minecraft](https://minecraft.wiki/w/Damage_type#JSON_format) para ver todas las posibles llaves y valores. + +::: + +### Accediendo los Tipos de Daño en El Código + +Cuando necesitamos acceder nuestro tipo de daño en el código, necesitaremos usar su `RegistryKey` (Llave de Registro) para crear una instancia de `DamageSource` (Fuente de Daño). + +El `RegistryKey` puede ser obtenida de la siguiente manera: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### Usando los Tipos de Daño + +Para demostrar el uso de tipos de daño personalizados, usaremos un bloque personalizado llamado **Tater Block**. Hagamos que cuando una entidad viviente pise sobre un **Bloque de Tater**, dará un daño de _Tater_. + +Puedes anular el método `onSteppedOn` para dar este daño. + +Empezamos creando un `DamageSource` de nuestro tipo de daño personalizado. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Después, llamamos `entity.damage()` con nuestro `DamageSource` y una cantidad. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +La implementación del bloque completa: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Ahora cuando una entidad viviente pise sobre nuestro bloque personalizado, tomará 5 de daño (2.5 corazones) usando nuestro tipo de daño personalizado. + +### Mensaje de Muerte Personalizado + +Puedes definir un mensje de muerte para el tipo de daño en el formato de `death.attack.` en nuestro archivo `en_us.json` de nuestro mod. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +Cuando suceda una muerta por nuestro tipo de daño, verás el siguiente mensaje: + +![Efecto en el inventario del jugador](/assets/develop/tater-damage-death.png) + +### Etiquetas de Tipo de Daño + +Algunos tipos de daño pueden pasar por la armadura, efectos de estado, y similares. Los Tags (Etiquetas) controlan estos tipos de propiedades de los tipos de daño. + +Puedes encontrar los tags de tipos de daño existentes en `data/minecraft/tags/damage_type`. + +::: info + +Verifica la [Wiki de Minecraft](https://minecraft.wiki/w/Tag#Damage_types) para una lista completa de los tags de tipo de daño. + +::: + +Agreguemos nuestro tipo de daño de Tater al tag de `bypasses_armor`. + +Para agregar nuestro tipo de daño a uno de estos tags, crearemos un archivo JSON bajo el namespace de `minecraft`. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +Con el siguiente contenido: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +Asegúrate que tu tag no reemplace el tag existente dándole un valor de `false` a la llave de `replace`. diff --git a/versions/1.21/translated/es_es/develop/entities/effects.md b/versions/1.21/translated/es_es/develop/entities/effects.md new file mode 100644 index 000000000..48511f7a8 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/entities/effects.md @@ -0,0 +1,69 @@ +--- +title: Efectos de Estado +description: Aprende a añadir efectos de estado personalizados. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil +authors-nogithub: + - siglong + - tao0lu +--- + +# Efectos de Estado + +Los efectos de estado, o simplemente estados, son una condición que puede afectar a una entidad. Pueden ser positivos, negativos o neutrales en naturaleza. El juego base aplica estos efectos de varias maneras como comida, pociones, etc. + +El comando `/effect` puede ser usado para aplicar efectos en una entidad. + +## Efectos de Estado Personalizados + +En este tutorial añadiremos un nuevo efecto de estado personalizado llamado _Tater_, el cual te da un punto de experiencia por cada tick del juego. + +### Extiende `StatusEffect` + +Vamos a crear una para nuestro efecto de estado personalizado extendiendo la clase `StatusEffect`, el cual es la clase base para todos los efectos. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### Registrar tu Efecto Personalizado + +Similar a la registración de bloques e items, usamos `Registry.register` para registrar nuestro efecto personalizado en el registro de `STATUS_EFFECT`. Esto se puede hacer en nuestro inicializador. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### Traducciones y Texturas + +Puedes asignar un nombre a tu efecto de estado y proveer una textura de ícono para que aparezca en la pantalla de inventario. + +#### Textura + +El ícono del efecto de estado es una imagen PNG de 18x18 pixeles. Coloca tu ícono personalizado en: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + +![Efecto en el inventario del jugador](/assets/develop/tater-effect.png) + +#### Traducciones + +Como cualquier otra traducción, puedes agregar una entrada con el formato de ID `"effect..": "Valor"` al archivo de idioma. + +::: code-group + +```json[assets/fabric-docs-reference/lang/en_us.json] +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### Probando + +Usa el comando `/effect give @p fabric-docs-reference:tater` para darle al jugador nuestro efecto Tater. Usa el comando `/effect clear` para remover el efecto. + +::: info +Para crear una poción que use este efecto, por favor visita la guía sobre [Pociones](../items/potions). +::: diff --git a/versions/1.21/translated/es_es/develop/events.md b/versions/1.21/translated/es_es/develop/events.md new file mode 100644 index 000000000..c26845e0b --- /dev/null +++ b/versions/1.21/translated/es_es/develop/events.md @@ -0,0 +1,124 @@ +--- +title: Eventos +description: Una guía para usar los eventos ofrecidos por el Fabric API. +authors: + - dicedpixels + - mkpoli + - daomephsta + - solidblock + - draylar + - jamieswhiteshirt + - PhoenixVX + - Juuxel + - YanisBft + - liach + - natanfudge +authors-nogithub: + - stormyfabric +--- + +# Eventos + +El Fabric API provee un sistema que le permite a los mods reaccionar a ciertas acciones u ocurrencias, definidas como _eventos_ que ocurren en el juego. + +Los eventos son enganches que satisfacen usos comunes y/o proveen mejor compatibilidad y rendimiento entre diferentes mods que se enganchan a las mismas áreas del código. El uso de eventos substituye el uso de mixins. + +El Fabric API provee eventos para áreas importantes en el código fuente de Minecraft, las cuales son de interés a desarrolladores de mods para engancharse en. + +Los eventos son representados por instancias de `net.fabricmc.fabric.api.event.Event`, el cual guarda y también llama _callbacks_. Usualmente solo hay una instancia del evento para un callback, el cual es almacenado en un miembro estático `EVENT` en la interfaz del callback, pero también hay otros patrones. Por ejemplo, `ClientTickEvents` agrupa varios eventos relacionados juntos. + +## Callbacks + +Un callback es una porción de código pasada como un argumento a un evento. Cuando el evento es activado por el juego, el código pasado será ejecutado. + +### Interfaces de Callbacks + +Cada evento tiene su propia interfaz de callback, convencionalmente llamada `Callback`. Los callbacks son registrados llamando el método `register()` en una instancia del evento, con una instancia de la interfaz del callback como el argumento. + +Todas las interfaces de callbacks para eventos proveídas por el Fabric API pueden ser encontradas en el paquete `net.fabricmc.fabric.api.event`. + +## Detectando Eventos + +### Un Ejemplo Sencillo + +Este ejemplo registra un `AttackBlockCallback` para atacar el jugador cuando este golpea bloques que no sueltan un item cuando son minados con la mano. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +### Añadiendo Items a Loot Tables Existentes + +A veces, uno desea añadir items a loot tables (o tablas que determinan los items soltados por un objeto, como bloque o entidad). Por ejemplo, añadir tus drops a un bloque o entidad vanilla. + +La solución más simple, la cual es reemplazar el archivo del loot table, puede romper otros mods. ¿Qué tal si otros mods también quierer cambiar el loot table? Echaremos un vistazo a como puedes agregar items a los loot tables sin tener que anularla. + +Agregaremos huevos al loot table del bloque de mena de hierro. + +#### Detectando el Cargado de Loot Tables + +El Fabric API tiene un evento que es llamado cuando los loot tables son cargados, llamado `LootTableEvents.MODIFY`. Puedes registrar un callback para el evento en tu inicializador de mod. Verifiquemos también que el loot table actual sea el del bloque de mena de hierro. + +@[code lang=java transclude={38-40}](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +#### Agregando Items al Loot Table + +En los loot tableas, los items son almacenados en _loot pool entries_ (o entradas en el grupo de loots), y las entradas son guardadas en _loot pools_ (o grupos de loot). Para agregar un item, necesitaremos agregar un grupo con una entrada de item al loot table. + +Podemos crear un grupo con `LootPool#builder`, y agregarlo al loot table. + +Nuestro grupo no tiene ningún item, asique haremos una entrada de item usando `ItemEntry#builder`, y la agregaremos al grupo. + +@[code highlight={6-7} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +## Eventos Personalizados + +Algunas áreas del juego no tienen enganches proveídos por el Fabric API, así que puedes usar un mixin o puedes crear tu propio evento. + +Veremos como crear un evento que es llamado cuando una oveja es esquilada. El proceso de creación de un evento es: + +- Crear la interfaz de callback del evento +- Activando el evento desde un mixin +- Crear una implementación de prueba + +### Crear la interfaz de callback del evento + +La interfaz de callback describe lo que debe ser implementado por los usuarios del evento que detectarán tu evento. La interfaz del callback también describe como el evento será llamado desde nuestro mixin. Es convencional poner un objecto `Event` como un miembro en la interfaz de callback, el cual identificará nuestro evento. + +Para nuestra implementación de `Event`, escogeremos usar un evento respaldado por un array (array-backed event). El array contendrá todos los escuchadores de evento que están detectando este evento. + +Nuestra implementación llamará los escuchadores de evento en orden hasta que uno de ellos no retorne `ActionResult.PASS`. Esto signfica que un usuario puede decir "_cancela esto_", "_aprueba esto_" o "_no me importa, déjaselo al siguiente escuchador del evento_" usando el valor retornado. + +Usar `ActionResult` como valor de retorno es una manera convencional para hacer que los diferentes usuarios del evento cooperen de esta manera. + +Necesitarás crear una interfaz que tiene una instancia de `Event` y un método para la implementación de la respuesta. Una configuración básica para nuestro callback de esquilado de oveja es: + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Veamos este códigdo con más detalle. Cuando el invocador es llamado, iteramos sobre todos los escuchadores: + +@[code lang=java transclude={21-22}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Entonces llamamos nuestro método (en este caso, `interact`), en el escuchador para obtener su respuesta: + +@[code lang=java transclude={33-33}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Si el escuchador dice que tenemos que cancelar (`ActionResult.FAIL`) o terminar completamente (`ActionResult.SUCCESS`), el callback retorna el resultado y termina el loop. `ActionResult.PASS` prosigue al siguiente escuchador, y en la mayoría de los casos debería resultar en éxito si no hay más escuchadores registrados: + +@[code lang=java transclude={25-30}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Podemos agregar Javadocs por encima de las clases de callback para documentar que es lo que hace cada `ActionResult`. En nuestro caso, puede ser: + +@[code lang=java transclude={9-16}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +### Activando el Evento Desde un Mixin + +Ya tenemos el esqueleto básico de nuestro evento, pero necesitamos llamarlo o activarlo. Ya que queremos que nuestro evento sea llamado cuando un jugador trata de esquilar una oveja, podemos llamado el invocador `invoker` del evento en `SheepEntity#interactMob`, cuando el método `sheared()` es llamado (osea que la oveja puede ser esquilada, y el jugador está sosteniendo tijeras): + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java) + +### Creando una Implementación de Prueba + +Ahora necesitamos probar nuestro evento. Puedes registrar un escuchador en tu método de inicialización (o en otro lugar, si lo prefieres) y poner tu propio código ahí. En este ejemplo, cuando la oveja es esquilada, suelta un diamante en vez de lana: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +Si entras al juego y esquilas una oveja, un diamante debería ser soltado en vez de lana. diff --git a/versions/1.21/translated/es_es/develop/getting-started/creating-a-project.md b/versions/1.21/translated/es_es/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..de3b6850b --- /dev/null +++ b/versions/1.21/translated/es_es/develop/getting-started/creating-a-project.md @@ -0,0 +1,68 @@ +--- +title: Creando un Proyecto +description: Una guía paso a paso sobre como crear un proyecto de mod usando el generador de plantillas de mods de Fabric. +authors: + - IMB11 +--- + +# Creando un Proyecto + +Fabric provee una manera fácil de crear un nuevo proyecto de mod usando el Generador de Plantillas de Mods de Fabric - si quieres, puedes crear un nuevo proyecto manualmelnte usando el repositorio del mod de ejemplo, deberías visitar la sección de [Creación Manual de Proyectos](#manual-project-creation). + +## Generando un Proyecto + +Puedes usar el [Generador de Plantillas de Mods de Fabric](https://fabricmc.net/develop/template/) para generar un nuevo proyecto para tu mod - deberías llenar los campos requeridos, como el nombre del paquete y el nombre del mod, y la versión de Minecraft para la cual quieres desarrollar. + +![Vista previa del generador](/assets/develop/getting-started/template-generator.png) + +Si quieres usar Kotlin, o quieres agregar generadores de datos, puedes seleccionar las opciones correspondientes en la sección de `Advanced Options` (Opciones Avanzadas). + +![Sección de Opciones Avanzadas](/assets/develop/getting-started/template-generator-advanced.png) + +Una vez llenados los campos requeridos, haz clic en el botón de `Generate` (Generar), y el generador creará un nuevo proyecto para ti en la forma de archivo zip. + +Deberías extraer este archivo zip en un lugar de tu elección, y luego abre el folder extraído en IntelliJ IDEA: + +![Sugerencia de Proyecto Abierto](/assets/develop/getting-started/open-project.png) + +## Importando el Proyecto + +Una vez que has abierto el proyecto en IntelliJ IDEA, el IDEA debería automáticamente cargar las configuraciones de Gradle y realizar las tareas de configuración necesarias. + +Si recibes una notificación que habla sobre un _script_ de Gradle, deberías hacer clic en el botón de `Import Gradle Project` (Importar Proyecto de Gradle): + +![Sugerencia de Gradle](/assets/develop/getting-started/gradle-prompt.png) + +Una vez que el proyecto ha sido importado, deberías ver los archivos del proyecto en el explorador del proyecto, y deberías poder empezar a desarrollar tu mod. + +## Creación Manual de Proyectos + +:::warning +Necesitarás tener instalado [Git](https://git-scm.com/) para clonar el repositorio del mod de ejemplo. +::: + +Si no puedes usar el Generador de Plantillas de Mods de Fabric, puedes crear un nuevo proyecto siguiendo los siguientes pasos. + +Primero, clona el repositorio del mod de ejemplo usando Git: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +Esto clonará el repositorio a un nuevo folder llamado `my-mod-project`. + +Después, deberías eliminar el folder de `.git` del repositorio clonado, y luego abre el proyecto en IntelliJ IDEA. Si el folder de `.git` no aparece, deberías habilitar la visualización de archivos ocultos en tu administrador de archivos. + +Una vez que has abierto el proyecto en IntelliJ IDEA, el IDEA debería automáticamente cargar las configuraciones de Gradle y realizar las tareas de configuración necesarias. + +Nuevamente, como ya hemos dicho, si recibes una notificación que habla sobre un _script_ de Gradle, deberías hacer clic en el botón de `Import Gradle Project` (Importar Proyecto de Gradle). + +### Modificando La Plantilla + +Una vez que el proyecto ha sido importado, deberías poder modificar los detalles del proyecto para que encajen con los detalles de tu mod: + +- Modifica el archivo de `gradle.properties` de tu proyecto para cambiar las propiedades de `maven_group` (grupo de maven) y `archive_base_name` (nombre base del archivo) para que sean los de tu mod. +- Modifica el archivo de `fabric.mod.json` para cambiar las propiedades de `id`, `name`, y `description` para que sean los de tu mod. +- Asegúrate de actualizar las versiones de Minecraft, los mapeos, el cargador de Fabric y Loom - todos ellos pueden ser consultados en https://fabricmc.net/develop/ - para tener las versiones deseadas. + +Obviamente también puedes cambiar el nombre del paquete y la clase principal para que sean las de tu mod. diff --git a/versions/1.21/translated/es_es/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/es_es/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..433c0baed --- /dev/null +++ b/versions/1.21/translated/es_es/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Introducción a Fabric y el desarrollo de Mods +description: "Una breve introducción a Fabric y el desarrollo de mods en Minecraft: Edición de Java." +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Introducción a Fabric y el desarrollo de Mods + +## Requisitos Previos + +Antes de empezar, deberías tener un entendimiento básico de programación en Java, y conocimiento de Programación Orientada a Objetos (POO). + +Si no estás familiarizados con estos conceptos, deberías investigar algunos tutoriales sobre Java y POO antes de que empiezas a desarrollar mods, aquí hay algunos de los recursos que puedes usar para aprender Java y POO: + +- [W3: Java Tutorials](https://www.w3schools.com/java/) +- [Codecademy: Learn Java](https://www.codecademy.com/learn/learn-java) +- [W3: Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium: Introduction to OOP](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### Terminología + +Antes de empezar, veamos algunos de los términos que usaremos cuando desarrollemos mods para Fabric: + +- **Mod**: Una modificación al juego, que añade nuevas funciones o características o que cambia funciones o características existentes. +- **Mod Loader** (Lanzador o Cargador de Mods): Una herramienta que carga los mods en el juego, como el Lanzador de Fabric. +- **Mixin**: Una herramienta para modificar el código del juego durante el tiempo de ejecución - visita [Introducción a los Mixins](https://fabricmc.net/wiki/tutorial:mixin_introduction) para más información. +- **Gradle**: Una herramienta para la automatización de construcción que se usa para compilar y construir los mods, usado por Fabric para construir mods. +- **Mappings** (Mapeos): Un conjunto de mapeos que traducen o "mapean" código ofuscado a código legible. +- **Obfuscation** (Ofuscación): El proceso de hacer que el código sea difícil de entender, usando por Mojang para proteger el código de Minecraft. +- **Remapping** (Remapeado): El proceso de mapear código ofuscado a código legible. + +## ¿Qué es Fabric? + +Fabric is un conjunto de herramientas ligeras para moddear Minecraft: Edición de Java. + +Está diseñado para ser una plataforma de moddeado simple y fácil de entender. Fabric es un proyecto dirigido por la comunidad, y es de fuente abierta, lo que significa que cualquiera puede contribuir al proyecto. + +Deberías saber de los cuatro componentes principales de Fabric: + +- **Fabric Loader** (Lanzador de Fabric): Un lanzador de mods flexible diseñado para Minecraft y otros juegos y aplicaciones, que funciona independiente de la plataforma. +- **Fabric Loom**: Un plugin o extensión de Gradle para desarrollar y depurar mods fácilmente. +- **Fabric API**: Un conjunto de APIs y herramientas para desarrolladores de mods para ser usadas durante la creación de mods. +- **Yarn**: Un conjunto de mapeos de Fabric abiertos. Cualquiera puede usarlos bajo la licencia de Creative Commons Zero. + +## ¿Por qué es necesario Fabric para crear mods para Minecraft? + +> El moddeado es el proceso de modificar el juego con el fin de cambiar su comportamiento y añadir nuevas funciones - en el caso de Minecraft, esto puede ser cualquier cosa, como añadir nuevos items, bloques, o entidades, o cambiar las mecánicas del juego o añadiendo nuevos modos de juego. + +Minecraft: Edición de Java es ofuscado por Mojang, haciendo que la modificación sea dificil por sí sola. Sin embargo, mediante la ayuda de herramientas para la creación de mods como Fabric, la creación de mods se hace mucho más facil. Hay varios sistemas sde mapeo que pueden asistir en el proceso. + +Loom remappea el código ofuscado a código legible usando estos mappings, permitiéndole a los desarrolladores de mods entender y modificar el código del juego. Yarn es una elección popular y excelente para los mpapings, pero también existen otras opciones. Cada proyecto de mappings tiene sus propias ventajas o enfoque. + +Loom te permite fácilmente desarrollar y compilar mods basados en código remapeado, y el Lanzador de Fabric te permite cargar estos mods en el juego. + +## ¿Qué provee el Fabric API, y por qué es necesario? + +> El Fabric API es un conjunto de APIs y herramientas para desarrolladores de mods para ser usadas durante la creación de mods. + +Fabric API provee un conjunto amplio de APIs basadas en la funcionalidad de Minecraft existente - por ejemplo, provee nuevos ganchos y eventos para ser usados por desarrolladores de mods, o provee nuevas utilidades para facilitar el desarrollo de mods - como _access wideners_ (ampliadores de acceso) transitivos y la abilidad de usar registros internos, como el registro de items compostables. + +Mientras que Fabric API ofrece funciones poderosas, algunas tares, como la registración básica de bloques, puede ser lograda sin ella, usando los APIs vanilla. diff --git a/versions/1.21/translated/es_es/develop/getting-started/launching-the-game.md b/versions/1.21/translated/es_es/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..b3bc88c95 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/getting-started/launching-the-game.md @@ -0,0 +1,63 @@ +--- +title: Corriendo tu Juego +description: Aprende a utilizar los perfiles de lanzamiento varios para cargar y depurar tus mods en un entorno de juego en vivo. +authors: + - IMB11 +--- + +# Corriendo tu Juego + +Fabric Loom provee una variedad de perfiles de lanzamiento para ayudarte a correr y depurar tus mods en un entorno de juego en vivo. Esta guía cubrirá los perfiles de lanzamiento varios y como usarlos para depurar y probar tus mods. + +## Perfiles de Lanzamiento + +Si estás usando IntelliJ IDEA, puedes encontrar los perfiles de lanzamiento en la esquina superior derecha de la ventana. Haz clic en el menú desplegable para ver los perfiles de lanzamiento disponibles. + +Debería haber un perfil para el cliente y el servidor, con la opción de correr cualquiera de los dos normalmente o en modo de depuración: + +![Perfiles de Lanzamiento](/assets/develop/getting-started/launch-profiles.png) + +## Tareas de Gradle + +Si estás usando la línea de comandos, puedes usar los siguientes comandos de Gradle para empezar el juego: + +- `./gradlew runClient` - Lanza el juego en modo de cliente. +- `./gradlew runServer` - Lanza el juego en modo de servidor. + +El único problema con esta opción es que no puedes depurar tu código fácilmente. Si quieres depurar tu código, deberás usar los perfiles de lanzamiento en IntelliJ IDEA o mediante la integración de Gradle de tu IDE. + +## Intercambiar Clases en tiempo de ejecución + +Cuando corres el juego en modo de depuración, puedes intercambiar clases sin tener que reiniciar el juego. Esto es útil para probar cambios en tu código rápidamente. + +Sin embargo, existen varias limitaciones: + +- No puedes agregar o remover métodos +- No puedes cambiar los parámetros de un método +- No puedes agregar o remover miembros + +## Intercambiar Mixins en tiempo de ejecución + +Si estás usando Mixins, puedes intercambiar tus clases de Mixin sin tener que reiniciar el juego. Esto es útil para probar cambios en tu Mixins rápidamente. + +Sin embargo, deberás instalar el _Mixin java agent_ para que esto funcione. + +### 1. Localiza el _Mixin Library Jar_ (Jar de Librería de Mixin) + +En IntelliJ IDEA, puedes encontrar el jar de librería de mixin en la sección de "Librerías Externas" en la sección de "Proyecto": + +![Librería de Mixin](/assets/develop/getting-started/mixin-library.png) + +Deberás copiar el "absolute path" (dirección absoluta) del jar para el siguiente paso. + +### 2. Agrega el argumento de VM de `-javaagent` + +En tus perfiles de lanzamiento de "Minecraft Client" y/o "Minecraft Server", agrega los siguientes argumentos de VM: + +```:no-line-numbers +-javaagent:"dirección absoluta del jar de librería de mixin aquí" +``` + +![Captura de pantalla los Argumentos de VM](/assets/develop/getting-started/vm-arguments.png) + +Ahora deberías poder modificar los contenidos de tus métodos mixin durante la depuración y ver los cambios en el juego sin tener que reiniciarlo. diff --git a/versions/1.21/translated/es_es/develop/getting-started/project-structure.md b/versions/1.21/translated/es_es/develop/getting-started/project-structure.md new file mode 100644 index 000000000..139328511 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/getting-started/project-structure.md @@ -0,0 +1,59 @@ +--- +title: Estructura de Proyecto +description: Una descripción general de la estructura de un proyecto de mod de Fabric. +authors: + - IMB11 +--- + +# Estructura de Proyecto + +Esta página cubrirá la estructura de un proyecto de mod de Fabric, y el propósito de cada archivo y folder en el proyecto. + +## `fabric.mod.json` + +El archivo `fabric.mod.json` es el archivo principal que describe tu mod al Lanzador de Fabric. Contiene información como el ID del mod, versión, y dependencias. + +Los campos más importantes en el archivo `fabric.mod.json` son: + +- `id`: El ID del mod, el cual debería ser único. +- `name`: El nombre del mod. +- `enviornment`: El entorno en el que tu mod será corrido en, como `client`, `server` o `*` para ambos. +- `entrypoints`: Los puntos de entrada que tu mod provee, como `main` o `client`. +- `depends:` Los mods en los que tu mod depende en. +- `mixins:` Los mixins que tu mod provee. + +Puedes ver un ejemplo del archivo `fabric.mod.json` abajo - este es el archivo `fabric.mod.json` del proyecto de referencia que este sitio de documentación utiliza. + +:::details Proyecto de Referencia `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## Puntos de Entrada + +Como ya fue mencionado, el archivo `fabric.mod.json` contiene un campo llamado `entrypoints` - este campo es usado para especificar los puntos de entrada que tu mod usa. + +El generador de plantillas de mods crea los puntos de entrada `main` y `client` por defecto - el punto de entrada de `main` es usado para código común, mientras que el punto de entrada de `client` es usado para código exclusivo o específico para el cliente. Estos puntos de entrada son llamados respectivamente cuando el juego comienza. + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +Lo anterior es un ejemplo de un punto de entrada de `main` simple, el cual manda un mensaje a la consola cuando el juego empieza. + +## `src/main/resources` + +El folder `src/main/resources` es usado para guardar los recursos que tu mod usa, como las texturas, modelos, y sonidos. + +Aquí también se puede encontrar el archivo `fabric.mod.json` y cualquier archivo de configuración de mixin que tu mod use. + +Los _assets_ o recursos son guardados en una estructura que es similar a la estructura de los paquetes de recursos - por ejemplo, una textura para un bloque sería guardada en `assets/modid/textures/block/block.png`. + +## `src/client/resources` + +El folder de `src/client/resources` es usado para guardar recursos específicos al cliente, como las texturas, modelos, y sonidos que solo son usados en el lado del cliente. + +## `src/main/java` + +El folder de `src/main/java` es usado para guardar el código fuente de Java para tu mod - existe tanto los entornos del cliente y el servidor. + +## `src/client/java` + +El folder de `src/client/java` es usado para guardar el código fuente de Java exclusivo del cliente, como código para renderización o lógica para el lado del cliente - como proveedores de colores de bloque. diff --git a/versions/1.21/translated/es_es/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/es_es/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..5061e6a03 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: Configurando tu entorno de desarrollo +description: Una guía paso a paso para como configurar un entorno de desarollo para crear mods usando Fabric. +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# Configurando tu entorno de desarrollo + +Para empezar a desarollar mods usando Fabric, necesitarás configurar un entorno de desarrollo usando IntelliJ IDEA. + +## Instalar Java 17 + +Para desarrollar mods para Minecraft 1.20.4, necesitarás JDK 17. + +Si necesitas ayuda instalando Java, puedes ver nuestras guías sobre la instalación de Java en la [sección de guías para jugadores](../../players/index) + +## Instalando IntelliJ IDEA + +:::info +Obviamente puedes usar otros IDEs, como Eclipse o Visual Studio Code, pero la mayoría de las páginas en esta documentación asumirán que estás usando IntelliJ IDEA - deberías visitar la documentación para tu IDE si estás usando alguno diferente. +::: + +Si no tienes IntelliJ IDEA instalado, puedes descargarlo desde la [página web oficial](https://www.jetbrains.com/idea/download/) - sigue los pasos de instalación para tu sistema operativo. + +La edición de Comunidad de IntelliJ IDEA es gratis y de fuente abierta, y es la versión recomendada para desarrollar mods con Fabric. + +Puede que tengas que deslizar la página hacia abajo para encontrar los enlaces para descargar la edición de Comunidad - se ve de la siguiente manera: + +![Sugerencia de descarga de IntelliJ edición de Comunidad](/assets/develop/getting-started/idea-community.png) + +## Instalando _Plugins_ en IDEA + +Aunque estos plugins no son estrictamente necesarios, hacen el desarrollo de mods con Fabric mucho más fácil - deberías considerar instalarlos. + +### Minecraft Development + +El plugin de Minecraft Development provee soporte para desarrollar mods con Fabric, y es el plugin más importante para instalar. + +Puedes instalarlo abriendo IntelliJ IDEA, y luego navegando a `File > Settings > Plugins > Marketplace Tab` - busca `Minecraft Development` en la barra de búsqueda, y luego haz clic en el botón de `Install` (Instalar). + +Alternativamente, puedes descargarlo desde la [página web del plugin](https://plugins.jetbrains.com/plugin/8327-minecraft-development) y luego puedes instalarlo navegando a `File > Settings > Plutins > Install Plugin from Disk`. diff --git a/versions/1.21/translated/es_es/develop/index.md b/versions/1.21/translated/es_es/develop/index.md new file mode 100644 index 000000000..83bcdf156 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/index.md @@ -0,0 +1,12 @@ +--- +title: Guías para Desarrolladores +description: Nuestras guías para desarrolladores, escritas por la comunidad, cubren una amplia gama de temas, desde la configuración de un entorno de desarrollo hasta temas más avanzados como renderizado y redes. +--- + +# Guías para Desarrolladores + +Nuestras guías para desarrolladores seleccionadas, escritas por la comunidad, cubren una amplia gama de temas, desde la configuración de un entorno de desarrollo hasta temas más avanzados como renderizado y redes. + +Echa un vistazo a la barra lateral para ver una lista de todas las guías para desarrolladores disponibles. Si buscas algo específico, puedes utilizar la barra de búsqueda en la parte superior de la página para encontrar lo que necesitas. + +Si desea contribuir a la Documentación de Fabric, puede encontrar el código fuente en [GitHub](https://github.com/FabricMC/fabric-docs) y las [pautas de contribución](../contributing) relevantes diff --git a/versions/1.21/translated/es_es/develop/rendering/draw-context.md b/versions/1.21/translated/es_es/develop/rendering/draw-context.md new file mode 100644 index 000000000..9df0a0337 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/rendering/draw-context.md @@ -0,0 +1,94 @@ +--- +title: Usando el Contexto de Dibujado +description: Aprende a como usar la clase `DrawContext` para renderizar varios objectos, texto y texturas. +authors: + - IMB11 +--- + +# Usando el Contexto de Dibujado + +Esta página asume que ya has visto la página de [Conceptos Básicos de Renderizado](./basic-concepts). + +La clase `DrawContext` es la clase principal usada para renderizar cosas en el juego. Es usada para renderizar objetos, texto y texturas y, como ya hemos visto, es usada para manipular diferentes `MatrixStack`s y usar `BufferBuilder`s. + +## Dibujar Formas + +La clase `DrawContext` puede ser usada para fácilmente dibujar formas **basadas en cuadrados**. Si quieres dibujar triángulos, o cualquier forma no basada en cuadrados, necesitarás usar un `BufferBuilder`. + +### Dibujando Rectángulos + +Puedes usar el método `DrawContext.fill(...)` para dibujar un rectángulo rellenado. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Un rectángulo](/assets/develop/rendering/draw-context-rectangle.png) + +### Dibujar Contornos/Bordes + +Digamos que queremos delinear el rectángulo que acabamos de dibujar. Podemos usar el método `DrawContext.drawBorder(...)` para dibujar un contorno. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Rectángulo con bordes](/assets/develop/rendering/draw-context-rectangle-border.png) + +### Dibujar Líneas Individuales + +Podemos usar los métodos `DrawContext.drawHorizontalLine(...)` y `DrawContext.drawVerticalLine(...)` para dibujar líneas. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Líneas](/assets/develop/rendering/draw-context-lines.png) + +## El _Scissor Manager_ (Gestor de Tijeras) + +La clase `DrawContext` tiene un _scissor manager_ ya incluido. Esto te permite cortar tu renderizado a un área específica. Esto es útil para renderizar cosas como un _tooltip_ (información de herramienta), u otros elementos que no deberían ser renderizados fuera un área en específico. + +### Usando el _Scissor Manager_ + +:::tip +¡Las regiones de tijeras pueden ser anidadas! Pero asegúrate de deshabilitar el _scissor manager_ la misma cantidad de veces que lo habilitaste. +::: + +Para habilitar el _scissor manager_, simplemente usa el método `DrawContext.enableScissor(...)`. De igual forma, para deshabilitar el _scissor manager_, usa el método `DrawContext.disableScissor()`. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Regiones de tijera en acción](/assets/develop/rendering/draw-context-scissor.png) + +Como puedes ver, aunque le dijimos al juego que renderice la gradiente por toda la pantalla, solo hace dentro de la región de tijera. + +## Dibujar Texturas + +No hay una sola manera "correcta" de dibujar texturas en la pantalla, ya que el método `drawTexture(...)` tiene varias sobrecargas. Esta sección cubrirá los usos más comunes. + +### Dibujar una Textura Entera + +Generalmente, es recomendado que uses la sobrecarga que especifique los parámetros de `textureWidth` y el `textureHeight`. Esto es porque la clase `DrawContext` asumirá estos valores si no los provees, los cuales pueden estar incorrectos algunas veces. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Ejemplo de diubjar la textura entera](/assets/develop/rendering/draw-context-whole-texture.png) + +### Dibujar una Porción de una Textura + +Aquí es donde `u` y `v` entran en pie. Estos parámetros especifican la esquina superior izquierda de la textura a dibujar, y los parámetros `regionWidth` y `regionHeight` especifican el tamaño de la porción de las texturas a dibujar. + +Tomemos esta textura como ejemplo. + +![Textura del Libro de Recetas](/assets/develop/rendering/draw-context-recipe-book-background.png) + +Si solo queremos dibujar una región que contiene el lente magnificador, podemos usar los siguientes valores para `u`, `v`, `regionWidth`, y `regionHeight`: + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Región de Textura](/assets/develop/rendering/draw-context-region-texture.png) + +## Dibujar Texto + +La clase `DrawContext` tiene varios métodos fáciles de entender para renderizar texto - para ser breves, no serán cubiertos aquí. + +Digamos que queremos dibujar "Hello World" en la pantalla. Podemos usar el método `DrawContext.drawText(...)` para esto. + +@[code lang=java transcludeWith=:::7](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Dibujar Texto](/assets/develop/rendering/draw-context-text.png) diff --git a/versions/1.21/translated/es_es/develop/rendering/gui/custom-screens.md b/versions/1.21/translated/es_es/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..18dddd3b7 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/rendering/gui/custom-screens.md @@ -0,0 +1,64 @@ +--- +title: Pantallas Personalizadas +description: Aprende a crear pantallas y menús personalizadas para tu mod. +authors: + - IMB11 +--- + +# Pantallas Personalizadas + +:::info +Esta página se refiere a pantallas normales, y no pantallas manejadas - estas pantallas son las que son abiertas por el jugador en el cliente, no las que son manejadas por el servidor. +::: + +Las pantallas son esencialmente la interfaz gráfica con la que jugador interactúa con, como el menú principal, el menú de pausa, etc. + +Puedes crear tus propios menús para mostrar contenido personalizado, un menú de configuraciones personalizado, o más. + +## Creando una Pantalla + +Para crear una pantalla, necesitarás extender la clase `Screen` y anular el método `init` (inicializar) - opcionalmente también anular el método `render` - pero asegúrate de llamar su implementación súper, de lo contrario no se renderizará el fondo, los widgets, etc. + +Toma en cuenta que: + +- Los widgets no son creados en el constructor de la clase porque la pantalla aún no ha sido inicializada a este punto - y ciertas variables, como `width` (ancho) y `height` (altura), aún no están disponibles o no tienen valores correctos. +- El método `init` es llamado cuando la pantalla es inicializada, y es el mejor lugar para crear widgets. + - Agregas widgets usando el método `addDrawableChild`, el cual acepta cualquier widget dibujable. +- El método `render` es llamado en cada frame - puedes acceder el contexto de dibujado, y la posición del mouse desde este método. + +Por ejemplo, podemos crear una pantalla simple que tiene un botón y una etiqueta arriba. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Pantalla Personalizada 1](/assets/develop/rendering/gui/custom-1-example.png) + +## Abrir La Panatalla + +Puedes abrir la pantalla usando el método `setScreen` de la clase `MinecraftClient` - puedes hacer esto desde muchos lugares, como un _key binding_, un comando, o un manipulador de paquetes de cliente. + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## Cerrar La Pantalla + +Si quieres cerrar la pantalla, simplemente establece la pantalla actual a un valor `null` (nulo): + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +Si quieres ser más elegante, y retornar a la pantalla anterior, puedes pasar la pantalla actual al constructor de la clase de `CustomScreen` y guardarla en un miembro, y después puedes usarlo para volver a la pantalla anterior cuando el método `close` es llamado. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +Ahora, cuando abramos la pantalla personalizada, puedes pasar la pantalla actual como el segundo argumento - para que cuando llames `CustomScreen#close` - volverá a la pantalla anterior. + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/translated/es_es/develop/rendering/gui/custom-widgets.md b/versions/1.21/translated/es_es/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..a8d3d57c2 --- /dev/null +++ b/versions/1.21/translated/es_es/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,39 @@ +--- +title: Widgets Personalizados +description: Aprende a crear widgets personalizados para tus pantallas o menús. +authors: + - IMB11 +--- + +# Widgets Personalizados + +Los widgets son esencialmente componentes renderizados que pueden ser agregados a una pantalla, y que pueden ser usados por el jugador mediante varios eventos como un click del mouse, presionar una tecla, y más. + +## Crear un Widget + +Hay varias maneras de crear una clase widget, como extender `ClickableWidget` (Widget Clickeable). Esta clase provee varias utilidades, como por ejemplo para manejar el ancho, la altura, la posición, y para manejar eventos - implementa las interfaces `Drawable` (Dibujable), `Element` (Elemento), `Narratable` (Narrable), y `Selectable` (Seleccionable): + +- `Drawable` - para renderizar - Requerido para registrar el widget a la pantalla mediante el método `addDrawableChild`. +- `Element` - para eventos - Requerido para manejar eventos como clicks del mouse, cuando se presiona una tecla, y más. +- `Narratable` - para accesibilidad - Requerido para que tu widget sea accesible a lectores de pantalla y otras herramientas de accesibilidad. +- `Seleccionable` - para selecciones - Requerido si quieres que tu widget sea seleccionable usando la tecla Tab - esto también ayuda en accesibilidad. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## Agregar el Widget a La Pantalla + +Como todos los widgets, necesitarás agregarlo a la pantalla mediante el método `addDrawableChild`, el cual es proveído por la clase `Screen`. Asegúrate de hacerlo en el método `init`. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Widget personalizado en la pantalla](/assets/develop/rendering/gui/custom-widget-example.png) + +## Eventos de Widget + +Puedes manejar eventos como clicks del mouse, cuando se presiona una tecla, anulando el método `onMouseClicked` (duranteMouseClickeado), `onMouseReleased` (duranteMouseSoltado), `onKeyPressed` (duranteTeclaPresionada), y otros métodos. + +Por ejemplo, puedes hacer que el widget cambie color cuando el mouse está flotando encima del widget usando el método `isHovering()` proveído por la clase `ClickableWidget`: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![Ejemplo de Evento de Mouse Flotando](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/translated/es_es/develop/rendering/particles/creating-particles.md b/versions/1.21/translated/es_es/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..f1c81138f --- /dev/null +++ b/versions/1.21/translated/es_es/develop/rendering/particles/creating-particles.md @@ -0,0 +1,72 @@ +--- +title: Creando Partículas Personalizadas +description: Aprende a crear partículas personalizadas usando el Fabric API. +authors: + - Superkat32 +--- + +# Creando Partículas Personalizadas + +Las partículas son una poderosa herramienta. Pueden agregar atmósfera a una hermosa escena, o agregar tensión durante una pelea contra un jefe. ¡Agreguemos una! + +## Registrar una partícula personalizada + +Agregaremos una nueva partícula brillante cuyo movimiento se asemejara al de la partícula de una vara del end. + +Primero tenemos que registrar un `ParticleType` (Tipo de Partícula) en nuestra clase inicializadora de mod usando nuestro _mod id_. + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +El "sparkle_particle" en letras minúsculas es la dirección JSON para la textura de la partícula. Crearás un archivo JSON con ese mismo nombre más adelante. + +## Registración en el Cliente + +Después de registrar la partícula en la entrada de `ModInitializer`, también necesitarás registrar la partícula en la entrada de `ClientModInitializer` (Inicializador del Mod de Cliente). + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +En este ejemplo, estamos registrando nuestra partícula en el lado del cliente. Después estamos dándole movimiento usando la fábrica de partículas de la vara del end. Esto significa que nuestra partícula se moverá exactamente como una partícula de vara del end. + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- Tecla de acceso rápido de IntelliJ: Ctrl+Alt+B +- Tecla de acceso rápido de Visual Studio Code: Ctrl+F12 + ::: + +## Crear el archivo JSON y añadir texturas + +Tienes que crear 2 folders in tu folder de `resources/assets//`. + +| Dirección del Folder | Explicación | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `/textures/particle` | El folder de `particle` (partícula) contendrá todas las texturas para todas tus partículas. | +| `/particles` | El folder de `particles` (partículas) contendrá todos los archivos json de todas tus partículas. | + +Para este ejemplo, solo tendremos una textura en `textures/particle` llamada "sparkle_particle_texture.png". + +Después, creamos un nuevo archivo JSON en `particles` con el mismo nombre que la dirección JSON que usaste para registrar tu `ParticleType`. Para este ejemplo, tendremos que crear `sparkle_particle.json`. Este archivo es importante, ya que le hace saber a Minecraft que texturas debería usar para nuestra partícula. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +:::tip +Puedes agregar más texturas al array de `texturas` para crear una animación de partícula. La partícula rotará las texturas en el array, empezando con la primera textura. +::: + +## Probando la nueva partícula + +¡Una vez que termines tu archivo JSON y hayas guardado tu trabajo, ya puedes iniciar Minecraft y probar que todo esté bien! + +Puedes ver si todo ha funcionado correctamente con el siguiente comando: + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![La partícula siendo mostrada](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +:::info +La partícula aparecerá dentro de la cabeza del jugador con este comando. Probablemente tengas que caminar para atrás para poder verla. +::: + +También puedes usar un bloque de comandos para invocar la partícula con el mismo comando. diff --git a/versions/1.21/translated/es_es/develop/sounds/custom.md b/versions/1.21/translated/es_es/develop/sounds/custom.md new file mode 100644 index 000000000..5f5425b5a --- /dev/null +++ b/versions/1.21/translated/es_es/develop/sounds/custom.md @@ -0,0 +1,63 @@ +--- +title: Crear Sonidos Personalizados +description: Aprende a agregar y usar un nuevo sonido con el registro. +authors: + - JR1811 +--- + +# Crear Sonidos Personalizados + +## Preparando el archivo del sonido + +Tus archivos de sonido tienen que estar formateados de una manera específica. OGG Vorbis es un formato de contenedor abierto para datos multimedia, como audio, y es usado para los archivos de sonido de Minecraft. Para evitar problemas con la manera en que Minecraft maneja el distanciamiento, tu audio tiene que tener solo un canal (Mono). + +Muchos software de DAWs (Estaciones de Trabajo de Audio Digitales) modernos pueden importar y exportar usando este formato de archivo. En el siguiente ejemplo el software gratuito y de fuente abierta "[Audacity](https://www.audacityteam.org/)" será usado para traer el archivo de sonido al formato correcto, aunque cualquier otro DAW debería ser suficiente también. + +![archivo de sonido sin preparar en Audacity](/assets/develop/sounds/custom_sounds_0.png) + +En este ejemplo, un sonido de un [silbido](https://freesound.org/people/strongbot/sounds/568995/) es importado a Audacity. Actualmente está guardado como un archivo ".wav" y tiene dos canales de audio (Stereo). Edita el sonido a tu gusto y asegúrate de eliminar uno de los canales usando el menú desplegable encima del "track head" (cabeza de pista). + +![dividiendo la pista Estereo](/assets/develop/sounds/custom_sounds_1.png) + +![eliminando uno de los canales](/assets/develop/sounds/custom_sounds_2.png) + +Al exportar o renderizar el archivo de audio, asegúrate de elegir el formato de archivo OGG. Algunos DAWs, como REAPER, pueden soportar múltiples capas de audio de OGG. En este caso, OGG Vorbis debería funcionar bien. + +![exportar como archivo OGG](/assets/develop/sounds/custom_sounds_3.png) + +También ten en cuenta que los archivos de audio pueden aumentar el tamaño de tu mod drásticamente. Si es necesario, comprime el audio cuando lo edites y exportes el archivo para mantener el tamaño de tu producto final a un mínimo. + +## Cargando El Archivo de Audio + +Agrega un nuevo folder `resources/assets//sounds` para los sonidos en tu mod, y pon el archivo de audio exportado `metal_whistle.ogg` ahí. + +Continúa creando el archivo `resources/assets//sounds.json` si no existe todavía y agrega tu sonido a las entradas de sonido. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json) + +La entrada de subtítulo provee más contexto para el jugador. El nombre del subtítulo es usado en los archivos de lenguaje en el folder de `resources/assets//lang` y serán mostrados si la opción de subtítulos en el juego es activada y el sonido personalizado está siendo reproducido. + +## Registrando el Sonido Personalizado + +Para agregar el sonido personalizado al mod, registra un SoundEvent (Evento de Sonido) en la clase que implemente la interfaz `ModInitializer`. + +```java +Registry.register(Registries.SOUND_EVENT, new Identifier(MOD_ID, "metal_whistle"), + SoundEvent.of(new Identifier(MOD_ID, "metal_whistle"))); +``` + +## Limpiando El Desorden + +Dependiendo de cuantas entradas de Registro hayan, las cosas pueden enredarse rápidamente. Para evitar eso, podemos hacer uso de una nueva clase ayudante. + +Agrega dos nuevos métodos a la nueva clase ayudante creada. Uno, que registre todos los sonidos y uno que es usado para inicializar esta clase en primer lugar. Después de eso, puedes agregar nuevos miembros estáticos de `SoundEvent` cómodamente como sea necesario. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java) + +De esta manera, la clase implementadora de `ModInitializer` solo tiene que implementar una línea para registrar todos los SoundEvents personalizados. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java) + +## Usando el SoundEvent Personalizado + +Use la clase ayudante para acceder el SoundEvent personalizado. Echa un vistazo a la página de [Reproducir SoundEvents (Eventos de Sonido)](./using-sounds) para aprender a reproducir sonidos. diff --git a/versions/1.21/translated/es_es/develop/sounds/using-sounds.md b/versions/1.21/translated/es_es/develop/sounds/using-sounds.md new file mode 100644 index 000000000..0046e3a7c --- /dev/null +++ b/versions/1.21/translated/es_es/develop/sounds/using-sounds.md @@ -0,0 +1,32 @@ +--- +title: Reproducir SoundEvents (Eventos de Sonido) +description: Aprende a reproducir eventos de sonido. +--- + +# Reproducir SoundEvents (Eventos de Sonido) + +Minecraft tiene una gran selección de sonidos para elegir. Mira la clase de `SoundEvents` para ver todas las instancias de eventos de sonido vanilla que Mojang provee. + +## Usando Sonidos en Tu Mod + +¡Asegúrate de ejecutar el método `playSond()` en el lado del servidor lógico cuando uses sonidos! + +En este ejemplo, los métodos de `useOnEntity()` y `useOnBlock()` para un item interactivo personalizado son usados para reproducir sonidos de "colocar un bloque de cobre" y de saqueador. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +El método `playSound()` es usado con el objeto de `LivingEntity` (Entidad Viviente). Solamente se tienen que especificar el SoundEvent, el volumen y el tono. También puedes usar el método de `playSound()` de la instancia del mundo para tener un mayor grado de control. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +### SoundEvent y SoundCategory (Categoría de Sonido) + +El SoundEvent define que sonido será reproducido. También puedes [registrar tu propio SoundEvent](./custom) para incluir tu propio sonido. + +Minecraft tiene varios deslizadores de audio en las opciones del juego. El enum (enumeración) de `SoundCategory` es usado para determinar que deslizador ajustará el volumen de tu sonido. + +### Volumen y Tono + +El parámetro de volumen puede ser algo engañoso. El volumen del sonido puede ser cambiado en el rango de `0.0f - 1.0f`. Si el número es mayor que eso, el volumen de `1.0f` será usado y solo la distancia la que tu sonido puede ser escuchado, será ajustada. La distancia en bloques puede ser calculada aproximadamente con `volumen * 16`. + +El parámetro de tono aumenta o disminuye el valor de tono y también cambia la duración del sonido. En el rango `(0.5f - 1.0f)` el tono y la velocidad son disminuídas, mientras que valores números incrementarán el tono y la velocidad. Números por debajo de `0.5f` se mantendrán en el valor de tono de `0.5f`. diff --git a/versions/1.21/translated/es_es/index.md b/versions/1.21/translated/es_es/index.md new file mode 100644 index 000000000..b810556f2 --- /dev/null +++ b/versions/1.21/translated/es_es/index.md @@ -0,0 +1,27 @@ +--- +title: Documentación de Fabric +description: La documentación oficial para Fabric, un conjunto de herramientas para desarrollar mods para Minecraft. +layout: home +hero: + name: Documentación de Fabric + tagline: La documentación oficial seleccionada para Fabric, una cadena de herramientas de modificación para Minecraft. +features: + - title: Guías para Desarrolladores + icon: 🛠️ + details: Nuestras guías para desarrolladores, escritas por la comunidad, cubren una amplia gama de temas, desde la configuración de un entorno de desarrollo hasta temas más avanzados como renderizado y redes. + link: /develop/ + linkText: Empezar + - title: Guías para Jugadores + icon: 📚 + details: ¿Eres un jugador buscando mods hechos en Fabric? Nuestras guías para jugadores te tienen cubierto. Estas guías te ayudarán en la descarga, instalación, y solución de problemas de mods de Fabric. + link: /players/ + linkText: Leer más +--- + +
+ +## ¿Quieres contribuir? + +Si quieres contribuir a la Documentación de Fabric, puedes encontrar el código fuente en [GitHub](https://github.com/FabricMC/fabric-docs), y las [pautas de contribución](./contributing) relevantes. + +
diff --git a/versions/1.21/translated/es_es/players/faq.md b/versions/1.21/translated/es_es/players/faq.md new file mode 100644 index 000000000..76eeda18c --- /dev/null +++ b/versions/1.21/translated/es_es/players/faq.md @@ -0,0 +1,31 @@ +--- +title: Preguntas Frecuentes para Jugadores +description: Preguntas frecuentes para jugadores y administradores de servidores relacionadas con Fabric. +--- + +# Preguntas Frecuentes + +Hay varias preguntas que se hacen con frecuencia, por lo que hemos compilado una lista de ellas aquí. + +## Preguntas Generales + +### ¿Qué versiones de Minecraft son compatibles con Fabric? + +Oficialmente, Fabric es compatible con todas las versiones de Minecraft empezando desde la snapshot `18w43b` en adelante, y la versión de salida `1.14` en adelante. + +### ¿Donde puedo descargar mods de Fabric publicados? + +:::info +Siempre debes asegurarte que los mods sean de una fuente confiable. Visita la guía de [Encontrar Mods Confiables](./finding-mods) para mayor información. +::: + +La mayoría de desarrolladores publican sus mods en [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) y [CurseForge](https://www.curseforge.com/minecraft/search?page=1&pageSize=20&sortType=1&class=mc-mods&gameFlavorsIds=4), aunque algunos prefieren subir sus mods en sus páginas web personales, o en otras plataformas, como sus repositorios de Github. + +### ¿Dónde puedo encontrar modpacks para Fabric? + +Puedes encontrar modpacks para Fabric en varias plataformas, como: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/es_es/players/finding-mods.md b/versions/1.21/translated/es_es/players/finding-mods.md new file mode 100644 index 000000000..5cba3fb50 --- /dev/null +++ b/versions/1.21/translated/es_es/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Encontrar Mods Confiables +description: Una guía sobre como encontrar mods de Fabric usando fuentes confiables. +authors: + - IMB11 +--- + +# Encontrar Mods Confiables + +En primer lugar, el término "confiable" es subjetivo, así que siempre usa tu propio juicio y sentido común a la hora de descargar mods. Sin embargo, hay algunas cosas que puedes hacer para encontrar mods confiables. + +## 1. Usa una fuente conocida por su confiabilidad y seguridad + +La mayoría de desarrolladores publican sus mods en [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) y [CurseForge](https://www.curseforge.com/minecraft/search?page=1&pageSize=20&sortType=1&class=mc-mods&gameFlavorsIds=4). + +Estas páginas web verifican los mods hacen lo que dicen hacer, y que no contengan código malicioso. También puedes reportar mods maliciosos en esas páginas web, y tomarán acción relativamente rápida. + +## 2. ¡Verifica con otros! + +Si descargas un mod desde una fuente que no es conocida por ser segura, puedes verificar con otros para ver si ellos han descargado el mod antes desde la misma fuente que tu, y verificar si han tenido problemas con ella. + +Si no estás seguro, eres bienvenido a consultar en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support`. + +## 3. ¡Evita sitios con malware comunes! + +:::info +Identificar páginas web con malware no es algo obvio para todos. Si no estás seguro, deberías consultar por opiniones de otros o evitar el sitio completamente y solamente usar fuentes seguras, como Modrinth y CurseForge. +::: + +Hay muchas páginas web que dicen tener mods para Minecraft, pero en realidad solo contienen malware. Debes evitar estos sitios a toda costa. + +Puedes usar software de antivirus y páginas web como [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) o [VirusTotal](https://www.virustotal.com/) para verificar los mods descargados. Sin embargo, no te bases completamente en esos métodos, ya que pueden producir resultados incorrectos. + +Para reiterar, eres bienvenido a consultar en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support`. diff --git a/versions/1.21/translated/es_es/players/index.md b/versions/1.21/translated/es_es/players/index.md new file mode 100644 index 000000000..07e88cef4 --- /dev/null +++ b/versions/1.21/translated/es_es/players/index.md @@ -0,0 +1,12 @@ +--- +title: Guías para Jugadores +description: Una colección de guías para jugadores y administradores sobre la instalación y el uso de Fabric. +--- + +# Guías para Jugadores + +Esta sección de la Documentación de Fabric está dedicada con jugadores y administradores de servidores que quieren aprender sobre como instalar, y usar, y solucionar problemas relacionados con Fabric. + +Puedes consultar la barra lateral para una lista de las guías disponibles. + +Si encuentras problemas, por favor repórtalos [en GitHub](https://github.com/FabricMC/fabric-docs) o pide ayuda en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support` o `#server-admin-support`. diff --git a/versions/1.21/translated/es_es/players/installing-fabric.md b/versions/1.21/translated/es_es/players/installing-fabric.md new file mode 100644 index 000000000..8ce64f1ff --- /dev/null +++ b/versions/1.21/translated/es_es/players/installing-fabric.md @@ -0,0 +1,55 @@ +--- +title: Instalar Fabric +description: Una guía paso a paso sobre como instalar Fabric. +authors: + - IMB11 +--- + +# Instalar Fabric + +Esta guía te enseñará sobre como instalar Fabric usando el launcher oficial de Minecraft. + +Para launchers o lanzadores de terceros, deberías consultar su documentación. + +## 1. Descarga el instalador de Fabric + +Puedes descargar el instalador de Fabric desde la [Página web de Fabric](https://fabricmc.net/use/). + +Si estás en Windows, descarga el archivo `.exe` (`Download For Windows`), ya que este no requiere que Java esté instalado en tu sistema. Este en cambio usa la instalación de Java que viene con el launcher oficial. + +Si estás en macOS o Linux, descarga la versión `.jar`. En algunas ocasiones, necesitarás instalar Java antes de este paso. + +## 2. Corre el instalador de Fabric + +:::warning +Cierra Minecraft y el Launcher de Minecraft antes de la instalación. +::: + +:::details Información para usuarios de MacOS + +En macOS, puede que tengas que hacer clic derecho en el archivo `.jar` en tu folder de descargas y hacer clic en `Abrir` para correrlo. + +![Instalador de Fabric con "Instalar" remarcado](/assets/players/installing-fabric/macos-downloads.png) + +Cuando aparezca la pregunta "¿Estás seguro de que quieres abrirlo?", has clic en `Abrir` de nuevo. +::: + +Una vez abierto el instalador, deberías ver una pantalla como la siguiente: + +![Instalador de Fabric con "Instalar" remarcado](/assets/players/installing-fabric/installer-screen.png) + +Para instalar Fabric, simplemente escoge tu versión del juego desde el menú deslizador, y cliquea en `Instalar`. + +**Asegurate de que la opción 'Crear Perfil' esté escogida.** + +## 3. ¡Hemos terminado! + +¡Una vez que la instalación haya terminado, puedes abrir el Launcher de Minecraft y seleccionar el perfil de Fabric desde el menú deslizador en la esquina inferior izquierda y presionar Jugar! + +![Launcher de Minecraft con el perfil de Fabric seleccionado](/assets/players/installing-fabric/launcher-screen.png) + +## Siguientes Pasos + +¡Ahora que has instalado Fabric, puedes agregar mods a tu juego! Visita la guía de [Encontrar Mods Confiables](./finding-mods) para mayor información. + +Si encuentras problemas tratando de seguir esta guía, puedes solicitar ayuda en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support`. diff --git a/versions/1.21/translated/es_es/players/installing-java/linux.md b/versions/1.21/translated/es_es/players/installing-java/linux.md new file mode 100644 index 000000000..deed41f03 --- /dev/null +++ b/versions/1.21/translated/es_es/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Instalar Java en Linux +description: Una guía paso a paso sobre como instalar Java en Linux. +authors: + - IMB11 +--- + +# Instalar Java en Linux + +Esta guía te enseñará como instalar Java 17 en Linux. + +## 1. Verifica si Java ya está instalado + +Abre una terminal, escribe `java -version`, y presiona Enter. + +![Terminal con el comando "java -version" escrito](/assets/players/installing-java/linux-java-version.png) + +:::warning +Para jugar en la mayoría de las versiones modernas de Minecraft, necesitarás Java 17 como mínimo. Si este comando muestra una versión de Java menor a 17, necesitarás actualizar tu instalación de Java existente. +::: + +## 2. Descargar e Instalar Java 17 + +Recomendamos usar OpenJDK 17, el cual está disponible en múltiples distribuciones de Linux. + +### Arch Linux + +:::info +Para más información sobre como instalar Java en Linux, visita la [Wiki de Arch Linux](https://wiki.archlinux.org/title/Java). +::: + +Puedes instalar el JRE (Entorno de Ejecución de Java) desde los respositorios oficiales: + +```sh +sudo pacman -S jre-openjdk +``` + +Si estás corriendo un servidor sin una interfaz gráfica, puedes instalar la versión "headless" (sin cabecera) en su lugar: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Si planeas desarrollar mods, necesitarás el JDK (Entorno de Desarrollo de Java) en cambio: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu + +Puedes instalar Java 17 usando `apt` con los siguientes comandos: + +```sh +sudo apt update +sudo apt install openjdk-17-jdk +``` + +### Fedora + +Puedes instalar Java 17 usando `dnf` con los siguientes comandos: + +```sh +sudo dnf install java-17-openjdk +``` + +Si no requieres de una interfaz gráfica, puedes instalar la versión "headless" en su lugar: + +```sh +sudo dnf install java-17-openjdk-headless +``` + +Si planeas desarrollar mods, necesitarás el JDK en cambio: + +```sh +sudo dnf install java-17-openjdk-devel +``` + +### Otras Distribuciones de Linux + +Si tu distribución no está mencionada arriba, puedes descargar el último JRE desde [Adoptium](https://adoptium.net/temurin/) + +Puedes consultar otra guía para tu distribución si planeas desarrollar mods. + +## 3. Verifica si Java 17 ya está instalado + +Una vez terminada la instalación, puedes verificar si Java 17 ya está instalado abriendo una terminal y escribiendo el comando `java -version`. + +Si el comando corre exitosamente, deberías ver algo similar a lo mostrado antes, donde se muestra la versión de Java: + +![Terminal con el comando "java -version" escrito](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/es_es/players/installing-java/windows.md b/versions/1.21/translated/es_es/players/installing-java/windows.md new file mode 100644 index 000000000..d469780a8 --- /dev/null +++ b/versions/1.21/translated/es_es/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Instalar Java en Windows +description: Una guía paso a paso sobre como instalar Java en Windows. +authors: + - IMB11 +--- + +# Instalar en Java en Windows + +Esta guía te enseñará como instalar Java 17 en Windows. + +El launcher de Minecraft viene con su propia instalación de Java, por lo que esta sección solo es relevante si quieres usar el instalador de Fabric `.jar`, o si quieres usar el `.jar` del Servidor de Minecraft. + +## 1. Verifica si Java ya está instalado + +Para comprobar si Java ya está instalado, primero debes abrir la línea de comandos. + +Puedes abrirla presionando Win + R y escribiendo `cmd.exe` en la caja de texto que aparece. + +![Diálogo de Ejecución de Windows con "cmd.exe" en la barra de ejecución](/assets/players/installing-java/windows-run-dialog.png) + +Una vez abierta la línea de comandos, escribe `java -version` y presiona Enter. + +Si el comando corre exitosamente, verás algo similar a esto. Si el comando falla, procede al siguiente paso. + +![Línea de comandos con "java -version" escrito](/assets/players/installing-java/windows-java-version.png) + +:::warning +Para usar la mayoría de las versiones modernas de Minecraft, necesitarás Java 17 instalado como mínimo. Si el comando muestra cualquier versión menor a 17, necesitarás actualizar tu instalación de Java existente. +::: + +## 2. Descarga el instalador de Java 17 + +Para instalar Java 17, debes descargar el instalar desde [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows&package=jdk&version=17). + +Querrás descargar la versión `Windows Installer (.msi)`: + +![Página de descargas de Adoptium con el Windows Installer (.msi) remarcado](/assets/players/installing-java/windows-download-java.png) + +Escoge `x86` si tienes un sistema operativo de 32 bits, o `x64` si tienes un sistema operativo de 64 bits. + +La mayoría de las computadoras modernas tienen un sistema operativo de 64 bits. Si no estás seguro, intenta con la descarga de 64 bits. + +## 3. ¡Corre el instalador! + +Sigue los pasos del instalador para instalar Java 17. Cuando llegues a esta página, debes elegir la opción de "La funcionalidad entera será instalada en el disco duro local" para las siguientes funcionalidades: + +- `Set JAVA_HOME environment variable` - Esto será agregado a tu PATH. +- `JavaSoft (Oracle) registry keys` + +![Instalador de Java 17 con "Set JAVA_HOME variable" y "JavaSoft (Oracle) registry keys" remarcados](/assets/players/installing-java/windows-wizard-screenshot.png) + +Una vez terminado, puedes hacer clic en `Next` y continuar con la instalación. + +## 4. Verificar si Java 17 ya está instalado + +Una vez terminada la instalación, puedes verificar si Java 17 está instalado abriendo la línea de comandos de nuevo y escribiendo `java -version`. + +Si el comando corre exitosamente, verás algo similar a lo mostrado antes, donde la versión de Java se muestra: + +![Línea de comandos con "java -version" escrito](/assets/players/installing-java/windows-java-version.png) + +--- + +Si encuentras problemas, puedes pedir ayuda en el canal de `#player-support` en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv). diff --git a/versions/1.21/translated/es_es/players/installing-mods.md b/versions/1.21/translated/es_es/players/installing-mods.md new file mode 100644 index 000000000..af0f12d4d --- /dev/null +++ b/versions/1.21/translated/es_es/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Instalar Mods +description: Una guía paso a paso sobre como instalar mods para Fabric. +authors: + - IMB11 +--- + +# Instalar Mods + +Esta guía te enseñará sobre como instalar mods para Fabric usando el Launcher de Minecraft. + +Para launchers o lanzadores de terceros, consulta su documentación. + +## 1. Descarga el Mod + +:::warning +Solo deberías descargar mods desde fuentes en las que confíes. Para mayor información sobre como encontrar mods, visita la guía sobre [Encontrar Mods Confiables](./finding-mods). +::: + +La mayoría de los mods requieren Fabric API, el cual puede ser descargado desde [Modrinth](https://modrinth.com/mod/fabric-api) o [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api) + +Cuando descargues mods, asegúrate que: + +- Son compatibles con la versión de Minecraft en la que juegues. Por ejemplo, un mod que funcione en la versión 1.20, puede que no funcione en la versión 1.20.2. +- Son hechos para Fabric y no otro lanzador de mods (mod loader). +- Finalmente, que sean compatibles con la edición de Minecraft correcta (Edición de Java). + +## 2. Mueve el archivo del mod al folder de `mods` + +El folder de mods puede ser encontrado en las siguientes localizaciones dependiendo de tu sistema operativo. + +Usualmente puedes copiar y pegar estas direcciones de archivo en la barra de direcciones de tu explorador de archivos para encontrar el folder rápidamente. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Una vez que hayas encontrado el folder de `mods`, puedes colocar el archivo `.jar` del mod ahí. + +![Mods instalados en el folder de mods](/assets/players/installing-mods.png) + +## 3. ¡Hemos terminado! + +¡Una vez que hayas movido los mods al folder de `mods`, puedes abrir el Launcher de Minecraft, seleccionar el perfil de Fabric desde el menú deslizador en la esquina inferior izquierda y presionar Jugar! + +![Launcher de Minecraft con el perfil de Fabric seleccionado](/assets/players/installing-fabric/launcher-screen.png) + +## Solucionar Problemas + +Si encuentras problemas tratando de seguir esta guía, puedes solicitar ayuda en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support`. + +También puedes intentar solucionar el problema tu mismo leyendo las guías sobre como solucionar problemas: + +- [Reportes de Crasheo](./troubleshooting/crash-reports) +- [Subir Logs](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/es_es/players/troubleshooting/crash-reports.md b/versions/1.21/translated/es_es/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..d4bbbe77c --- /dev/null +++ b/versions/1.21/translated/es_es/players/troubleshooting/crash-reports.md @@ -0,0 +1,111 @@ +--- +title: Reportes de Crasheos +description: Aprender sobre que hacer con los reportes de crasheo, y como leerlos. +authors: + - IMB11 +--- + +at snownee.snow.block.ShapeCaches.get(ShapeCaches.java:51) +at snownee.snow.block.SnowWallBlock.method_9549(SnowWallBlock.java:26) // [!code focus] +... +at me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache.shouldDrawSide(BlockOcclusionCache.java:52) +at link.infra.indium.renderer.render.TerrainBlockRenderInfo.shouldDrawFaceInner(TerrainBlockRenderInfo.java:31) +... +=================================================== + +:::tip +Si estás teniendo dificultades encontrando la causa del crasheo, puedes pedir ayuda en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support` o `server-admin-support`. +::: + +Los reportes de crasheo son importantes para la solución de problemas con tu juego o servidor. Contienen mucha información sobre el crasheo, y pueden ayudarte a encontrar la causa del crasheo. + +## Encontrar los Reportes de Crasheo + +Los reportes de crasheo se encuentran en el folder de `crash-reports` en el folder de tu juego. Si estás usando un servidor, se encuentran en el folder de `crash-reports` en el folder del servidor. + +Para launchers de terceros, puedes referirte a su documentación sobre donde encontrar los reportes de crasheo. + +Los reportes de crasheo pueden ser encontrados en los siguientes lugares: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Leer los Reportes de Crasheo + +Los reportes de crasheo son muy largos, y pueden ser confusos de leer. Sin embargo, contienen mucha información sobre el crasheo, y pueden ayudarte a encontrar la causa del crasheo. + +Para esta guía, estaremos utilizando el [siguiente reporte de crasheo como ejemplo](https://github.com/FabricMC/fabric-docs/blob/main/public/assets/players/crash-report-example.txt). + +:::details Reportes de Crasheos + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Secciones del Reporte de Crasheo + +Los reportes de crasheo consisten de varias secciones, cada una separada por un encabezado: + +- `---- Minecraft Crash Report ----`, el resumen del reporte. Esta sección contiene el error principal que ocasionó el crasheo, el tiempo en el que ocurrió, y el stack trace relevante. Esta es la sección más importante del reporte de crasheo, ya que el stack trace usualmente contiene referencias al mod que casuó el crasheo. +- `-- Last Reload --`, esta sección no es muy útil almenos que el crasheo ocurrió durante una recarga de recursos (F3+T). Esta sección contiene el tiempo en el que se hizo la última recarga de recursos, y el stack trace relevante de errores que ocurrieron durante el proceso de recarga. Estos errores usualmente son causados por paquetes de recursos, y pueden ser ignorados al menos que estén causando problemas en el juego. +- `-- System Details --`, esta sección contiene información sobre tu sistema, como el sistema operativo, la versión de Java, y la cantidad de memoria RAM alocada para el juego. Esta sección es útil para determinar si estás usando la versión correcta de Java, y si tienes suficiente memoria alocada para el juego. + - En esta sección, Fabric incluye una línea personalizada que dice `Fabric Mods:`, seguida de una lista de los mods que tienes instalados. Esta sección es útil para determinar si pudo haber ocurrido algún conflicto entre los mods que tienes instalados. + +### Entendiendo el Reporte de Crasheo + +Ahora que sabemos de qué se trata cada sección del reporte de crasheo, podemos empezar a analizar y entender el reporte de crasheo y encontrar la causa del crasheo. + +Usando el ejemplo enlazado arriba, podemos analizar el reporte de crasheo y encontrar la causa del crasheo, incluyendo los mods que causaron el crasheo. + +El stack trace en la sección de `---- Minecraft Crash Report ----` es la más importante en este caso, ya que contiene el error principal que causó el crasheo. En este caso, el error es `java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2248.method_9539()" because "net.minecraft.class_2248.field_10540" is null`. + +Con la cantidad de mods mencionados en el stack trace, puede ser difícil encontrar el mod culpable, pero lo primero que se debe hacer es encontrar el mod que causó el crasheo. + + + +<<< @/public/assets/players/crash-report-example.txt{8-9,14-15 log} + +En este caso, el mod que causó el crasheo es `snownee`, ya que es el primer mod mencionado en el stack trace. + +Sin embargo, con la cantidad de mods mencionados, puede significar que hay problemas de compatibiildad entre los mods, y el mod que causó el crasheo puede que no sea el mod culpable. En este caso, es mejor reportar el crasheo al autor del mod, y dejar que investiguen el crasheo. + +## Crasheos de Mixin + +:::info +Los Mixins son una manea de modificar el juego sin tener que modificar el código fuente del juego. Son usados por muchos mods, y son una herramienta muy útil para desarrolladores de mods. +::: + +Cuando un mixin crashea, usualmente mencionará el mixin en el stack trace, y la clase que el mixin está modificando. + +Los métodos en un mixin contendrán `modid$handlerName` en el stack trace, donde `modid` es el ID del mod, y `handlerName` es el nombre del handler en el mixin. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +Puedes usar esta información para encontrar el mod que ocasionó el crasheo, y reportar el crasheo al autor del mod. + +## Que hacer con los Reportes de Crasheo + +Lo mejor que puedes hacer con los reportes de crasheo es subirlos a un sitio para pegar texto, y luego compartir el link con el autor del mod, ya sea en su rastreador de problemas o mediante un canal de comunicación (Discord etc). + +Esto le permitirá al autor investigar el crasheo, potencialmente reproducir el problema, y arreglarlo. + +Algunos sitios comunes para pegar texto de reportes de crasheo son: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/es_es/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/es_es/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..d8a23e3a8 --- /dev/null +++ b/versions/1.21/translated/es_es/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Subir Logs +description: Como subir logs para solucionar problemas. +authors: + - IMB11 +--- + +# Subir Logs + +Durante la solución de problemas, muchas veces es necesario proveer los logs para ayudar a identificar la causa del problema. + +## ¿Porqué debería subir los logs? + +Subir los logs le permite a otros ayudarte a solucionar tus problemas más rápido comparado a simplemente pegar los logs en un chat o en una publicación de foro. También te permite compartir tus logs con otros sin tener que copiar y pegarlos. + +Algunos sitios para pegar texto también remarcan la sintaxis del log, lo cual los hace más facil de leer, y pueden censurar información sensible, como tu nombre de usuario, o información de sistema. + +## Reportes de Crasheos + +Los reportes de crasheo son generados automáticamente cuando tu juego crashea. Solo contienen información sobre el crasheo, más no los logs enteros del juego. Están en el folder de `crash-reports` en el folder del juego. + +Para más información sobre los reportes de crasheo, visita [Reportes de Crasheo](./crash-reports). + +## Encontrar los Logs + +Esta guía cubre el launcher oficial de Minecraft (comúnmente referido como el "launcher vanilla") - para launchers de terceros, puedes consultar su documentación. + +El folder del juego puede ser encontrado en los siguientes lugares dependiendo de tu sistema operativo: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +El log más recient se llama `latest.log`, mientras que logs anteriores utilizan un patrón de nombramiento como este: `aaaa-mm-dd_numero.log.gz`. + +## Subir Logs + +Los logs pueden ser subidos en una variedad de servicios, como: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/es_es/players/updating-fabric.md b/versions/1.21/translated/es_es/players/updating-fabric.md new file mode 100644 index 000000000..2c2dc4afe --- /dev/null +++ b/versions/1.21/translated/es_es/players/updating-fabric.md @@ -0,0 +1,41 @@ +--- +title: Actualizar Fabric +description: Una guía paso a paso sobre como actualizar Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Actualizar Fabric + +Esta guía te enseñará como actualizar Fabric desde el Launcher de Minecraft. + +Para launchers o lanzadores de terceros, consulta su documentación. + +El proceso de actualizar Fabric es muy similar al proceso de la instalación de Fabric, por lo que parte de esta guía será la misma que la guía sobre como [Instalar Fabric](./installing-fabric). + +## ¿Porque debería actualizar mi lanzador Fabric? + +Mods más recientes pueden requerir una versión del Lanzador de Fabric más reciente, así que es importante que lo mantengas actualizado para que puedas usar los mods mas recientes. + + + + + +Para actualizar Fabric, simplemente asegurate que la versión del juego y la versión del lanzador de Fabric sean las correctas, y haz click en `Instalar`. + +**Asegurate de no seleccionar la opción de 'Crear Perfil' al correr el instalador, de otro modo creará un nuevo perfil, cosa que no necesitamos en este caso.** + +## 3. Abre el Perfil en el Launcher de Minecraft + +Una vez que la instalación haya terminado, puedes abrir el Launcher de Minecraft e ir a la pestaña de `Instalaciones`. Debes ir a tu perfil de Fabric y abrir la pantalla de edición. + +Reemplaza la versión con la nueva versión del lanzador de Fabric que acabas de instalar, y presiona `Guardar`. + +![Actualizando la versión de Fabric en el Launcher de Minecraft](/assets/players/updating-fabric.png) + +## 4. ¡Hemos terminado! + +¡Una vez completado los pasos, puedes regresar a la pestaña de `Jugar`, seleccionar el perfil de Fabric desde el menú deslizador en la esquina inferior izquierda y presionar Jugar! + +Si encuentras problemas tratando de seguir esta guía, puedes solicitar ayuda en el servidor de [Discord de Fabric](https://discord.gg/v6v4pMv), en el canal de `#player-support`. diff --git a/versions/1.21/translated/es_es/sidebar_translations.json b/versions/1.21/translated/es_es/sidebar_translations.json new file mode 100644 index 000000000..43db1282b --- /dev/null +++ b/versions/1.21/translated/es_es/sidebar_translations.json @@ -0,0 +1,46 @@ +{ + "players.title": "Guías para Jugadores", + "players.faq": "Preguntas Frecuentes", + "players.installingJava": "Instalar Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Instalando Fabric", + "players.findingMods": "Encontrar Mods Seguros", + "players.installingMods": "Instalar Mods", + "players.troubleshooting": "Solucionar Problemas", + "players.troubleshooting.uploadingLogs": "Subiendo tus Logs", + "players.troubleshooting.crashReports": "Reportes de Crasheos", + "players.updatingFabric": "Actualizando Fabric", + "develop.title": "Guías para Desarrolladores", + "develop.gettingStarted": "Primeros Pasos", + "develop.gettingStarted.introduction": "Introducción a Fabric y el desarrollo de Mods", + "develop.gettingStarted.devEnvSetup": "Configurando tu entorno de desarrollo", + "develop.gettingStarted.creatingProject": "Creando un Proyecto", + "develop.gettingStarted.projectStructure": "Estructura de Proyecto", + "develop.gettingStarted.launchGame": "Corriendo tu Juego", + "develop.items": "Items", + "develop.items.potions": "Pociones", + "develop.entities": "Entidades", + "develop.entities.effects": "Efectos de Estado", + "develop.entities.damage-types": "Tipos de Daño", + "develop.commands": "Comandos", + "develop.commands.basics": "Creando Comandos", + "develop.commands.arguments": "Argumentos", + "develop.commands.suggestions": "Sugerencias", + "develop.rendering": "Renderizado", + "develop.rendering.basicConcepts": "Conceptos Básicos sobre Renderización", + "develop.rendering.drawContext": "Usando el Drawing Context (Contexto de Dibujo)", + "develop.rendering.hud": "Renderizando en el Hud", + "develop.rendering.gui": "Interfaces Gráficas y Menús", + "develop.rendering.gui.customScreens": "Menús Personalizados", + "develop.rendering.gui.customWidgets": "Widgets Personalizados", + "develop.rendering.particles": "Partículas", + "develop.rendering.particles.creatingParticles": "Creando Partículas Personalizadas", + "develop.misc": "Páginas Misceláneas", + "develop.misc.codecs": "Codecs", + "develop.misc.events": "Eventos", + "develop.sounds": "Sonidos", + "develop.sounds.using-sounds": "Reproducir SoundEvents (Eventos de Sonido)", + "develop.sounds.custom": "Crear Sonidos Personalizados" +} \ No newline at end of file diff --git a/versions/1.21/translated/fr_fr/contributing.md b/versions/1.21/translated/fr_fr/contributing.md new file mode 100644 index 000000000..490a647e1 --- /dev/null +++ b/versions/1.21/translated/fr_fr/contributing.md @@ -0,0 +1,253 @@ +--- +title: Lignes directrices pour les contributions +description: Lignes directrices pour les contributions à la documentation de Fabric. +--- + +# Lignes directrices pour les contributions {#contributing} + +Ce site utilise [VitePress](https://vitepress.dev/) pour générer du HTML statique à partir de divers fichiers Markdown. Vous devriez vous familiariser avec les extensions Markdown que VitePress supporte [ici](https://vitepress.dev/guide/markdown#features). + +Il y a trois façons de contribuer à ce site web : + +- [Traduire la documentation](#translating-documentation) +- [Contribuer au contenu](#contributing-content) +- [Contribuer au framework](#contributing-framework) + +Toutes les contributions doivent suivre nos [lignes directrices de style](#style-guidelines). + +## Traduire la documentation {#translating-documentation} + +Si vous souhaitez traduire la documentation dans votre langue, vous pouvez le faire sur la [page Crowdin de Fabric](https://crowdin.com/project/fabricmc). + + + +## new-content Contribuer au contenu {#contributing-content} + +Les contributions de contenu sont le principal moyen de contribuer à la documentation de Fabric. + +Toutes les contributions de contenu passent par les étapes suivantes, chacune étant associée à une étiquette : + +1. locally Préparez vos modifications et soumettez une PR +2. stage:expansion: Guide pour l'expansion si nécessaire +3. stage:verification: Vérification du contenu +4. stage:cleanup: Grammaire, Linting... +5. stage:ready: Prêt à être fusionné ! + +Tout le contenu doit suivre nos [lignes directrices de style](#style-guidelines). + +### 1. Préparez vos modifications {#1-prepare-your-changes} + +Ce site est open-source et est développé dans un dépôt GitHub, ce qui signifie que nous nous appuyons sur le flux GitHub : + +1. [Forkez le dépôt Github](https://github.com/FabricMC/fabric-docs/fork) +2. Créez une nouvelle branche sur votre fork +3. Effectuez vos modifications sur cette branche +4. Ouvrez une Pull Request vers le dépôt original + +Vous pouvez en savoir plus sur le flux GitHub [ici](https://docs.github.com/en/get-started/using-github/github-flow). + +Vous pouvez soit apporter des modifications depuis l'interface web de GitHub, soit développer et prévisualiser le site localement. + +#### Cloner votre fork {#clone-your-fork} + +Si vous souhaitez développer localement, vous devrez installer [Git](https://git-scm.com/). + +Ensuite, clonez votre fork du dépôt avec : + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### Installer les dépendances {#install-dependencies} + +Si vous souhaitez prévisualiser vos modifications localement, vous devrez installer [Node.js 18+](https://nodejs.org/en/). + +Ensuite, assurez-vous d'installer toutes les dépendances avec : + +```sh +npm install +``` + +#### Exécuter le serveur de développement {#run-the-development-server} + +Cela vous permettra de prévisualiser vos modifications localement à l'adresse `localhost:5173` et rechargera automatiquement la page lorsque vous apporterez des modifications. + +```sh +npm run dev +``` + +Vous pouvez maintenant ouvrir et parcourir le site web depuis le navigateur en visitant `http://localhost:5173`. + +#### Construire le site web {#building-the-website} + +Cela va compiler tous les fichiers Markdown en fichiers HTML statiques et les placer dans `.vitepress/dist` : + +```sh +npm run build +``` + +#### Prévisualiser le site web construit {#previewing-the-built-website} + +Cela va démarrer un serveur local sur le port 4173 servant le contenu trouvé dans `.vitepress/dist` : + +```sh +npm run preview +``` + +#### Ouvrir une Pull Request {#opening-a-pull-request} + +Une fois que vous êtes satisfait de vos modifications, vous pouvez `push` vos modifications : + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +Ensuite, suivez le lien dans la sortie de `git push` pour ouvrir une PR. + +### 2. stage:expansion Guide pour l'expansion si nécessaire {#2-guidance-for-expansion-if-needed} + +Si l'équipe de documentation pense que vous pourriez développer votre pull request, un membre de l'équipe ajoutera l'étiquette stage:expansion à votre pull request avec un commentaire expliquant ce qu'ils pensent que vous pourriez développer. Si vous êtes d'accord avec la suggestion, vous pouvez développer votre pull request. + +Si vous ne souhaitez pas développer votre pull request, mais que vous êtes d'accord pour que quelqu'un d'autre le fasse ultérieurement, vous devriez créer une issue sur la page des [Issues](https://github.com/FabricMC/fabric-docs/issues) et expliquer ce que vous pensez pouvoir être développé. L'équipe de documentation ajoutera alors l'étiquette help-wanted à votre PR. + +### 3. stage:verification Vérification du contenu {#3-content-verification} + +C'est l'étape la plus importante car elle garantit que le contenu est exact et suit le guide de style de la documentation Fabric. + +À cette étape, les questions suivantes doivent être répondues : + +- Tout le contenu est-il correct ? +- Tout le contenu est-il à jour ? +- Le contenu couvre-t-il tous les cas, comme les différents systèmes d'exploitation ? + +### 4. stage:cleanup Nettoyage {#4-cleanup} + +À cette étape, les actions suivantes sont effectuées : + +- Correction des problèmes de grammaire à l'aide de [LanguageTool](https://languagetool.org/) +- Vérification de tous les fichiers Markdown à l'aide de [`markdownlint`](https://github.com/DavidAnson/markdownlint) +- Formatage de tout le code Java à l'aide de [Checkstyle](https://checkstyle.sourceforge.io/) +- Autres corrections ou améliorations diverses + +## framework Contribuer au Framework {#contributing-framework} + +Le framework fait référence à la structure interne du site web. Toute pull request modifiant le framework du site web sera étiquetée avec l'étiquette framework. + +Vous devriez vraiment ne faire des pull requests de framework qu'après avoir consulté l'équipe de documentation sur le [Discord de Fabric](https://discord.gg/v6v4pMv) ou via une issue. + +:::info +La modification des fichiers de la barre latérale et de la configuration de la barre de navigation ne compte pas comme une pull request de framework. +::: + +## Lignes directrices de style {#style-guidelines} + +Si vous avez des doutes sur quoi que ce soit, vous pouvez poser vos questions sur le [Discord de Fabric](https://discord.gg/v6v4pMv) ou via les Discussions GitHub. + +### Écrire l'original en anglais américain {#write-the-original-in-american-english} + +Toute la documentation originale est rédigée en anglais, en suivant les règles de grammaire américaines. + +### Ajouter des données au Frontmatter {#add-data-to-the-frontmatter} + +Chaque page doit avoir un `title` et une `description` dans le frontmatter. + +N'oubliez pas d'ajouter également votre nom d'utilisateur GitHub à `authors` dans le frontmatter du fichier Markdown ! De cette manière, nous pouvons vous attribuer le mérite qui vous revient. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### Ajouter des ancres aux titres {#add-anchors-to-headings} + +Chaque titre doit avoir une ancre, qui est utilisée pour créer un lien vers ce titre : + +```md +# This Is a Heading {#this-is-a-heading} +``` + +L'ancre doit utiliser des caractères en minuscules, des chiffres et des tirets. + +### Placer le code dans le mod `/reference` {#place-code-within-the-reference-mod} + +Si vous créez ou modifiez des pages contenant du code, placez le code à un emplacement approprié dans le mod de référence (situé dans le dossier `/reference` du dépôt). Ensuite, utilisez la [fonctionnalité d'extrait de code offerte par VitePress](https://vitepress.dev/guide/markdown#import-code-snippets) pour intégrer le code. + +Par exemple, pour mettre en évidence les lignes 15-21 du fichier `FabricDocsReference.java` du mod de référence : + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +Si vous avez besoin d'un contrôle plus étendu, vous pouvez utiliser la [fonctionnalité de transclusion de `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + +Par exemple, ceci intégrera les sections du fichier ci-dessus qui sont marquées avec l'étiquette `#entrypoint` : + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### Créer une barre latérale pour chaque nouvelle section {#create-a-sidebar-for-each-new-section} + +Si vous créez une nouvelle section, vous devez créer une nouvelle barre latérale dans le dossier `.vitepress/sidebars` et l'ajouter au fichier `i18n.mts`. + +Si vous avez besoin d'aide, veuillez poser votre question dans le canal #docs du [Discord de Fabric](https://discord.gg/v6v4pMv). + +### Ajouter de nouvelles pages aux barres latérales pertinentes {#add-new-pages-to-the-relevant-sidebars} + +Lors de la création d'une nouvelle page, vous devez l'ajouter à la barre latérale pertinente dans le dossier `.vitepress/sidebars`. + +Encore une fois, si vous avez besoin d'aide, demandez dans le canal `#docs` du Discord de Fabric. + +### Placer les médias dans `/assets` {#place-media-in-assets} + +Toutes les images doivent être placées à un endroit approprié dans le dossier `/public/assets`. + +### Utilisez des liens relatifs ! {#use-relative-links} + +Cela est dû au système de versioning en place, qui traitera les liens pour ajouter la version au préalable. Si vous utilisez des liens absolus, le numéro de version ne sera pas ajouté au lien. + +Vous ne devez pas non plus ajouter l'extension de fichier au lien. + +Par exemple, pour créer un lien vers la page trouvée dans `/players/index.md` depuis la page `/develop/index.md`, vous devriez faire ce qui suit : + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/fr_fr/develop/codecs.md b/versions/1.21/translated/fr_fr/develop/codecs.md new file mode 100644 index 000000000..d4870b43f --- /dev/null +++ b/versions/1.21/translated/fr_fr/develop/codecs.md @@ -0,0 +1,397 @@ +--- +title: Codecs +description: Un guide complet pour comprendre et utiliser le système de codecs de Mojang pour la sérialisation et désérialisation d'objets. +authors: + - enjarai + - Syst3ms +--- + +# Codecs + +Les codecs sont un système de sérialisation facile d'objets Java, et est inclus dans la librairie DataFixerUpper (DFU) de Mojang, qui vient avec Minecraft. Dans la création de mods, ils peuvent être utilisés comme une alternative à GSON et Jankson pour lire des fichiers JSON personnalisés. + +Les codecs sont utilisés en tandem avec une autre API de DFU, `DynamicOps`. Un codec définit la structure d'un objet, et les `DynamicOps` (litt. 'opérations dynamiques') définissent un format de (dé)sérialisation, comme JSON ou NBT. Cela signifie que n'importe quel codec peut être utilisé avec n'importe quelles `DynamicOps`, et vice versa, pour une flexibilité accrue. + +## Utilisation des codecs + +### Sérialisation et désérialisation + +En premier lieu, un codec est utilisé pour sérialiser et désérialiser des objets vers et à partir d'un format donné. + +Puisque quelques classes vanilla définissent déjà des codecs, on peut prendre ceux-là en exemple. Mojang fournit également deux `DynamicOps` par défaut, `JsonOps` et `NbtOps`, qui recouvrent la plupart des utilisations. + +Supposons qu'on veuille sérialiser une `BlockPos` en JSON et inversement. C'est possible en utilisant le codec stocké statiquement en `BlockPos.CODEC` avec les méthodes `Codec#encodeStart` et `Codec#parse`, respectivement. + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// Serialisation de la BlockPos en JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +Quand on manipule un codec, les valeurs renvoyées prennent la forme d'un `DataResult` (litt. 'résultat de données'). C'est un adaptateur qui représente soit un succès, soit un échec. On peut l'utiliser de plusieurs façons : si on veut juste la valeur sérialisée, `DataResult#result` renverra un `Optional` contenant la valeur, alors que `DataResult#resultOrPartial` permet également de fournir une fonction pour prendre en charge d'éventuelles erreurs qui se sont produites. La seconde est particulièrement utile pour les ressources de packs de données, où il est souhaitable de signaler les erreurs sans créer de problèmes autre part. + +Prenons donc notre valeur sérialisée et transformons-la en `BlockPos` : + +```java +// Si on écrivait un vrai mod, il faudrait évidemment prendre en charge les Optionals vides +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Voici notre valeur JSON, qui devrait correspondre à `[1,2,3]`, +// puisque c'est le format que le codec de BlockPos utilise. +LOGGER.info("BlockPos sérialisée : {}", json); + +// Maintenant on désérialise le JsonElement en BlockPos +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// Encore une fois, on extrait directement notre valeur du résultat +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Et on peut voir qu'on a sérialisé et désérialisé notre BlockPos avec succès ! +LOGGER.info("BlockPos désérialisée : {}", pos); +``` + +### Codecs intégrés + +Comme mentionné ci-dessus, Mojang a déjà défini des codecs pour plusieurs classes vanilla et Java standard, y compris, sans s'y limiter, `BlockPos`, `BlockState`, `ItemStack`, `Identifier`, `Text` et les `Pattern`s regex. Les codecs pour les classes de Mojang sont souvent des champs statiques nommés `CODEC` dans la classe-même, les autres se situant plutôt dans la classe `Codecs`. Par exemple, on peut utiliser `Registries.BLOCK.getCodec()` pour obtenir un `Codec` qui sérialise l'identifiant du bloc et inversement. + +L'API des codecs contient déjà des codecs pour des types primitifs, comme `Codec.INT` et `Codec.STRING`. Ceux-ci sont disponibles statiquement dans la classe `Codec`, et servent souvent de briques pour des codecs plus avancés, comme expliqué ci-dessous. + +## Construction de codecs + +Maintenant qu'on sait utiliser les codecs, regardons comment construire le nôtre. Supposons qu'on ait la classe suivante, et qu'on veuille en désérialiser des instances à partir de fichiers JSON : + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +Le fichier JSON correspondant pourrait ressembler à : + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +On peut créer un codec pour cette classe par assemblage de codecs plus simples. Dans ce cas-ci, il en faut un pour chaque champ : + +- un `Codec` +- un `Codec` +- un `Codec>` + +Le premier est un des codecs primitifs de la classe `Codec` mentionnés plus haut, plus précisément `Codec.INT`. Le deuxième s'obtient à partir du registre `Registries.ITEM` et sa méthode `getCodec()` qui renvoie un `Codec`. Il n'y a pas de codec par défaut pour `List`, mais on peut en créer un à partir de `BlockPos.CODEC`. + +### Listes + +`Codec#listOf` crée une version liste de n'importe quel codec : + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +À noter que les codecs créés ainsi se désérialisent toujours en `ImmutableList`. Si une liste mutable est nécessaire, on pourrait faire appel à [xmap](#mutually-convertible-types-and-you) pour effectuer la conversion. + +### Fusion de codecs pour les classes similaires à des records + +Avec les codecs pour chaque champ à notre disposition, on peut les combiner en un codec pour la classe avec un `RecordCodecBuilder`. On présuppose ici que la classe a un constructeur avec tous les champs qu'on veut sérialiser, et que ces champs ont des getters associés. C'est idéal pour des classes de type record, mais fonctionne également pour des classes normales. + +Voyons voir comment créer un codec pour notre `CoolBeansClass` : + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // Jusqu'à 16 champs peuvent être déclarés ici +).apply(instance, CoolBeansClass::new)); +``` + +Chaque argument à la méthode `group` spécifie un codec, un nom de champ, et une méthode getter. L'appel à `Codec#fieldOf` convertit le codec en [codec map](#mapcodec) et celui à `forGetter` indique la méthode getter utilisée pour obtenir la valeur du champ à partir d'une instance de la classe. Enfin, `apply` spécifie le constructeur utilisé pour créer de nouvelles instances. Attention, l'ordre des champs dans la méthode `group` doit être le même que celui des arguments dans le constructeur. + +On peut également utiliser `Codec#optionalFieldOf` dans ce contexte pour rendre un champ facultatif, comme expliqué dans la section [Champs facultatifs](#optional-fields). + +### MapCodec, et non pas Codec<Map> {#mapcodec} + +`Codec#fieldOf` transforme un `Codec` en `MapCodec` qui est une variante de `Codec`, sans en être une implémentation directe. Comme leur nom peut le suggérer, les codecs map sérialisent leurs valeurs dans en maps clés-valeurs, ou plutôt leur équivalent dans les `DynamicOps` utilisées. Certaines fonctions peuvent en nécessiter un au lieu d'un codec normal. + +Essentiellement, cette manière de créer un codec map encapsule simplement la valeur du codec initial dans une map, avec le nom de champ donné pour clé. Par exemple, un `Codec` sérialiserait en JSON ainsi : + +```json +[1, 2, 3] +``` + +Mais quand transformé en `MapCodec` via `BlockPos.CODEC.fieldOf("pos")`, donnerait ceci : + +```json +{ + "pos": [1, 2, 3] +} +``` + +Les codecs map servent principalement à être assemblés afin de construire un codec pour une classe avec plusieurs champs, comme expliqué dans la section [Fusion de codecs pour les classes similaires à des records](#merging-codecs-for-record-like-classes) ci-dessus. + +#### Champs facultatifs + +`Codec#optionalFieldOf` permet de créer un codec map facultatif. Si le champ en question n'est pas présent pendant la désérialisation, celui-ci va le déséraliser soit en `Optional` vide, soit une valeur par défaut donnée. + +```java +// Sans valeur par défaut +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// Avec valeur par défaut +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +Attention, les champs facultatifs vont ignorer silencieusement toute erreur lors de la désérialisation. Si le champ est présent mais la valeur invalide, il sera toujours désérialisé en la valeur par défaut. + +**Depuis la 1.20.2**, Minecraft (et non pas DFU!) fournit cependant `Codecs#createStrictOptionalFieldCodec`, qui échoue à désérialiser si la valeur du champ est invalide. + +### Constantes, contraintes et composition + +#### Unit + +`Codec.unit` sert à créer un codec qui désérialise toujours en une valeur constante, indépendamment de l'entrée. Lors de la sérialisation, ce codec ne fera rien. + +```java +Codec leSensDuCodec = Codec.unit(42); +``` + +#### Intervalles numériques + +`Codec.intRange` et ses acolytes `Codec.floatRange` et `Codec.doubleRange` servent à créer un codec qui accepte seulement des valeurs numériques dans un intervalle donné, **bornes incluses**. Cela vaut et pour la sérialisation, et pour la désérialisation. + +```java +// Ne peut excéder 2 +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Pair + +`Codec.pair` fusionne deux codecs `Codec
` et `Codec` en un `Codec>`. Il faut garder à l'esprit que cela ne marche correctement qu'avec des codecs qui sérialisent un champ précis, comme [des codec maps convertis](#mapcodec) ou [des codecs records](#merging-codecs-for-record-like-classes). +Le codec résultant sérialisera en une map qui combine les champs des deux codecs utilisés. + +Par exemple, l'exécution de ce code : + +```java +// Création de deux codecs encapsulés distincts +Codec firstCodec = Codec.INT.fieldOf("un_nombre").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("cette_phrase_est_fausse").codec(); + +// Fusion en un codec paire +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// Utilisation pour sérialiser des données +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +Donnera ce JSON en sortie : + +```json +{ + "un_nombre": 23, + "cette_phrase_est_fausse": true +} +``` + +#### Either + +`Codec.either` fusionne deux codecs `Codec` et `Codec` en un `Codec>`. Pendant la désérialisation, le codec résultat essaiera d'utiliser le premier codec, et _seulement si cela échoue_, essaiera d'utiliser le second. +Si le second échoue à son tour, l'erreur du _second_ codec sera renvoyée. + +#### Maps + +Pour gérer des `Map`s avec des clés arbitraires commes des `HashMap`s, `Codec.unboundedMap` peut être utilisé. Celle-ci renvoie un `Codec>`, étant donnés un `Codec` et un `Codec`. Le codec résultant sérialisera en un objet JSON ou équivalent relativement aux `DynamicOps` utilisées. + +À cause de limitations du JSON et du NBT, le codec associé à la clé _doit_ sérialiser en texte. Cela comprend des codecs pour des types qui ne sont pas des textes, mais qui sérialisent ainsi, comme `Identifier.CODEC`. Voir l'exemple suivant : + +```java +// Création d'un codec pour une Map d'identifiants à entiers +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// Utilisation pour sérialiser des données +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "nombre"), 23, + new Identifier("example", "le_nombre_plus_cool"), 42 +)); +``` + +Cela donnera ce JSON en sortie : + +```json +{ + "example:nombre": 23, + "example:le_nombre_plus_cool": 42 +} +``` + +Remarquons que ça marche parce que `Identifier.CODEC` sérialise directement en un texte. On peut arriver au même résultat pour des objets qui ne se sérialisent pas en texte grâce à [xmap et compagnie](#mutually-convertible-types-and-you) pour faire la conversion. + +### Les joies des types interconvertibles + +#### xmap + +Supposons qu'on ait deux classes qui peuvent être converties entre elles, mais sans relation parent-enfant. Par exemple, une `BlockPos` et un `Vec3d` vanilla. Si on a un codec pour l'un, `Codec#xmap` permet de créer un codec pour l'autre en donnant une fonction de conversion pour chaque direction. + +`BlockPos` possède déjà un codec, mais imaginons que non. On peut en créer un à partir du codec de `Vec3d` comme ceci : + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // Conversion de Vec3d en BlockPos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // Conversion de BlockPos en Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// Si vous convertissez une classe pré-existante (`X` par exemple) +// en une classe à vous (`Y`) ainsi, il peut être pratique +// d'ajouter des méthodes `toX` and `fromX` (statique) à `Y` +// et d'utiliser des références de méthodes dans l'appel à `xmap`. +``` + +#### flatComapMap, comapFlatMap, and flatXMap + +`Codec#flatComapMap`, `Codec#comapFlatMap` et `flatXMap` ressemblent à `xmap`, mais permettent à l'une ou aux deux fonctions de conversions de renvoyer un `DataResult`. C'est utile en pratique car il n'est pas forcément toujours possible de convertir une instance donnée d'un objet. + +Prenons par exemple les `Identifier`s vanilla. Utiliser `xmap` dans ce cas nécessiterait des exceptions inélégantes si la conversion échouait. +Par conséquent, son codec intégré est en réalité un `comapFlatMap` sur `Codec.STRING`, ce qui illustre bien son utilisation : + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Not a valid resource location: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +Ces méthodes sont très utiles, mais leurs noms sont assez cryptiques, voici donc un tableau pour aider à se souvenir laquelle utiliser : + +| Méthode | A -> B toujours valide ? | B -> A toujours valide ? | +| ----------------------- | ------------------------ | ------------------------ | +| `Codec#xmap` | Oui | Oui | +| `Codec#comapFlatMap` | Non | Oui | +| `Codec#flatComapMap` | Oui | Non | +| `Codec#flatXMap` | Non | Non | + +### Répartition par registre + +Si on définit un registre de codecs, `Codec#dispatch` permet d'utiliser l'un des codecs selon la valeur d'un champ dans les données sérialisées. C'est utile lorsque les objets à désérialiser ont une structure différente selon leur type, mais représentent une même chose. + +Par exemple, imaginons une interface abstraite `Bean` avec deux classes qui l'implémentent : `StringyBean` et `CountingBean`. Pour les sérialiser via une répartition par registre, plusieurs choses sont nécessaires : + +- Des codecs distincts pour chaque type de `Bean`. +- Une classe/record `BeanType` qui représente le type de blob, et peut fournir le codec associé. +- Une méthode de `Bean` qui renvoie son `BeanType`. +- Une map ou un registre pour associer des `Identifier`s à des `BeanType`s. +- Un `Codec>` à partir de ce registre. En utilisant un `net.minecraft.registry.Registry`, cela s'obtient facilement avec `Registry#getCodec`. + +Une fois tout ceci fait, on peut créer un codec de répartition par registre pour les beans : + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// On peut créer un codec pour les types de bean +// grâce au registre précédemment créé +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// Et à partir de ça, un codec de répartition par registre pour beans ! +// Le premier argument est le nom du champ correspondant au type. +// Si omis, il sera égal à "type". +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::getCodec); +``` + +Notre nouveau codec sérialisera les beans en JSON ainsi, en n'utilisant que les champs en rapport avec leur type spécifique : + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "Ce bean est textuel !" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### Codecs récursifs + +Il est parfois utile d'avoir un codec qui s'utilise _soi-même_ pour décoder certains champs, par exemple avec certaines structures de données récursives. Le code vanilla en fait usage pour les objets `Text`, qui peuvent stocker d'autres `Text`s en tant qu'enfants. Un tel codec peut être construit grâce à `Codec#recursive`. + +À titre d'exemple, essayons de sérialiser une liste simplement chaînée. Cette manière de représenter une liste consiste en des nœuds qui contiennent et une valeur, et une référence au prochain nœud de la liste. La liste est alors représentée par son premier nœud, et pour la parcourir, il suffit de continuer à regarder le nœud suivant juste qu'à ce qu'il n'en existe plus. Voici une implémentation simple de nœuds qui stockent des entiers. + +```java +public record ListNode(int value, ListNode next) {} +``` + +Il est impossible de construire un codec comme d'habitude, puisque quel codec utiliserait-on pour le champ `next` ? Il faudrait un `Codec`, ce qui est précisément ce qu'on veut obtenir ! `Codec#recursive` permet de le faire au moyen d'un lambda magique en apparence : + +```java +Codec codec = Codec.recursive( + "ListNode", // un nom pour le codec + selfCodec -> { + // Ici, `selfCodec` représente le `Codec`, comme s'il était déjà construit + // Ce lambda doit renvoyer le codec qu'on aurait voulu utiliser depuis le départ, + // qui se réfère à lui-même via `selfCodec` + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // le champ `next` sera récursivement traité grâce à l'auto-codec + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +Un `ListNode` sérialisé pourrait alors ressembler à ceci : + +```json +{ + "value": 2, + "next": { + "value": 3, + "next" : { + "value": 5 + } + } +} +``` + +## Références + +- Il y a une documentation bien plus exhaustive des codecs et des APIs attenantes dans la [JavaDoc DFU non-officielle](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec). +- La structure globale de ce guide s'inspire beaucoup de [la page du Forge Community Wiki sur les codecs](https://forge.gemwire.uk/wiki/Codecs), qui propose une approche du même sujet plus centrée autour de Forge. diff --git a/versions/1.21/translated/fr_fr/develop/commands/arguments.md b/versions/1.21/translated/fr_fr/develop/commands/arguments.md new file mode 100644 index 000000000..772a3640d --- /dev/null +++ b/versions/1.21/translated/fr_fr/develop/commands/arguments.md @@ -0,0 +1,56 @@ +--- +title: Paramètres de Commandes +description: Apprenez comment créer des commandes avec des paramètres complexes. +--- + +# Paramètres de commandes {#command-arguments} + +La notion de paramètres (`Argument`) est utilisée dans la plupart des commandes. Des fois, ces paramètres peuvent être optionnels, ce qui veut dire que si vous ne donnez pas ce paramètre, la commande va quand même s'exécuter. Un nœud peut avoir plusieurs types de paramètres, mais n'oubliez pas qu'il y a une possibilité d'ambiguïté, qui devrait toujours être évitée. + +@[code lang=java highlight={3} transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Dans ce cas d'exemple, après la commande textuelle `/argtater`, vous devez donner un nombre. Par exemple, si vous exécutez `/argtater 3`, vous allez avoir en retour le message `Called /argtater with value = 3`. Si vous tapez `/argater` sans arguments, la commande ne pourra pas être correctement analysée. + +Nous ajoutons ensuite un second paramètre optionnel : + +@[code lang=java highlight={3,13} transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Maintenant, vous pouvez donner un ou deux arguments de type nombre à la commande. Si vous donnez un seul nombre, vous allez avoir en retour un texte avec une seule valeur d'affichée. Si vous donnez deux nombres, vous allez avoir en retour un texte avec deux valeurs d'affichées. + +Vous pouvez penser qu'il n'est pas nécessaire de spécifier plusieurs fois des exécutions similaires. Donc, nous allons créer une méthode qui va être utilisée pour les deux cas d'exécution. + +@[code lang=java highlight={3,5,6,7} transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Types de paramètre personnalisé {#custom-argument-types} + +Si le type de paramètre de commande dont vous avez besoin n'existe pas en vanilla, vous pouvez toujours le créer par vous-même. Pour le faire, vous avez besoin de créer une nouvelle classe qui hérite l'interface `ArgumentType` où `T` est le type du paramètre. + +Vous devrez implémenter la méthode `parse`, qui va donc analyser la saisie de chaine de caractères afin de la transformer en le type désiré. + +Par exemple, vous pouvez créer un type de paramètre qui transforme une chaine de caractères en `BlockPos` avec le format suivant : `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Enregistrer des types de paramètres personnalisés {#registering-custom-argument-types} + +:::warning +Vous devez enregistrer votre paramètre de commande personnalisée à la fois sur le serveur et sur le client, sinon dans le cas contraire cette commande ne fonctionnera pas ! +::: + +Vous pouvez enregistrer votre paramètre de commande personnalisé dans la méthode `onInitialize` de l'initialiseur de votre mod en utilisant la classe `ArgumentTypeRegistry` : + +@[code lang=java transcludeWith=:::11](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Utiliser des types de paramètre personnalisé {#using-custom-argument-types} + +Nous pouvons utiliser notre paramètre de commande personnalisé dans une commande, en passant une instance de ce dernier dans la méthode `.argument` du constructeur de commande. + +@[code lang=java transcludeWith=:::10 highlight={3}](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +En exécutant la commande, on peut vérifier si le paramètre de commande fonctionne ou pas : + +![Argument invalide](/assets/develop/commands/custom-arguments_fail.png) + +![Argument valide](/assets/develop/commands/custom-arguments_valid.png) + +![Résultat de commande](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/fr_fr/index.md b/versions/1.21/translated/fr_fr/index.md new file mode 100644 index 000000000..d9b9137e7 --- /dev/null +++ b/versions/1.21/translated/fr_fr/index.md @@ -0,0 +1,21 @@ +--- +title: Documentation de Fabric +description: La documentation officielle de Fabric, une chaîne d'outils pour modder Minecraft. +layout: home +hero: + name: Documentation de Fabric + tagline: La documentation officielle de Fabric, une chaîne d'outils pour modder Minecraft. +features: + - title: Guides des joueurs + icon: 📚 + details: Êtes-vous un joueur envisageant d'utiliser des mods fonctionnant grâce à Fabric ? Nos guides des joueurs sont là pour vous aider. Ces guides vous aideront à télécharger, installer des mods Fabric et résoudre les problèmes pouvant survenir. + link: /fr_fr/players/ + linkText: En Savoir Plus + - title: Guides développeur + icon: 🛠️ + details: Nos guides développeurs communautaires couvrent tous les sujets, du paramétrage de votre IDE à des sujets avancés tels que le rendu et le réseautage. + link: /fr_fr/develop/ + linkText: Commencer +--- + +Si vous voulez contribuer à la documentation de Fabric, vous pouvez retrouver son code source sur [GitHub](https://github.com/FabricMC/fabric-docs) ainsi que son [guide de contribution](./contributing). diff --git a/versions/1.21/translated/fr_fr/players/faq.md b/versions/1.21/translated/fr_fr/players/faq.md new file mode 100644 index 000000000..007b59328 --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Foire Aux Questions pour les joueurs +description: Foire aux questions pour les joueurs et les administrateurs de serveur liés à Fabric. +--- + +# Questions générales + +Certaines questions sont posées très fréquemment, donc en voici une liste. + +## Quelles versions de Minecraft sont supportées par Fabric ? Foire Aux Questions + +Officiellement, Fabric supporte toutes les versions de Minecraft, les snapshots `18w43b` et ultérieures et les releases `1.14` et ultérieures. + +## Où télécharger des mods Fabric ? {#where-can-i-download-published-fabric-mods} + +:::info +Vous devriez toujours vérifier que vos mods proviennent d'une source fiable. Consultez le guide [Trouver des mods](./finding-mods) pour plus d'informations. +::: + +La majorité des auteurs publient leurs mods sur [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) et [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\\&gameVersionTypeId=4), cependant certains peuvent choisir de les mettre en ligne sur leurs sites personnels, ou sur d'autres plateformes, telle qu'un dépot/une repo GitHub. + +## Où puis-je trouver des packs de mods préexistant pour Fabric ? {#where-can-i-find-premade-fabric-modpacks} + +Vous pouvez trouver des packs de mods conçu pour Fabric sur une variété de plateformes, telles que : + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/fr_fr/players/finding-mods.md b/versions/1.21/translated/fr_fr/players/finding-mods.md new file mode 100644 index 000000000..74e2e34cf --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Trouver des mods fiables +description: Un guide pour trouver des mods Fabric depuis des sources fiables. +authors: + - IMB11 +--- + +# Trouver des mods fiables + +La fiabilité d'une source est subjective, et vous devriez toujours juger de par vous-même lorsque vous téléchargez des mods. Mais voici quelques astuces pour vous aider à trouver des mods fiables. + +## 1. Utiliser une source connue pour être fiable + +La majorité des mods sont publiés sur [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) ou [CurseForge](https://www.curseforge.com/minecraft/search?page=1\&pageSize=20\&sortType=1\&class=mc-mods\&gameFlavorsIds=4). + +Ces sites vérifient que les mods sont bel et bien ce qu'ils prétendent être, et qu'ils ne contiennent pas de code malicieux. Vous pouvez également signaler les mods malicieux sur ces sites, et ces derniers prennent les choses en main relativement rapidement. + +## 2. Voyez avec d'autres personnes ! {#with-others} + +Si vous téléchargez un mod d'une source qui n'est pas réputée pour être fiable, vous devriez voir avec d'autres personnes si elles ont déjà téléchargé le mod depuis la même source, et si elles ont eu des problèmes avec. + +Dans le doute, vous pouvez demander de l'aide sur le [serveur Discord Fabric](https://discord.gg/v6v4pMv) (en anglais) dans le channel `#player-support`. + +## 3. Évitez les sites de malware ! {#avoid-malware} + +:::info +Les sites de malware ne sont pas une évidence pour tout le monde. Si vous n'êtes pas sûr, vous devriez demander l'opinion d'autres personnes ou éviter le site entièrement et uniquement utiliser des sites de confiance, comme Modrinth et CurseForge. +::: + +Il y a plein de sites qui prétendent héberger des mods Minecraft, mais qui ne sont en réalité que des sites de malware. Vous devriez les éviter à tout prix. + +Vous pouvez utiliser des logiciels et sites antivirus comme [Windows Defender](https://www.microsoft.com/en-us/windows/windows-defender) ou [VirusTotal](https://www.virustotal.com/) pour vérifier les mods que vous avez téléchargé. Mais cependant, ne vous fiez pas uniquement à ces méthodes, car elles peuvent parfois être incorrectes. + +Pour rappel, si vous avez un doute, vous êtes le/la bienvenu(e) sur le [serveur Discord Fabric](https://discord.gg/v6v4pMv) pour demander de l'aide dans le channel `#player-support`. diff --git a/versions/1.21/translated/fr_fr/players/index.md b/versions/1.21/translated/fr_fr/players/index.md new file mode 100644 index 000000000..08377fba7 --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/index.md @@ -0,0 +1,12 @@ +--- +title: Guides pour les joueur.ses +description: Une collection de guides pour les joueurs et les administrateurs de serveur sur comment installer et utiliser Fabric. +--- + +# Guides pour les joueur.ses + +Cette section de la documentation de Fabric est destinée aux joueurs et administrateurs serveurs qui souhaitent apprendre comment installer, utiliser et résoudre leurs problèmes avec Fabric. + +La barre latérale contient une liste de tous les guides disponibles. + +Si vous rencontrez de quelconques problèmes avec la documentation, demandez de l'aide sur le [Discord de Fabric](https://discord.gg/v6v4pMv) dans les canaux `#player-support` or `#server-admin-support`, ou signalez-les [sur GitHub](https://github.com/FabricMC/fabric-docs). diff --git a/versions/1.21/translated/fr_fr/players/installing-fabric.md b/versions/1.21/translated/fr_fr/players/installing-fabric.md new file mode 100644 index 000000000..8883cdff6 --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/installing-fabric.md @@ -0,0 +1,59 @@ +--- +title: Installer Fabric +description: Un guide pour installer Fabric pas à pas. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Installation de Fabric {#installing-fabric} + + + +Ce guide ne s'applique qu'au launcher Minecraft officiel. Pour les lanceurs tiers, vous devriez consulter leur documentation. + +## 1. Télécharger l'installateur Fabric {#1-download-the-fabric-installer} + +Vous pouvez télécharger l'installateur Fabric depuis le [site de Fabric](https://fabricmc.net/use/). + +Si vous utilisez Windows, téléchargez la version `.exe` (`Download For Windows`) car elle ne requiert pas d'avoir installé Java sur votre système. Elle utilise à la place le Java fourni avec le launcher officiel. + +Pour macOS et Linux, vous devrez télécharger la version `.jar`. Parfois, il vous faudra aussi installer Java avant cette étape. + +## 2. Lancer l'installateur Fabric {#2-run-the-fabric-installer} + +:::warning +Fermez Minecraft et le launcher avant de lancer l'installation. +::: + +:::details Information pour les utilisateurs de MacOS + +Sur macOS, vous devrez peut-être faire un clic droit sur le fichier `.jar` dans votre répertoire de téléchargements et cliquer sur `Ouvrir` pour l'exécuter. + +![Menu de l'installateur Fabric sur MacOS](/assets/players/installing-fabric/macos-downloads.png) + +Lorsqu'on vous demande « Êtes-vous sûr de vouloir l'ouvrir ? », cliquez sur « Ouvrir ». +::: + +Une fois l'installateur ouvert, vous devriez voir un écran comme celui-ci : + +![Installateur Fabric avec "Install" de mis en avant](/assets/players/installing-fabric/installer-screen.png) + + + +Pour installer Fabric, choisissez la version du jeu depuis le menu déroulant et cliquez sur `Installer`. + +:::warning IMPORTANT +Assurez-vous que 'Créer un profil' est coché. +::: + +## 3. Et voilà ! {#3-you-re-done} + +Lorsque l'installeur a terminé, vous pouvez ouvrir le lanceur Minecraft et sélectionner le profil Fabric dans le menu déroulant en bas à gauche. Appuyez ensuite sur Jouer ! + +![Launcher Minecraft avec le profil Fabric sélectionné](/assets/players/installing-fabric/launcher-screen.png) + +Maintenant que vous avez installé Fabric, vous pouvez ajouter des mods à votre jeu ! Consultez le guide [Trouver des mods](./finding-mods) pour plus d'informations. + +Si vous rencontrez des problèmes en suivant ce guide, vous pouvez demander de l'aide dans le [Discord de Fabric](https://discord.gg/v6v4pMv) dans le salon `#player-support`. diff --git a/versions/1.21/translated/fr_fr/players/installing-java/linux.md b/versions/1.21/translated/fr_fr/players/installing-java/linux.md new file mode 100644 index 000000000..2063e45ec --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Installer Java sous Linux +description: Un guide étape par étape sur comment installer Java sous Linux. +authors: + - IMB11 +--- + +# Installer Java sous Linux + +Ce guide vous accompagnera dans l'installation de Java 21 sous Linux. + +## 1. Vérification de si Java est déjà installé {#1-check-if-java-is-already-installed} + +Ouvrez un terminal, entrez `java -version`, et pressez Entrer. + +![Terminal avec "java -version" entré dedans](/assets/players/installing-java/linux-java-version.png) + +:::warning +Pour utiliser Minecraft 1.21, vous avez besoin d'avoir au moins Java 21 d'iinstallé. Si cette commande affiche une version inférieure à 21, vous aurez besoin de mettre à jour votre installation de Java. +::: + +## 2. Téléchargement et installation de Java 21 {#2-downloading-and-installing-java} + +Nous recommandons d'utiliser OpenJDK 21, qui est disponible sur la plupart des distributions Linux. + +### Arch Linux {#arch-linux} + +:::info +Pour plus d'information sur comment installer Java sous Arch Linux, consultez le [Wiki d'Arch Linux (Anglais)](https://wiki.archlinux.org/title/Java). +::: + +Vous pouvez installer le dernier JRE depuis les dépots officiels : + +```sh +sudo pacman -S jre-openjdk +``` + +Si vous faites tourner un serveur sans besoin d'interface graphique, vous pouvez installer la version sans affichage à la place : + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Si vous prévoyez de développer des mods, vous aurez plutôt besoin du JDK : + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu + +Vous pouvez installer Java 21 en utilisant `apt` avec les commandes suivantes : + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora + +Vous pouvez installer Java 21 en utilisant `dnf` avec les commandes suivantes : + +```sh +sudo dnf install java-21-openjdk +``` + +Si vous n'avez pas besoin d'interface graphique, vous pouvez installer la version sans affichage à la place : + +```sh +sudo dnf install java-21-openjdk-headless +``` + +Si vous prévoyez de développer des mods, vous aurez plutôt besoin du JDK : + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Autres distributions Linux + +Si votre distribution n'est pas listée ci-dessus, vous pouvez télécharger le dernier JRE sur [Adoptium](https://adoptium.net/fr/temurin/) + +Il est recommandé de se référer à un guide alternatif pour votre distribution si vous souhaitez développer des mods. + +## 3. Vérifier que Java 21 est bien installé {#3-verify-that-java-is-installed} + +Lorsque l'installation est terminée, vous pouvez vérifier que Java 21 est installé en ouvrant un terminal et en entrant `java -version`. + +Si la commande se termine avec succès, vous verrez quelque chose de similaire à avant, où la version de java est affichée : + +![Terminal avec "java -version" entré dedans](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/fr_fr/players/installing-mods.md b/versions/1.21/translated/fr_fr/players/installing-mods.md new file mode 100644 index 000000000..52e9fc59f --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Installer des mods +description: Un guide pour installer des mods pour Fabric pas à pas. +authors: + - IMB11 +--- + +# Installer des mods + +Ce guide explique en détail le processus d'installation de mods pour Fabric avec le launcher Minecraft officiel. + +Pour les lanceurs tiers, vous devriez consulter leur documentation. + +## 1. Télécharger le mod + +:::warning +Ne téléchargez que des mods provenant de sources dignes de confiance. Pour plus d'informations sur comment trouver des mods, voir le guide [Trouver des mods fiables](./finding-mods). +::: + +La majorité des mods requiert également Fabric API, qui peut être téléchargée depuis [Modrinth](https://modrinth.com/mod/fabric-api) ou [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +Lorsque vous téléchargez des mods, assurez-vous : + +- Qu'ils fonctionnent sur la version de Minecraft à laquelle vous souhaitez jouer. Par exemple, un mod qui fonctionne sur la version 1.20 peut ne pas fonctionner sur la version 1.20.2. +- Qu'ils sont pour Fabric et pas un autre mod loader. +- Et qu'ils sont pour la bonne version de Minecraft (Java Edition). + +## 2. Déplacer le mod dans le dossier `mods` + +Le dossier mods peut être trouvé aux emplacements suivants pour chaque système d'exploitation. + +Vous pouvez généralement coller ces chemins dans la barre d'adresse de votre explorateur de fichiers pour naviguer rapidement jusqu'au dossier. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Une fois le dossier `mods` trouvé, vous pouvez y déplacer les fichiers `.jar` du mod. + +![Mods installés dans le dossier mods](/assets/players/installing-mods.png) + +## 3. Et voilà ! {#3-you-re-done} + +Après avoir déplacé les mods dans le dossier `mods`, vous pouvez ouvrir le launcher Minecraft et sélectionner le profil Fabric depuis le menu déroulant en bas à gauche, puis appuyer sur Jouer. + +![Le lanceur Minecraft avec le profil Fabric sélectionné](/assets/players/installing-fabric/launcher-screen.png) + +## Résolution de problèmes + +Si vous rencontrez des problèmes en suivant ce guide, vous pouvez demander de l'aide dans le [Discord Fabric](https://discord.gg/v6v4pMv) dans le salon `#player-support`. + +Vous pouvez également essayer de dépanner le problème vous-même en utilisant les guides de dépannage : + +- [Rapports de plantage](./troubleshooting/crash-reports) +- [Mettre en ligne des logs](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/fr_fr/players/updating-fabric.md b/versions/1.21/translated/fr_fr/players/updating-fabric.md new file mode 100644 index 000000000..7d7ac1b13 --- /dev/null +++ b/versions/1.21/translated/fr_fr/players/updating-fabric.md @@ -0,0 +1,43 @@ +--- +title: Mettre à jour Fabric +description: Un guide pour mettre à jour Fabric pas à pas. +authors: + - IMB11 + - modmuss50 +--- + +# Mettre à jour Fabric + +Ce guide explique en détail le processus de mise à jour de Fabric pour le launcher Minecraft. + +Pour les lanceurs tiers, vous devriez consulter leur documentation. + +La mise à jour de Fabric ressemble beaucoup à l'installation de Fabric, donc certains passages seront identiques au guide [Installer Fabric](./installing-fabric). + +## Pourquoi mettre à jour Fabric Loader ? Et voilà ! + +De nouveaux mods peuvent nécessiter une version plus récente de Fabric Loader pour fonctionner, il est donc important de le garder à jour pour s'assurer de pouvoir utiliser les mods les plus récents. + + + + + +Pour mettre à jour Fabric, s'assurer que les versions du jeu et de Loader correspondent, puis appuyer sur 'Install' (Installer). + +:::warning IMPORTANT +**Assurez-vous d'avoir décoché 'Créer un profil' en exécutant l'installateur, sinon un nouveau profil sera créé, ce qui est indésirable ici.** +::: + +## 3. Ouvrir le profil dans le launcher Minecraft + +Une fois que l'installateur a terminé, il est désormais possible d'ouvrir le launcher Minecraft et d'aller à l'onglet 'Installations'. Il est recommandé d'aller sur votre profil Fabric et d'ouvrir l'écran d'édition. + +Remplacer la version avec la version de Fabric Loader tout juste installée et appuyer sur 'Sauvegarder'. + +![Mise à jour de la version de Fabric Loader dans le launcher Minecraft](/assets/players/updating-fabric.png) + +## 4. Et voilà ! {#4-you-re-done} + +Une fois que ces étapes ont été faites, retourner à l'onglet 'Jeu', sélectionner le profil Fabric depuis le menu déroulant dans le coin inférieur gauche et appuyer sur 'Jouer' ! + +Si vous rencontrez des problèmes en suivant ce guide, vous pouvez demander de l'aide dans le [Discord de Fabric](https://discord.gg/v6v4pMv) dans le salon `#player-support`. diff --git a/versions/1.21/translated/fr_fr/sidebar_translations.json b/versions/1.21/translated/fr_fr/sidebar_translations.json new file mode 100644 index 000000000..3d0c524ee --- /dev/null +++ b/versions/1.21/translated/fr_fr/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "Guides des joueurs", + "players.faq": "Foire Aux Questions", + "players.installingJava": "Installer Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Installer Fabric", + "players.findingMods": "Où trouver des mods fiables", + "players.installingMods": "Installer des mods", + "players.troubleshooting": "Résolution de problèmes", + "players.troubleshooting.uploadingLogs": "Mettre en ligne ses logs", + "players.troubleshooting.crashReports": "Rapports de plantage", + "players.updatingFabric": "Mettre à jour Fabric", + "develop.title": "Guides développeur", + "develop.gettingStarted": "Bien débuter", + "develop.gettingStarted.introduction": "Introduction à Fabric et au modding", + "develop.gettingStarted.devEnvSetup": "Mettre en place votre environnement de développement", + "develop.gettingStarted.creatingProject": "Créer un projet", + "develop.gettingStarted.projectStructure": "Structure du projet", + "develop.gettingStarted.launchGame": "Démarrer votre jeu", + "develop.gettingStarted.solvingProblems": "Problèmes Usuels", + "develop.items": "Objets Personnalisés", + "develop.items.first-item": "Créer Votre Premier Objet", + "develop.items.food": "Nourritures Personnalisées", + "develop.items.custom-armor": "Armures Personnalisées", + "develop.items.custom-tools": "Outils Personnalisés", + "develop.items.custom-item-groups": "Groupe d'Objets Personnalisés", + "develop.items.custom-item-interactions": "Interactions d'Objets Personnalisées", + "develop.items.potions": "Potions Personnalisées", + "develop.items.custom-data-components": "Composants De Donné Personnalisés", + "develop.blocks": "Blocs", + "develop.blocks.first-block": "Créer votre premier Bloc", + "develop.blocks.blockstates": "États de bloc", + "develop.entities": "Entités Personnalisées", + "develop.entities.effects": "Les effets de statut", + "develop.entities.damage-types": "Types de dégâts", + "develop.commands": "Les commandes", + "develop.commands.basics": "Créer des commandes", + "develop.commands.arguments": "Les arguments", + "develop.commands.suggestions": "Les suggestions", + "develop.rendering": "Rendu", + "develop.rendering.basicConcepts": "Concepts élémentaires de rendu", + "develop.rendering.drawContext": "Utiliser le context de dessin", + "develop.rendering.hud": "Afficher dans le Hud", + "develop.rendering.gui": "Écrans et IHMs", + "develop.rendering.gui.customScreens": "Écrans Personnalisés", + "develop.rendering.gui.customWidgets": "Widgets Personnalisés", + "develop.rendering.particles": "Les particules", + "develop.rendering.particles.creatingParticles": "Créer des particules personnalisées", + "develop.misc": "Pages diverses", + "develop.misc.codecs": "Les codecs", + "develop.misc.events": "Les événements", + "develop.misc.text-and-translations": "Textes et traductions", + "develop.misc.ideTipsAndTricks": "Astuces pour l'IDE", + "develop.misc.automatic-testing": "Tests automatisés", + "develop.sounds": "Sons", + "develop.sounds.using-sounds": "Jouer SoundEvents", + "develop.sounds.custom": "Créer des sons personnalisés" +} diff --git a/versions/1.21/translated/fr_fr/website_translations.json b/versions/1.21/translated/fr_fr/website_translations.json new file mode 100644 index 000000000..b94eaaddc --- /dev/null +++ b/versions/1.21/translated/fr_fr/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "Auteurs de page", + "authors.nogithub": "%s (pas sur GitHub)", + "banner": "La documentation Fabric est en cours de création. Reporté les problèmes sur %s ou %s.", + "description": "Documentation complète pour Fabric, la chaîne d'outils de modding pour Minecraft.", + "download": "Télécharger %s", + "footer.next": "Page suivante", + "footer.prev": "Page précédente", + "github_edit": "Modifier cette page sur GitHub", + "lang_switcher": "Choisir la langue", + "last_updated": "Dernière mise à jour", + "mode_dark": "Basculer en mode sombre", + "mode_light": "Basculer en mode clair", + "mode_switcher": "Apparence", + "nav.contribute": "Contribuer", + "nav.contribute.api": "API Fabric", + "nav.download": "Télécharger", + "nav.home": "Accueil", + "outline": "Sur cette page", + "return_to_top": "Retourner en haut", + "search.back": "Abandonner la recherche", + "search.button": "Rechercher", + "search.display_details": "Afficher la liste détaillée", + "search.footer.close": "fermer", + "search.footer.close.key": "Echap", + "search.footer.down.key": "Flèche bas", + "search.footer.navigate": "naviguer", + "search.footer.up.key": "Flèche haut", + "search.footer.select": "sélectionner", + "search.footer.select.key": "Entrer", + "search.no_results": "Aucun résultat pour", + "search.reset": "Réinitialiser la recherche", + "sidebar_menu": "Menu", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Documentation Fabric", + "version.reminder": "Cette page est écrite pour la version :", + "version.switcher": "Changer de version", + "404.code": "404", + "404.crowdin_link": "Lien vers Crowdin", + "404.crowdin_link.label": "Ouvrir l'éditeur Crowdin", + "404.english_link": "Lire en anglais", + "404.english_link.label": "Ouvrir la version en anglais", + "404.link": "Retour à l'accueil", + "404.link.label": "Aller à la page d'accueil", + "404.quote": "Cette page a essayé de nager dans la lave", + "404.title": "Page non trouvée" +} diff --git a/versions/1.21/translated/it_it/contributing.md b/versions/1.21/translated/it_it/contributing.md new file mode 100644 index 000000000..510a33770 --- /dev/null +++ b/versions/1.21/translated/it_it/contributing.md @@ -0,0 +1,253 @@ +--- +title: Linee Guida per la Contribuzione +description: Linee guida per le contribuzioni alla Documentazione di Fabric. +--- + +# Linee Guida per la Contribuzione {#contributing} + +Questo sito usa [VitePress](https://vitepress.dev/) per generare HTML statico da vari file Markdown. Dovresti familiarizzare con le estensioni per Markdown che VitePress supporta [qui](https://vitepress.dev/guide/markdown#features). + +Ci sono tre modi per contribuire a questo sito: + +- [Tradurre la Documentazione](#translating-documentation) +- [Contribuire con Contenuti](#contributing-content) +- [Contribuire al Framework](#contributing-framework) + +Tutte le contribuzioni devono seguire le nostre [linee guida per lo stile](#style-guidelines). + +## Tradurre la Documentazione {#translating-documentation} + +Se vuoi tradurre la documentazione nella tua lingua, puoi farlo nella [pagina Crowdin di Fabric](https://crowdin.com/project/fabricmc). + + + +## new-content Contribuire con Contenuti {#contributing-content} + +Le contribuzioni con contenuti sono il modo principale per contribuire alla Documentazione di Fabric. + +Tutte le contribuzioni con contenuti passano per le seguenti fasi, ciascuna delle quali è associata ad un'etichetta: + +1. localmente Prepara le tue modifiche e apri una PR +2. stage:expansion Indicazioni per l'espansione se necessaria +3. stage:verification: Verifica dei contenuti +4. stage:cleanup: Grammatica, Linting... +5. stage:ready: Pronta per il merge! + +Tutto il contenuto deve rispettare le nostre [linee guida per lo stile](#style-guidelines). + +### 1. Prepara le Tue Modifiche {#1-prepare-your-changes} + +Il sito è open-source, ed è sviluppato in una repository su GitHub, il che significa che ci affidiamo al flow GitHub: + +1. [Crea una fork della Repository su GitHub](https://github.com/FabricMC/fabric-docs/fork) +2. Crea un nuovo branch sulla tua fork +3. Aggiungi le tue modifiche su quel branch +4. Apri una Pull Request alla repository originale + +Puoi leggere di più riguardo al flow GitHub [qui](https://docs.github.com/en/get-started/using-github/github-flow). + +È possibile fare modifiche dall'interfaccia web su GitHub, oppure puoi sviluppare e ottenere un'anteprima del sito localmente. + +#### Clonare la Tua Fork {#clone-your-fork} + +Se vuoi sviluppare localmente, dovrai installare [Git](https://git-scm.com/). + +Dopo di che, clona la tua fork della repository con: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### Installare le Dipendenze {#install-dependencies} + +Se vuoi ottenere un'anteprima locale delle tue modifiche, dovrai installare [Node.js 18+](https://nodejs.org/en/). + +Dopo di che, assicurati di installare tutte le dipendenze con: + +```sh +npm install +``` + +#### Eseguire il Server di Sviluppo {#run-the-development-server} + +Questo di permetterà di ottenere un'anteprima locale delle tue modifiche presso `localhost:5173` e ricaricherà automaticamente la pagina quando farai modifiche. + +```sh +npm run dev +``` + +Ora puoi aprire e navigare sul sito dal browser visitando `http://localhost:5173`. + +#### Costruire il Sito {#building-the-website} + +Questo compilerà tutti i file Markdown in HTML statico e li posizionerà in `.vitepress/dist`: + +```sh +npm run build +``` + +#### Ottenere un'Anteprima del Sito Costruito {#previewing-the-built-website} + +Questo avvierà un server locale in porta `4173` che servirà il contenuto trovato in `.vitepress/dist`: + +```sh +npm run preview +``` + +#### Aprire una Pull Request {#opening-a-pull-request} + +Quando sarai felice delle tue modifiche, puoi fare `push` delle tue modifiche: + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +Dopo di che segui il link nell'output di `git push` per aprire una PR. + +### 2. stage:expansion Indicazioni per l'Espansione Se Necessaria {#2-guidance-for-expansion-if-needed} + +Se il team della documentazione crede che tu possa espandere la tua pull request, un membro del team aggiungerà l'etichetta stage:expansion alla tua pull request assieme a un commento che spiega cosa credono che tu possa espandere. Se sei d'accordo con il consiglio, puoi espandere la tua pull request. + +Se non vuoi espandere la tua pull request, ma ti va bene che qualcun altro lo faccia successivamente, dovresti creare un'issue sulla [pagina Issues](https://github.com/FabricMC/fabric-docs/issues) e spiegare cosa credi che si possa espandere. Il team di documentazione aggiungerà quindi l'etichetta help-wanted alla tua PR. + +### 3. stage:verification Verifica dei Contenuti {#3-content-verification} + +Questa è la fase più importante poiché assicura che il contenuto sia accurato e segua le linee guida per lo stile della Documentazione di Fabric. + +In questa fase, bisognerebbe rispondere alle seguenti domande: + +- Il contenuto è tutto corretto? +- Il contenuto è tutto aggiornato? +- Il contenuto copre tutti i casi possibili, per esempio i vari sistemi operativi? + +### 4. stage:cleanup: Pulizia {#4-cleanup} + +In questa fase, avviene ciò che segue: + +- Correzione di eventuali errori grammaticali tramite [LanguageTool](https://languagetool.org/) +- Linting di tutti i file Markdown tramite [`markdownlint`](https://github.com/DavidAnson/markdownlint) +- Formattazione di tutto il codice Java tramite [Checkstyle](https://checkstyle.sourceforge.io/) +- Altri cambiamenti o miglioramenti vari + +## framework Contribuire al Framework {#contributing-framework} + +Framework si riferisce alla struttura interna del sito, ogni pull request che modifica il framework del sito dovrebbe essere etichettata con l'etichetta framework. + +Dovresti davvero fare pull request riguardanti il framework solo dopo esserti consultato con il team della documentazione nel [Discord di Fabric](https://discord.gg/v6v4pMv) o tramite un'issue. + +:::info +Modificare i file nella sidebar e la configurazione della barra di navigazione non conta come pull request riguardante il framework. +::: + +## Linee Guida per lo Stile {#style-guidelines} + +Se fossi incerto riguardo a qualsiasi cosa, puoi chiedere nel [Discord di Fabric](https://discord.gg/v6v4pMv) o tramite GitHub Discussions. + +### Scrivi l'Originale in Inglese Americano {#write-the-original-in-american-english} + +Tutta la documentazione originale è scritta in inglese, seguendo le regole grammaticali americane. + +### Aggiungi i Dati al Frontmatter {#add-data-to-the-frontmatter} + +Ogni pagina deve avere un titolo (`title`) e una descrizione (`description`) nel frontmatter. + +Ricordati anche di aggiungere il tuo nome utente GitHub ad `authors` nel frontmatter del file Markdown! In questo modo possiamo darti l'attribuzione che meriti. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### Aggiungi Ancore alle Intestazioni {#add-anchors-to-headings} + +Ogni intestazione deve avere un'ancora, che viene usata per collegarsi a quell'intestazione: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +L'ancora deve usare caratteri minuscoli, numeri e trattini. + +### Posiziona il Codice Nella Mod `/reference` {#place-code-within-the-reference-mod} + +Se crei o modifichi pagine contenenti codice, metti il codice in una posizione appropriata nella mod reference (presente nella cartella `/reference` della repository). Dopo di che, usa la [funzione code snippet fornita da VitePress](https://vitepress.dev/guide/markdown#import-code-snippets) per incorporare il codice. + +Per esempio, per evidenziare le linee 15-21 del file `FabricDocsReference.java` dalla mod reference: + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +Se ti serve un controllo più raffinato, puoi usare la [funzione transclude da `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + +Per esempio, questo incorporerà le sezioni del suddetto file che sono contrassegnate con il tag `#entrypoint`: + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### Crea una Barra Laterale per Ogni Nuova Sezione {#create-a-sidebar-for-each-new-section} + +Se stai creando una nuova sezione, dovresti creare una nuova barra laterale nella cartella `.vitepress/sidebars` ed aggiungerla al file `i18n.ts`. + +Se hai bisogno di assistenza con questo, chiedi per favore nel canale `#docs` del [Discord di Fabric](https://discord.gg/v6v4pMv). + +### Aggiungi Nuove Pagine alle Barre Laterali Appropriate {#add-new-pages-to-the-relevant-sidebars} + +Quando crei una nuova pagina, dovresti aggiungerla alla barra laterale appropriata nella cartella `.vitepress/sidebars`. + +Di nuovo, se hai bisogno di assistenza, chiedi nel canale `#docs` del Discord di Fabric. + +### Posiziona i Contenuti Multimediali in `/assets` {#place-media-in-assets} + +Ogni immagine dovrebbe essere messa in una posizione appropriata nella cartella `/public/assets/`. + +### Usa Link Relativi! {#use-relative-links} + +Questo è dovuto al sistema di gestione delle versioni in uso, che processerà i link per aggiungerci la versione anticipatamente. Se usassi link assoluti, il numero di versione non verrebbe aggiunto al link. + +Devi anche non aggiungere l'estensione del file al link. + +Per esempio, per inserire un link alla pagina `/players/index.md` dalla pagina `/develop/index.md`, dovresti fare il seguente: + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/it_it/develop/automatic-testing.md b/versions/1.21/translated/it_it/develop/automatic-testing.md new file mode 100644 index 000000000..a1068d04e --- /dev/null +++ b/versions/1.21/translated/it_it/develop/automatic-testing.md @@ -0,0 +1,91 @@ +--- +title: Testing Automatizzato +description: Una guida per scrivere test automatici con Fabric Loader JUnit. +authors: + - kevinthegreat1 +--- + +# Testing Automatizzato {#automated-testing} + +Questa pagina spiega come scrivere codice che testi parti della tua mod automaticamente. Ci sono due modi per testare la tua mod automaticamente: unit test con Fabric Loader JUnit o test nel gioco con il framework Gametest di Minecraft. + +Gli unit test dovrebbero essere usato per testare le componenti del tuo codice, come i metodi e le classi ausiliarie, mentre test nel gioco avviano un client e un server Minecraft reali per eseguire i tuoi test, il che li rende appropriati per testare funzionalità e gameplay. + +:::warning +Per ora, questa guida si occupa solo dello unit testing. +::: + +## Unit Testing {#unit-testing} + +Poiché il modding in Minecraft si affida a strumenti di modifica del byte-code da eseguire come i Mixin, aggiungere e usare JUnit normalmente non funzionerebbe. Questo è il motivo per cui Fabric fornisce Fabric Loader JUnit, un plugin JUnit che attiva lo unit testing in Minecraft. + +### Configurare Fabric Loader JUnit {#setting-up-fabric-loader-junit} + +Anzitutto, dobbiamo aggiungere Fabric Loader JUnit all'ambiente di sviluppo. Aggiungi il seguente blocco di dipendenze al tuo `build.gradle`: + +@[code lang=groovy transcludeWith=:::automatic-testing:1](@/reference/build.gradle) + +Poi, dobbiamo informare Gradle su come usare Fabric Loader JUnit per il testing. Puoi fare ciò aggiungendo il codice seguente al tuo `build.gradle`: + +@[code lang=groovy transcludeWith=:::automatic-testing:2](@/reference/1.21/build.gradle) + +### Scrivere Test {#writing-tests} + +Appena ricaricato Gradle, sei pronto a scrivere test. + +Questi test si scrivono proprio come altri test JUnit regolari, con un po' di configurazione aggiuntiva se vuoi accedere a classi che dipendono dalle registry, come `ItemStack`. Se JUnit ti è familiare, puoi saltare a [Impostare le Registry](#setting-up-registries). + +#### Impostare la Tua Prima Classe di Test {#setting-up-your-first-test-class} + +I test si scrivono nella cartella `src/test/java`. + +Una convenzione per i nomi è quella di rispecchiare la struttura del package della classe che stai testando. Per esempio, per testare `src/main/java/com/example/docs/codec/BeanType.java`, dovresti creare la classe `src/test/java/com/example/docs/codec/BeanTypeTest.java`. Nota che abbiamo aggiunto `Test` alla fine del nome della classe. Questo ti permette anche di accedere facilmente a metodi e attributi privati al package. + +Un'altra convenzione è avere un package `test`, quindi `src/test/java/com/example/docs/test/codec/BeanTypeTest.java`. Questo previene alcuni problemi dovuti all'uso dello stesso package se usi i moduli Java. + +Dopo aver creato la classe di test, usa ⌘/CTRLN per aprire il menu Generate. Seleziona Test e comincia a scrivere il nome del tuo metodo, che di solito inizia con `test`. Premi Invio quando hai fatto. Per altri trucchi riguardo all'ambiente di sviluppo, vedi [Trucchi Riguardanti l'IDE](./ide-tips-and-tricks#code-generation). + +![Generare un metodo di test](/assets/develop/misc/automatic-testing/unit_testing_01.png) + +Puoi ovviamente scrivere la firma del metodo manualmente, e qualsiasi istanza del metodo senza parametri e come tipo restituito void sarà identificato come metodo di test. Dovresti alla fine avere il seguente: + +![Un metodo di test vuoto con indicatori di test](/assets/develop/misc/automatic-testing/unit_testing_02.png) + +Nota gli indicatori a freccia verde nel margine: puoi facilmente eseguire un test cliccandoci sopra. In alternativa, i tuoi test si eseguiranno in automatico ad ogni build, incluse le build di CI come GitHub Actions. Se stai usando GitHub Actions, non dimenticare di leggere [Configurare le GitHub Actions](#setting-up-github-actions). + +Ora è il tempo di scrivere il tuo codice di test effettivo. Puoi assicurare condizioni con `org.junit.jupiter.api.Assertions`. Dai un'occhiata ai test seguenti: + +@[code lang=java transcludeWith=:::automatic-testing:4](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +Per una spiegazione di cosa fa questo codice, consulta la pagina [Codec](./codecs#registry-dispatch). + +#### Impostare le Registry {#setting-up-registries} + +Ottimo, il primo test è funzionato! Ma aspetta, il secondo test è fallito? Nei log, otteniamo uno dei seguenti errori. + +@[code lang=java transcludeWith=:::automatic-testing:5](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +Questo è perché stiamo provando ad accedere alla registry o a una classe che dipende su queste (o, in casi rari, dipende su altre classi Minecraft come `SharedConstants`), ma Minecraft non è stato inizializzato. Dobbiamo solo inizializzarlo un po' perché funzionino le registry. Ti basta aggiungere il codice seguente all'inizio del tuo metodo `beforeAll`. + +@[code lang=java transcludeWith=:::automatic-testing:7](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +### Configurare le GitHub Actions {#setting-up-github-actions} + +:::info +Questa sezione suppone che stia usando il workflow GitHub Action standard incluso con la mod di esempio e con la mod modello. +::: + +I tuoi test ora verranno eseguiti ad ogni build, incluse quelle di fornitori CI come GitHub Actions. E se una build fallisce? Dovrai caricare i log come artifact per permetterci di vedere i report del test. + +Aggiungi questo al tuo file `.github/workflows/build.yml`, sotto alla fase `./gradlew build`. + +```yaml +- name: Store reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: reports + path: | + **/build/reports/ + **/build/test-results/ +``` diff --git a/versions/1.21/translated/it_it/develop/blocks/block-entities.md b/versions/1.21/translated/it_it/develop/blocks/block-entities.md new file mode 100644 index 000000000..09c7f4e51 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/blocks/block-entities.md @@ -0,0 +1,112 @@ +--- +title: Blocchi-Entità +description: Impara come creare blocchi-entità per i tuoi blocchi personalizzati. +authors: + - natri0 +--- + +# Blocchi-Entità {#block-entities} + +I blocchi-entità sono un modo per memorizzare dati aggiuntivi per un blocco, che non siano parte dello stato del blocco: contenuti dell'inventario, nome personalizzato e così via. +Minecraft usa i blocchi-entità per blocchi come bauli, fornaci, e blocchi dei comandi. + +Come esempio, creeremo un blocco che conta quante volte esso è stato cliccato con il tasto destro. + +## Creare il Blocco-Entità {#creating-the-block-entity} + +Per fare in modo che Minecraft riconosca e carichi i nuovi blocchi-entità, dobbiamo creare un tipo di blocco-entità. Questo si fa estendendo la classe `BlockEntity` e registrandola in una nuova classe `ModBlockEntities`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +La registrazione di un `BlockEntity` produce un `BlockEntityType` come il `COUNTER_BLOCK_ENTITY` che abbiamo usato sopra: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java) + +:::tip +Nota come il costruttore del `CounterBlockEntity` prenda due parametri, ma il costruttore del `BlockEntity` ne prenda tre: il `BlockEntityType`, la `BlockPos`, e lo `BlockState`. +Se non fissassimo nel codice il `BlockEntityType`, la classe `ModBlockEntities` non compilerebbe! Questo perché la `BlockEntityFactory`, che è un'interfaccia funzionale, descrive una funzione che prende solo due parametri, proprio come il nostro costruttore. +::: + +## Creare il Blocco {#creating-the-block} + +Dopo di che, per usare effettivamente il blocco-entità, ci serve un blocco che implementi `BlockEntityProvider`. Creiamone uno e chiamiamolo `CounterBlock`. + +:::tip +Ci sono due modi per approcciarsi a questo: + +- Creare un blocco che estenda `BlockWithEntity` e implementi il metodo `createBlockEntity` (_e_ il metodo `getRenderType`, poiché `BlockWithEntity` li rende invisibili in maniera predefinita) +- Creare un blocco che implementi `BlockEntityProvider` da solo e faccia override del metodo `createBlockEntity` + +Useremo il primo approccio in questo esempio, poiché `BlockWithEntity` fornisce anche alcune utilità comode. +::: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Usare `BlockWithEntity` come classe genitore significa che dobbiamo anche implementare il metodo `createCodec`, il che è piuttosto semplice. + +A differenza dei blocchi, che sono dei singleton, viene creato un nuovo blocco-entità per ogni istanza del blocco. Questo viene fatto con il metodo `createBlockEntity`, che prende la posizione e il `BlockState`, e restituisce un `BlockEntity`, o `null` se non ce ne dovrebbe essere uno. + +Non dimenticare di registrare il blocco nella classe `ModBlocks`, proprio come nella guida [Creare il Tuo Primo Blocco](../blocks/first-block): + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +## Usare il Blocco-Entità {#using-the-block-entity} + +Ora che abbiamo un blocco-entità, possiamo usarlo per memorizzare il numero di clic con il tasto destro sul blocco. Faremo questo aggiungendo un attributo `clicks` alla classe `CounterBlockEntity`: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Il metodo `markDirty`, usato in `incrementClicks`, informa il gioco che i dati dell'entità sono stati aggiornati; questo sarà utile quando aggiungeremo i metodi per serializzare il contatore e ricaricarlo dal file di salvataggio. + +Il prossimo passaggio è incrementare questo attributo ogni volta che il blocco viene cliccato con il tasto destro. Questo si fa facendo override del metodo `onUse` nella classe `CounterBlock`: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Poiché il `BlockEntity` non viene passato nel metodo, usiamo `world.getBlockEntity(pos)`, e se il `BlockEntity` non è valido, usciamo dal metodo. + +![Messaggio "You've clicked the block for the 6th time" apparso sullo schermo dopo il clic con il tasto destro](/assets/develop/blocks/block_entities_1.png) + +## Salvare e Caricare i Dati {#saving-loading} + +Ora che abbiamo un blocco funzionante, dovremmo anche fare in modo che il contatore non si resetti dopo un riavvio del gioco. Questo si fa serializzandolo in NBT quando si salva il gioco, e deserializzandolo durante il caricamento. + +La serializzazione avviene con il metodo `writeNbt`: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Qui, aggiungiamo gli attributi che dovrebbero essere salvati al `NbtCompound` passato: nel caso del blocco contatore, l'attributo `clicks`. + +La lettura è simile, ma invece di salvare nel `NbtCompound` si ottengono i valori salvati precendentemente, e salvarli negli attributi del `BlockEntity`: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Ora, salvando e ricaricando il gioco, il blocco contatore dovrebbe riprendere da dove è stato salvato. + +## Ticker {#tickers} + +L'interfaccia `BlockEntityProvider` definisce anche un metodo chiamato `getTicker`, che può essere usato per eseguire del codice ogni tick per ogni istanza del blocco. Possiamo implementarlo creando un metodo statico che verrà usato come `BlockEntityTicker`: + +Il metodo `getTicker` dovrebbe anche controllare che il `BlockEntityType` passato sia quello che stiamo usando; se lo è, restituirà la funzione da chiamare a ogni tick. Vi è una funzione di utilità che fa il controllo in `BlockWithEntity`: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +`CounterBlockEntity::tick` è un riferimento al metodo statico `tick` che dobbiamo creare nella classe `CounterBlockEntity`. Non è necessario seguire questa struttura, ma buona pratica per mantenere del codice pulito e organizzato. + +Diciamo di voler fare in modo che il contatore possa essere incrementato soltanto ogni 10 tick (2 volte al secondo). Possiamo fare ciò aggiungendo un attributo `ticksSinceLast` alla classe `CounterBlockEntity`, e incrementandolo a ogni tick: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Non dimenticare di serializzare e deserializzare questo attributo! + +Ora possiamo usare `ticksSinceLast` per controllare se il contatore può essere incrementato in `incrementClicks`: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +:::tip +Se sembra che il blocco-entità non faccia tick, prova a controllare il codice della registrazione! Dovrebbe passare i blocchi validi per questa entità nel `BlockEntityType.Builder`, o altrimenti scriverà un avviso nella console: + +```text +[13:27:55] [Server thread/WARN] (Minecraft) Block entity fabric-docs-reference:counter @ BlockPos{x=-29, y=125, z=18} state Block{fabric-docs-reference:counter_block} invalid for ticking: +``` + +::: diff --git a/versions/1.21/translated/it_it/develop/blocks/block-entity-renderer.md b/versions/1.21/translated/it_it/develop/blocks/block-entity-renderer.md new file mode 100644 index 000000000..de01601ff --- /dev/null +++ b/versions/1.21/translated/it_it/develop/blocks/block-entity-renderer.md @@ -0,0 +1,99 @@ +--- +title: Renderer dei Blocchi-Entità +description: Impara come vivacizzare il rendering con i renderer di blocchi-entità. +authors: + - natri0 +--- + +# Renderer dei Blocchi-Entità {#block-entity-renderers} + +A volte non basta usare il formato del modello di Minecraft. Se devi aggiungerci del rendering dinamico, dovrai usare un `BlockEntityRenderer`. + +Per esempio, facciamo in modo che il Blocco Contatore dell'[articolo sui Blocchi-Entità](../blocks/block-entities) mostri il numero di clic sulla sua faccia superiore. + +## Creare un BlockEntityRenderer {#creating-a-blockentityrenderer} + +Anzitutto, dobbiamo creare un `BlockEntityRenderer` per il nostro `CounterBlockEntity`. + +Nel creare un `BlockEntityRenderer` per il `CounterBlockEntity`, è importante inserire la classe nell'insieme delle fonti corretto, come `src/client/`, se il tuo progetto divide gli insiemi delle fonti tra client e server. Accedere a classi legate al rendering direttamente nell'insieme delle fonti `src/main/` non è sicuro perché quelle classi potrebbero essere caricare su un server. + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +La nuova classe ha un costruttore con un `BlockEntityRendererFactory.Context` come parametro. Il `Context` ha alcune utilità per il rendering, come l'`ItemRenderer` o il `TextRenderer`. +Inoltre, includendo un costruttore come questo, è possibile usare il costruttore come interfaccia funzionale per la `BlockEntityRendererFactory`: + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java) + +Aggiungi l'entrypoint al file `fabric.mod.json`, in modo che il renderer sia registrato. + +`BlockEntityRendererFactories` è una registry che mappa ogni `BlockEntityType` con del codice di rendering personalizzato al rispettivo `BlockEntityRenderer`. + +## Disegnare su Blocchi {#drawing-on-blocks} + +Ora che abbiamo un renderer, possiamo disegnare. Il metodo `render` viene chiamato ad ogni frame, ed è qui che la magia del rendering avviene. + +### Orientarsi {#moving-around} + +Anzitutto, dobbiamo bilanciare e ruotare il testo in modo che sia sul lato superiore del blocco. + +:::info +Come suggerisce il nome, il `MatrixStack` è uno _stack_, il che significa che puoi inserirci (push) ed estrarne (pop) le trasformazioni. +Una buona regola di base è inserirne uno nuovo all'inizio del metodo `render` ed estrarlo alla fine, in modo che il rendering di un blocco non influenzi gli altri. + +Si possono trovare maggiori informazioni riguardo al `MatrixStack` nell'[articolo sui Concetti Base del Rendering](../rendering/basic-concepts). +::: + +Per capire meglio le traslazioni e le rotazioni necessarie, visualizziamole. Nell'immagine, il blocco verde è dove il testo verrebbe disegnato, nel punto più in basso a sinistra del blocco in maniera predefinita: + +![Posizione di rendering predefinita](/assets/develop/blocks/block_entity_renderer_1.png) + +Quindi dobbiamo inizialmente spostare il testo a metà del blocco sugli assi X e Z, poi muoverlo in cima al blocco lungo l'asse Y: + +![Blocco verde nel punto centrale in alto](/assets/develop/blocks/block_entity_renderer_2.png) + +Questo si fa con una sola chiamata a `translate`: + +```java +matrices.translate(0.5, 1, 0.5); +``` + +Ecco che abbiamo completato la _tranlazione_, mancano la _rotazione_ e la _scala_. + +Per impostazione predefinita il testo viene disegnato sul piano XY, quindi dobbiamo ruotarlo di 90 gradi attorno all'asse X perché sia orientato verso l'alto sul piano XZ: + +![Blocco verde nel punto centrale in alto, orientato verso l'alto](/assets/develop/blocks/block_entity_renderer_3.png) + +Il `MatrixStack` non ha una funzione `rotate`, invece dobbiamo usare `multiply` e `RotationAxis.POSITIVE_X`: + +```java +matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); +``` + +Ora il testo è nella posizione corretta, ma è troppo grande. Il `BlockEntityRenderer` mappa l'intero blocco ad un cubo `[-0.5, 0.5]`, mentre il `TextRenderer` usa come coordinate Y `[0, 9]`. Per questo dobbiamo rimpicciolirlo di un fattore di 18: + +```java +matrices.scale(1/18f, 1/18f, 1/18f); +``` + +Ora la trasformazione completa ha questo aspetto: + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +### Disegnare Testo {#drawing-text} + +Come menzionato in precedenza, il `Context` passato al costruttore del nostro renderer ha un `TextRenderer` che possiamo usare per disegnare testo. Per questo esempio lo salveremo in un attributo. + +Il `TextRenderer` ha metodi per misurare il testo (`getWidth`), il che è utile per centrarlo, e per disegnarlo (`draw`). + +@[code transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +Il metodo `draw` prende molti parametri, ma quelli più importanti sono: + +- Il `Text` (o `String`) da disegnare; +- Le sue coordinate `x` e `y`; +- Il valore RGB di `color`; +- La `Matrix4f` che descrive come deve essere trasformato (peeeeer ottenerne una da un `MatrixStack`, possiamo usare `.peek().getPositionMatrix()` per ottenere la `Matrix4f` per la voce in cima). + +Dopo tutto questo lavoro, eccone il risultato: + +![Blocco Contatore con un numero in cima](/assets/develop/blocks/block_entity_renderer_4.png) diff --git a/versions/1.21/translated/it_it/develop/blocks/blockstates.md b/versions/1.21/translated/it_it/develop/blocks/blockstates.md new file mode 100644 index 000000000..f0cab4acc --- /dev/null +++ b/versions/1.21/translated/it_it/develop/blocks/blockstates.md @@ -0,0 +1,128 @@ +--- +title: Stati dei Blocchi +description: Impara perché gli stati dei blocchi sono ottimi per aggiungere funzionalità visive ai tuoi blocchi. +authors: + - IMB11 +--- + +# Stati dei Blocchi {#block-states} + +Uno stato di un blocco è un dato relativo a un singolo blocco nel mondo di Minecraft che contiene informazioni riguardanti il blocco sotto forma di proprietà - ecco alcuni esempi di proprietà che in vanilla sono memorizzate come stati: + +- Rotazione: Usato principalmente per i tronchi e per altri blocchi naturali. +- Attivo: Fondamentale nei componenti della redstone, e blocchi come la fornace e l'affumicatore. +- Età: Usato per colture, piante, arboscelli, alghe... + +Probabilmente hai capito perché sono così utili - per evitare di immagazzinare dati NBT in un blocco-entità, riducendo dunque le dimensioni del mondo e migliorando i TPS! + +Le definizioni degli stati dei blocchi si trovano nella cartella `assets//blockstates`. + +## Esempio: Pilastro {#pillar-block} + + + +Minecraft ha già delle classi che permettono di creare velocemente alcuni tipi di blocco - questo esempio mostra la creazione di un blocco con la proprietà `asse`, con un blocco "Tronco di Quercia Condensato". + +La classe vanilla `PillarBlock` permette di piazzare il blocco lungo gli assi X, Y o Z. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +I pilastri hanno due texture diverse, superiore e laterale - e usano il modello `block/cube_column`. + +Ovviamente, come per tutte le altre texture dei blocchi, i file si trovano nella cartella `assets//textures/blocks` + +le Texture + +Dato che un pilastro ha due posizioni, orizzontale e verticale, dobbiamo creare due file di modelli separati: + +- 'condensed_oak_log_horizontal.json`che estende il modello`block/cube_column_horizontal\`. +- `condensed_oak_log.json` che estende il modello `block/cube_column`. + +Un esempio di come deve essere il file `condensed_oak_log_horizontal.json`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +Se vuoi vedere tutti i modificatori disponibili nel file degli stati, leggi la pagina [Minecraft Wiki - Models (Block States)] +(https://minecraft.wiki/w/Tutorials/Models#Block_states). +::: + +Ora dobbiamo creare un file per lo stato. Il file dello stato è dove avviene la magia—i pilastri hanno tre assi e quindi useremo modelli specifici per i seguenti casi: + +- `axis=x` - Quando il blocco è piazzato sull'asse X, ne ruoteremo il modello in modo che guardi verso la parte positiva delle X. +- `axis=y` - Quando il blocco è piazzato sull'asse Y, useremo il modello verticale normale. +- `axis=z` - Quando il blocco è piazzato sull'asse Z, ne ruoteremo il modello in modo che guardi verso la parte positiva delle X. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +Come sempre, dovrai creare una traduzione per il tuo blocco, oltre ad un modello dell'oggetto il quale deve essere figlio di uno dei due modelli. + +![Foto del pilastro in gioco](/assets/develop/blocks/blockstates_1.png) + +## Stati del Blocco Personalizzati {#custom-block-states} + +Gli stati del blocco personalizazti sono ottimi se il tuo blocco ha proprietà uniche - a volte è anche possibile che il tuo blocco riusi proprietà vanilla. + +Questo esempio creerà una proprietà booleana chiamata `activated` - quando un giocatore clicca con il tasto destro il blocco, il blocco passerà dall'essere `activated=false` ad `activated=true` - cambiando la texture in maniera appropriata. + +### Creare la Proprietà {#creating-the-property} + +Anzitutto, dovrai creare la proprietà in sé - poiché questo è un booleano, useremo il metodo `BooleanProperty.of`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Dopo di che, dovremo aggiungere la proprietà al gestore degli stati del blocco nel metodo `appendProperties`. Dovrai fare override del metodo per accedere al costruttore: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Dovrai anche impostare un valore predefinito per la proprietà `activated` nel costruttore del tuo blocco personalizzato. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +Non dimenticare di registrare il tuo blocco usando la classe personalizzata invece di `Block`! +::: + +### Usare la Proprietà {#using-the-property} + +Questo esempio invertirà la proprietà booleana `activated` quando il giocatore interagisce con il blocco. Possiamo fare override del metodo `onUse` per questo: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### Visualizzare la Proprietà {#visualizing-the-property} + +Prima di creare il file degli stati del blocco, dovrai fornire texture per entrambi gli stati del blocco, sia attivo sia inattivo, e con quelle anche il modello del blocco. + +le Texture + +Sfrutta la tua conoscenza dei modelli dei blocchi per creare due modelli per il blocco: uno per lo stato attivo ed uno per quello inattivo. Quando avrai fatto ciò, puoi iniziare la creazione del file degli stati del blocco. + +Poiché hai aggiunto una nuova proprietà, dovrai aggiornare il file degli stati di quel blocco per tenere quella proprietà in considerazione. + +Se hai proprietà multiple su un blocco, dovrai tenere in conto tutte le possibili combinazioni. Per esempio, `activated` e `axis` porterebbero a 6 combinazioni (due valori possibili per `activated` e tre valori possibili per `axis`). + +Poiché questo blocco ha solo due possibili varianti, dato che ha solo una proprietà (`activated`), il file JSON degli stati del blocco avrà il seguente aspetto: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +Poiché il blocco nell'esempio è una lampada, dovremo anche fargli emettere luce quando la proprietà `activated` è `true`. Questo si può ottenere tramite le impostazioni del blocco, passate al costruttore durante la registrazione del blocco. + +Puoi usare il metodo `luminance` per impostare il livello di luce emessa dal blocco, possiamo creare un metodo statico nella classe `PrismarineLampBlock` per restituire il livello di luce in base alla proprietà `activated`, e passarlo come riferimento a un metodo nel metodo `luminance`: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +Quando avrai completato tutto, il risultato finale dovrebbe avere il seguente aspetto: + + diff --git a/versions/1.21/translated/it_it/develop/blocks/first-block.md b/versions/1.21/translated/it_it/develop/blocks/first-block.md new file mode 100644 index 000000000..b90f58e76 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/blocks/first-block.md @@ -0,0 +1,170 @@ +--- +title: Creare il Tuo Primo Blocco +description: Impara come creare il tuo primo blocco personalizzato in Minecraft. +authors: + - IMB11 + - xEobardThawne + - its-miroma +--- + +# Creare il Tuo Primo Blocco {#creating-your-first-block} + +I blocchi sono i blocchi di costruzione di Minecraft (perdona il gioco di parole) - proprio come tutto il resto di Minecraft, sono memorizzati in registry. + +## Preparare la Tua Classe dei Blocchi {#preparing-your-blocks-class} + +Se hai già completato la pagina [Creare il Tuo Primo Oggetto](../items/first-item), questo processo ti sembrerà molto familiare - dovrai creare un metodo che registri il tuo blocco, e l'oggetto ad esso associato. + +Dovresti mettere questo metodo in una classe chiamata `ModBlocks` (o qualsiasi altro nome). + +Mojang fa qualcosa di simile con i suoi blocchi vanilla; informati riguardo alla classe `Blocks` per sapere come fanno loro. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Proprio come per gli oggetti, dovrai assicurarti che la classe sia caricata, in modo che tutti gli attributi statici contenenti le istanze dei tuoi blocchi siano inizializzati. + +Puoi fare questo creando un metodo fittizio `initialize`, che potrà essere richiamato nell'[initializer della tua mod](./getting-started/project-structure#entrypoints) per avviare l'inizializzazione statica. + +:::info +Se non sai cos'è l'inizializzazione statica, essa è il processo di inizializzazione degli attributi statici in una classe. Questo viene fatto quando la classe viene caricata dalla JVM, ed è fatto prima che qualsiasi istanza della classe venga creata. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## Creare e Registrare il Tuo Blocco {#creating-and-registering-your-block} + +In maniera del tutto simile agli oggetti, i blocchi prendono la classe `Blocks.Settings` nel costruttore. La classe indica proprietà specifiche del blocco, come i suoi effetti sonori e il livello di estrazione. + +Non tratteremo tutte le opzioni qui—puoi vedere la classe da solo per capirne le varie opzioni, che dovrebbero essere chiaramente comprensibili. + +Per questo esempio, creeremo un blocco semplice, con le proprietà della terra ma con un materiale diverso. + +:::tip +Puoi anche usare `AbstractBlock.Settings.copy(AbstractBlock block)` per copiare le impostazioni di un blocco esistente, in questo caso avremmo potuto usare `Blocks.DIRT` per copiare le impostazioni della terra, ma per questo esempio useremo il costruttore. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Per creare l'oggetto del blocco in automatico, possiamo passare `true` al parametro `shouldRegisterItem` del metodo `register` che abbiamo creato nel passaggio precedente. + +### Aggiungere il Tuo Blocco ad un Gruppo di Oggetti {#adding-your-block-to-an-item-group} + +Poiché il `BlockItem` viene creato e registrato in automatico, per aggiungerlo a un gruppo di oggetti devi usare il metodo `Block.asItem()` per ottenere l'istanza `BlockItem`. + +Per questo esempio, useremo un gruppo di oggetti personalizzato, che abbiamo creato nella pagina [Gruppi di Oggetti Personalizzati](../items/custom-item-groups). + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Dovresti ora notare che il tuo blocco è nell'inventario in creativa, e può essere posizionato nel mondo! + +![Blocco nel mondo senza né modello né texture](/assets/develop/blocks/first_block_0.png) + +Ci sono alcuni problemi tuttavia - il blocco non ha nome, non ha texture e non ha modello né per il blocco né per l'oggetto. + +## Aggiungere Traduzioni del Blocco {#adding-block-translations} + +Per aggiungere una traduzione, devi creare una chiave di traduzione nel tuo file di traduzioni - `assets//lang/en_us.json`. + +Minecraft userà questa traduzione nell'inventario in creativa e in altri posti in cui il nome del blocco viene mostrato, come nel feedback dei comandi. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +Per applicare le modifiche, puoi riavviare il gioco o costruire la tua mod e premere F3+T - e dovresti vedere che il blocco ha un nome nell'inventario in creative e in altri posti come nella schermata delle statistiche. + +## Modelli e Texture {#models-and-textures} + +Tutte le texture dei blocchi si trovano nella cartella `assets//textures/block` - ti forniamo una texture di esempio del blocco di "Terra Condensata", che sei libero di usare. + +Texture + +Per fare in modo che la texture sia visibile nel gioco, devi creare un blocco e un modello di oggetto, presenti nelle posizioni appropriate al blocco di "Terra Condensata": + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +Il modello dell'oggetto è piuttosto semplice, basta che usi il modello del blocco come genitore - poiché la GUI supporta il rendering della maggior parte dei modelli dei blocchi: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +Nel nostro caso, però, il modello del blocco deve avere come genitore il modello `block/cube_all`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +Quando carichi il gioco, potresti notare che la texture è ancora mancante. Questo perché devi aggiungere la definizione degli stati del blocco. + +## Creare la Definizione degli Stati del Blocco {#creating-the-block-state-definition} + +La definizione degli stati del blocco è usata dal gioco per capire quale modello renderizzare in base allo stato corrente del blocco. + +Per il blocco di esempio, che non ha stati complessi, basta una sola voce nella definizione. + +Questo file si dovrebbe trovare nella cartella `assets/mod_id/blockstates`, e il suo nome dovrebbe corrispondere all'ID del blocco che hai usato quando l'hai registrato nella classe `ModBlocks`. Per esempio, se l'ID è `condensed_dirt`, il file dovrebbe chiamarsi `condensed_dirt.json`. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +Gli stati dei blocchi sono piuttosto complessi, per cui li tratteremo in un'altra pagina: [Stati dei Blocchi](./blockstates) + +Riavviando il gioco o ricaricando con F3+T per applicare le modifiche - dovresti poter vedere la texture del blocco nell'inventario e fisicamente nel mondo: + +![Blocco nel mondo con texture e modello appropriati](/assets/develop/blocks/first_block_4.png) + +## Aggiungere Drop al Blocco {#adding-block-drops} + +Quando si rompe il blocco in sopravvivenza, potresti notare che il blocco non droppa - potresti volere questa funzionalità, ma per fare in modo che il blocco droppi come oggetto quando viene rotto devi implementarne la loot table - il file della loot table dovrebbe essere nella cartella `data//loot_table/blocks/`. + +:::info +Per comprendere le loot table nel profondo, fai riferimento alla pagina [Minecraft Wiki - Loot Tables](https://minecraft.wiki/w/Loot_table). +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +Questa loot table fornisce un solo drop come oggetto del blocco quando viene rotto, o distrutto da un'esplosione. + +## Consigliare uno Strumento per la Raccolta {#recommending-a-harvesting-tool} + +Potresti anche volere che il tuo blocco sia ottenibile solo con uno strumento specifico - per esempio, più veloce da ottenere con una pala. + +Tutti i tag degli strumenti dovrebbero essere nella cartella `data/minecraft/tags/block/mineable/` - e il nome del file dipende dal tipo di strumento usato, uno tra i seguenti: + +- `hoe.json` +- `axe.json` +- `pickaxe.json` +- `shovel.json` + +I contenuti del file sono piuttosto semplici - è una lista di oggetti da aggiungere al tag. + +Questo esempio aggiunge il blocco "Terra Condensata" al tag `shovel`. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +Se desideri che uno strumento sia necessario per minare il blocco, dovrai aggiungere `.requiresTool()` alle impostazioni del tuo blocco, oltre che aggiungere il tag dello scavo appropriato. + +## Livelli di Scavo {#mining-levels} + +Similmente, il tag del livello di scavo si trova nella cartella `data/minecraft/tags/block/`, e segue il seguente formato: + +- `needs_stone_tool.json` - Almeno strumenti di pietra +- `needs_iron_tool.json` - Almeno strumenti di ferro +- `needs_diamond_tool.json` - Almeno strumenti di diamante + +Il file ha lo stesso formato di quello per la raccolta - una lista di oggetti da aggiungere al tag. + +## Note Aggiuntive {#extra-notes} + +Se stai aggiungendo più blocchi alla tua mod, potresti voler usare la [Data Generation](https://fabricmc.net/wiki/tutorial:datagen_setup) per automatizzare il processo di creazione dei modelli di blocchi e oggetti, delle definizioni degli stati del blocco, e delle loot table. diff --git a/versions/1.21/translated/it_it/develop/codecs.md b/versions/1.21/translated/it_it/develop/codecs.md new file mode 100644 index 000000000..e4551c1ae --- /dev/null +++ b/versions/1.21/translated/it_it/develop/codecs.md @@ -0,0 +1,398 @@ +--- +title: Codec +description: Una guida esaustiva per la comprensione e l'uso del sistema di codec di Mojang per serializzare e deserializzare gli oggetti. +authors: + - enjarai + - Syst3ms +--- + +# Codec {#codecs} + +Un codec è un sistema per serializzare facilmente oggetti Java, ed è incluso nella libreria DataFixerUpper (DFU) di Mojang, che è inclusa in Minecraft. Nel contesto del modding essi possono essere usati come un'alternativa a GSON e Jankson quando si leggono e si scrivono file json personalizzati, anche se hanno cominciato a diventare sempre più rilevanti, visto che Mojang sta riscrivendo molto suo codice in modo che usi i Codec. + +I Codec vengono usati assieme a un'altra API da DFU, `DynamicOps`. Un codec definisce la struttura di un oggetto, mentre i dynamic ops vengono usati per definire un formato da cui e a cui essere serializzato, come json o NBT. Questo significa che qualsiasi codec può essere usato con qualsiasi dynamic ops, e viceversa, permettendo una grande flessibilità. + +## Usare i Codec {#using-codecs} + +### Serializzazione e Deserializzazione {#serializing-and-deserializing} + +L'uso principale di un codec è serializzare e deserializzare oggetti da e a un formato specifico. + +Poiché alcune classi vanilla hanno già dei codec definiti, possiamo usare quelli come un esempio. Mojang ci ha anche fornito due classi di dynamic ops predefinite, `JsonOps` e `NbtOps`, che tendono a coprire la maggior parte degli casi. + +Ora, immaginiamo di voler serializzare un `BlockPos` a json e viceversa. Possiamo fare questo usando il codec memorizzato staticamente presso `BlockPos.CODEC` con i metodi `Codec#encodeStart` e `Codec#parse`, rispettivamente. + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// Serializza il BlockPos a un JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +Quando si usa un codec, i valori sono restituiti come un `DataResult`. Questo è un wrapper che può rappresentare un successo oppure un fallimento. Possiamo usare questo in diversi modi: Se vogliamo soltanto il nostro valore serializzato, `DataResult#result` restituirà semplicemente un `Optional` contenente il nostro valore, mentre `DataResult#resultOrPartial` ci permette anche di fornire una funzione per gestire qualsiasi errore che potrebbe essersi verificato. La seconda è specialmente utile per risorse di datapack personalizzati, in cui potremmo voler segnare gli errori nel log senza causare problemi altrove. + +Quindi prendiamo il nostro valore serializzato e ritrasformiamolo nuovamente in un `BlockPos`: + +```java +// Quando stai davvero scrivendo una mod, vorrai ovviamente gestire gli Optional vuoti propriamente +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Qui abbiamo il nostro valore json, che dovrebbe corrispondere a `[1, 2, 3]`, +// poiché quello è il formato usato dal codec di BlockPos. +LOGGER.info("Serialized BlockPos: {}", json); + +// Ora deserializzeremo nuovamente il JsonElement in un BlockPos +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// Ancora, prenderemo soltanto il nostro valore dal risultato +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// E possiamo notare che abbiamo serializzato e deserializzato il nostro BlockPos con successo! +LOGGER.info("Deserialized BlockPos: {}", pos); +``` + +### Codec Predefiniti {#built-in-codecs} + +Come menzionato in precedenza, Mojang ha già definito codec per tante classi Java vanilla e standard, incluse, ma non solo, `BlockPos`, `BlockState`, `ItemStack`, `Identifier`, `Text`, e `Pattern` regex. I Codec per le classi di Mojang si trovano solitamente come attributi static chiamati `CODEC` della classe stessa, mentre molte altre sono mantenute nella classe `Codecs`. Bisogna anche sottolineare che tutte le registry vanilla contengono un metodo `getCodec()`, per esempio, puoi usare `Registries.BLOCK.getCodec()` per ottenere un `Codec` che serializza all'id del blocco e viceversa. + +L'API stessa dei Codec contiene anche alcuni codec per tipi primitivi, come `Codec.INT` e `Codec.STRING`. Queste sono disponibili come statici nella classe `Codec`, e sono solitamente usate come base per codec più complessi, come spiegato sotto. + +## Costruire Codec {#building-codecs} + +Ora che abbiamo visto come usare i codec, vediamo come possiamo costruircene di nostri. Supponiamo di avere la seguente classe, e di voler deserializzare le sue istanze da file json: + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +Il corrispondente file json potrebbe avere il seguente aspetto: + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +Possiamo creare un codec per questa classe mettendo insieme tanti codec più piccoli per formarne uno più grande. In questo caso, ne avremo bisogno di uno per ogni attributo: + +- un `Codec` +- un `Codec` +- un `Codec>` + +Possiamo ottenere il primo dal codec primitivo nella classe `Codec` menzionato in precedenza, nello specifico `Codec.INT`. Mentre il secondo può essere ottenuto dalla registry `Registries.ITEM`, che ha un metodo `getCodec()` che restituisce un `Codec`. Non abbiamo un codec predefinito per `List`, ma possiamo crearne uno a partire da `BlockPos.CODEC`. + +### Liste {#lists} + +`Codec#listOf` può essere usato per creare una versione lista di qualsiasi codec: + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +Bisogna sottolineare che i codec creati così verranno sempre deserializzati a un'`ImmutableList`. Se invece ti servisse una lista mutabile, puoi usare [xmap](#tipi-convertibili-mutualmente-e-tu) per convertirla ad una durante la deserializzazione. + +### Unire i Codec per Classi Simili ai Record {#merging-codecs-for-record-like-classes} + +Ora che abbiamo codec separati per ciascun attributo, possiamo combinarli a formare un singolo codec per la nostra classe usando un `RecordCodecBuilder`. Questo suppone che la nostra classe abbia un costruttore che contiene ogni attributo che vogliamo serializzare, e che ogni attributo ha un metodo getter corrispondente. Questo lo rende perfetto per essere usato assieme ai record, ma può anche essere usato con classi regolari. + +Diamo un'occhiata a come creare un codec per la nostra `CoolBeansClass`: + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // Un massimo di 16 attributi può essere dichiarato qui +).apply(instance, CoolBeansClass::new)); +``` + +Ogni linea nel gruppo specifica un codec, il nome di un attributo, e un metodo getter. La chiamata a `Codec#fieldOf` è usata per convertire il codec a un [MapCodec](#mapcodec), e la chiamata a `forGetter` specifica il metodo getter usato per ottenere il valore dell'attributo da un'istanza della classe. Inoltre, la chiamata ad `apply` specifica il costruttore usato per creare nuove istanze. Nota che l'ordine degli attributi nel gruppo dovrebbe essere lo stesso di quello dei parametri nel costruttore. + +Puoi anche usare `Codec#optionalFieldOf` in questo contesto per rendere un attributo opzionale, come spiegato nella sezione [Attributi Opzionali](#attributi-opzionali). + +### MapCodec, Da Non Confondere Con Codec&lt;Map&gt; {#mapcodec} + +La chiamata a `Codec#fieldOf` convertirà un `Codec` in un `MapCodec`, che è una variante, ma non una diretta implementazione di `Codec`. I `MapCodec`, come suggerisce il loro nome garantiscono la serializzazione a una mappa chiave-valore, o al suo equivalente nella `DynamicOps` usata. Alcune funzioni ne potrebbero richiedere uno invece di un codec normale. + +Questo modo particolare di creare un `MapCodec` racchiude sostanzialmente il valore del codec sorgente dentro una mappa, con il nome dell'attributo dato come chiave. Per esempio, un `Codec` serializzato a json avrebbe il seguente aspetto: + +```json +[1, 2, 3] +``` + +Ma quando viene convertito in un `MapCodec` usando `BlockPos.CODEC.fieldOf("pos")`, esso ha il seguente aspetto: + +```json +{ + "pos": [1, 2, 3] +} +``` + +Anche se i Map Codec vengono più frequentemente usati per essere uniti ad altri Map Codec per costruire un codec per l'intero insieme di attributi di una classe, come spiegato nella sezione [Unire i Codec per Classi simili ai Record](#unire-i-codec-per-classi-simili-ai-record) sopra, essi possono anche essere ritrasformati in codec normali usando `MapCodec#codec`, che darà lo stesso risultato di incapsulare il loro valore di input. + +#### Attributi Opzionali {#optional-fields} + +`Codec#optionalFieldOf` può essere usato per create una mappa codec opzionale. Esso, quando l'attributo indicato non è presente nel container durante la deserializzazione, verrà o deserializzato come un `Optional` vuoto oppure con un valore predefinito indicato. + +```java +// Senza un valore predefinito +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// Con un valore predefinito +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +Nota che gli attributi opzionali ignoreranno silenziosamente qualsiasi errore che possa verificarsi durante la deserializzazione. Questo significa che se l'attributo è presente, ma il valore non è valido, l'attributo verrà sempre deserializzato al valore predefinito. + +**A partire da 1.20.2**, Minecraft stesso (non DFU!) fornisce `Codecs#createStrictOptionalFieldCodec`, che fallisce del tutto nel deserializzare se il valore dell'attributo non è valido. + +### Costanti, Vincoli, e Composizione {#constants-constraints-composition} + +#### Unità {#unit} + +`Codec.unit` può essere usato per creare un codec che verrà sempre deserializzato a un valore costante, indipendentemente dall'input. Durante la serializzazione, non farà nulla. + +```java +Codec theMeaningOfCodec = Codec.unit(42); +``` + +#### Intervalli Numerici {#numeric-ranges} + +`Codec.intRange` e compagnia, `Codec.floatRange` e `Codec.doubleRange` possono essere usati per creare un codec che accetta soltanto valori numerici all'interno di un intervallo **inclusivo** specificato. Questo si applica sia alla serializzazione sia alla deserializzazione. + +```java +// Non può essere superiore a 2 +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Coppia {#pair} + +`Codec.pair` unisce due codec, `Codec` e `Codec`, in un `Codec>`. Tieni a mente che funziona correttamente soltanto con codec che serializzano a un attributo specifico, come [MapCodec convertiti](#mapcodec) oppure [Codec di Record](#unire-i-codec-per-classi-simili-ai-record). +Il codec risultante serializzerà a una mappa contenente gli attributi di entrambi i codec usati. + +Per esempio, eseguire questo codice: + +```java +// Crea due codec incapsulati separati +Codec firstCodec = Codec.INT.fieldOf("i_am_number").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("this_statement_is_false").codec(); + +// Uniscili in un codec coppia +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// Usalo per serializzare i dati +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +Restituirà il seguente json: + +```json +{ + "i_am_number": 23, + "this_statement_is_false": true +} +``` + +#### Either {#either} + +`Codec.either` unisce due codec, `Codec` e `Codec`, in un `Codec>`. Il codec risultante tenterà, durante la deserializzazione, di usare il primo codec, e _solo se quello fallisce_, tenterà di usare il secondo. +Se anche il secondo fallisse, l'errore del _secondo_ codec verrà restituito. + +#### Mappe {#maps} + +Per gestire mappe con chiavi arbitrarie, come `HashMap`, `Codec.unboundedMap` può essere usato. Questo restituisce un `Codec>` per un dato `Codec` e `Codec`. Il codec risultante serializzerà a un oggetto json oppure a qualsiasi equivalente disponibile per il dynamic ops corrente. + +Date le limitazioni di json e nbt, il codec chiave usato _deve_ serializzare a una stringa. Questo include codec per tipo che non sono in sé stringhe, ma che serializzano a esse, come `Identifier.CODEC`. Vedi l'esempio sotto: + +```java +// Crea un codec per una mappa da identifier a interi +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// Usalo per serializzare i dati +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "number"), 23, + new Identifier("example", "the_cooler_number"), 42 +)); +``` + +Questo restituirà il json seguente: + +```json +{ + "example:number": 23, + "example:the_cooler_number": 42 +} +``` + +Come puoi vedere, questo funziona perché `Identifier.CODEC` serializza direttamente a un valore di tipo stringa. Un effetto simile può essere ottenuto per oggetti semplici che non serializzano a stringhe usando [xmap e compagnia](#tipi-convertibili-mutualmente-e-tu) per convertirli. + +### Tipi Convertibili Mutualmente e Tu {#mutually-convertible-types} + +#### `xmap` {#xmap} + +Immagina di avere due classi che possono essere convertite l'una nell'altra e viceversa, ma che non hanno un legame gerarchico genitore-figlio. Per esempio, un `BlockPos` vanilla e un `Vec3d`. Se avessimo un codec per uno, possiamo usare `Codec#xmap` per creare un codec per l'altro specificando una funzione di conversione per ciascuna direzione. + +`BlockPos` ha già un codec, ma facciamo finta che non ce l'abbia. Possiamo creargliene uno basandolo sul codec per `Vec3d` così: + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // Converti Vec3d a BlockPos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // Converti BlockPos a Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// Quando converti una classe esistente (per esempio `X`) +// alla tua classe personalizzata (`Y`) in questo modo, +// potrebbe essere comodo aggiungere i metodi `toX` e +// `fromX` statico ad `Y` e usare riferimenti ai metodi +// nella tua chiamata ad `xmap`. +``` + +#### flatComapMap, comapFlatMap, e flatXMap {#flatcomapmap-comapflatmap-flatxmap} + +`Codec#flatComapMap`, `Codec#comapFlatMap` e `flatXMap` sono simili a xmap, ma permettono a una o a entrambe le funzioni di conversione di restituire un DataResult. Questo è utile nella pratica perché un'istanza specifica di un oggetto potrebbe non essere sempre valida per la conversione. + +Prendi per esempio gli `Identifier` vanilla. Anche se tutti gli identifier possono essere trasformati in stringhe, non tutte le stringhe sono identifier validi, quindi usare xmap vorrebbe dire lanciare delle brutte eccezioni quando la conversione fallisce. +Per questo, il suo codec predefinito è in realtà una `comapFlatMap` su `Codec.STRING`, che illustra bene come usarla: + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Posizione di risorsa non valida: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +Anche se questi metodi sono molto d'aiuto, i loro nomi possono confondere un po', quindi ecco una tabella per aiutarti a ricordare quale usare: + +| Metodo | A -> B è sempre valido? | B -> A è sempre valido? | +| ----------------------- | ----------------------- | ----------------------- | +| `Codec#xmap` | Sì | Sì | +| `Codec#comapFlatMap` | No | Sì | +| `Codec#flatComapMap` | Sì | No | +| `Codec#flatXMap` | No | No | + +### Dispatch della Registry {#registry-dispatch} + +`Codec#dispatch` ci permette di definire una registry di codec e di fare dispatch ad uno di essi in base al valore di un attributo nei dati serializzati. Questo è molto utile durante la deserializzazione di oggetti che hanno attributi diversi a seconda del loro tipo, ma che rappresentano pur sempre la stessa cosa. + +Per esempio, immaginiamo di avere un'interfaccia astratta `Bean` con due classi che la implementano: `StringyBean` e `CountingBean`. Per serializzare queste con un dispatch di registry, ci serviranno alcune cose: + +- Codec separati per ogni tipo di fagiolo. +- Una classe o un record `BeanType` che rappresenta il tipo di fagiolo, e che può restituire il codec per esso. +- Una funzione in `Bean` per ottenere il suo `BeanType`. +- Una mappa o una registry per mappare `Identifier` a `BeanType`. +- Un `Codec>` basato su questa registry. Se usi una `net.minecraft.registry.Registry`, un codec può essere creato facilmente usando `Registry#getCodec`. + +Con tutto questo, possiamo creare un codec di dispatch di registry per i fagioli: + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// Ora possiamo creare un codec per i tipi di fagioli +// in base alla registry creata in precedenza +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// E in base a quello, ecco il nostro codec di dispatch della registry per i fagioli! +// Il primo parametro e il nome dell'attributo per il tipo di fagiolo. +// Se lasciato vuoto, assumerà "type" come valore predefinito. +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::codec); +``` + +Il nostro nuovo codec serializzerà fagioli a json così, prendendo solo attributi che sono rilevanti al loro tipo specifico: + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "This bean is stringy!" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### Codec Ricorsivi {#recursive-codecs} + +A volte è utile avere un codec che usa _sé stesso_ per decodificare attributi specifici, per esempio quando si gestiscono certe strutture dati ricorsive. Nel codice vanilla, questo è usato per gli oggetti `Text`, che potrebbero contenere altri `Text` come figli. Un codec del genere può essere costruito usando `Codec#recursive`. + +Per esempio, proviamo a serializzare una lista concatenata singolarmente. Questo metodo di rappresentare le liste consiste di una serie di nodi che contengono sia un valore sia un riferimento al nodo successivo nella lista. La lista è poi rappresentata dal suo primo nodo, e per attraversare la lista si segue il prossimo nodo finché non ce ne sono più. Ecco una semplice implementazione di nodi che contengono interi. + +```java +public record ListNode(int value, ListNode next) {} +``` + +Non possiamo costruire un codec per questo come si fa di solito: quale codec useremmo per l'attributo `next`? Avremmo bisogno di un `Codec`, che è ciò che stiamo costruendo proprio ora! `Codec#recursive` ci permette di fare ciò usando una lambda che sembra magia: + +```java +Codec codec = Codec.recursive( + "ListNode", // un nome per il codec + selfCodec -> { + // Qui, `selfCodec` rappresenta il `Codec`, come se fosse già costruito + // Questa lambda dovrebbe restituire il codec che volevamo usare dall'inizio, + // che punta a sé stesso attraverso `selfCodec` + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // l'attributo `next` sarà gestito ricorsivamente con il self-codec + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +Un `ListNode` serializzato potrebbe avere questo aspetto: + +```json +{ + "value": 2, + "next": { + "value": 3, + "next": { + "value": 5 + } + } +} +``` + +## Riferimenti {#references} + +- Una documentazione molto più dettagliata sui Codec e sulle relative API può essere trovata presso la [JavaDoc non Ufficiale di DFU](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec). +- La struttura generale di questa guida è fortemente ispirata dalla [pagina sui codec della Wiki della Community di Forge](https://forge.gemwire.uk/wiki/Codecs), una pagina più orientata verso Forge sullo stesso argomento. diff --git a/versions/1.21/translated/it_it/develop/commands/arguments.md b/versions/1.21/translated/it_it/develop/commands/arguments.md new file mode 100644 index 000000000..5d97cbbac --- /dev/null +++ b/versions/1.21/translated/it_it/develop/commands/arguments.md @@ -0,0 +1,64 @@ +--- +title: Parametri dei Comandi +description: Impara come creare comandi con parametri complessi. +--- + +# Parametri dei Comandi {#command-arguments} + +La maggior parte dei comandi usa i parametri. A volte possono essere opzionali, il che significa che se non viene fornito quel parametri, il comando verrà eseguito comunque. Ogni nodo può avere tipi di parametri multipli, ma ricorda che c'è una possibilità di ambiguità, che dovrebbe essere evitata. + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +In questo caso, dopo il testo del comando `/command_with_arg`, dovresti scrivere un intero. Per esempio, se eseguissi `/command_with_arg 3`, otterresti come risposta il messaggio: + +> Called /command_with_arg with value = 3 + +Se scrivessi `/command_with_arg` senza parametri, non sarebbe possibile fare il parsing del comando correttamente. + +Dopo di che aggiungiamo un secondo parametro opzionale: + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Ora puoi scrivere uno oppure due interi. Se fornisci un intero, un testo di feedback con un singolo valore verrà stampato. Se fornisci due interi, un testo di feedback con due interi verrà stampato. + +Potresti pensare che sia inutile specificare esecuzioni simili due volte. Per cui possiamo creare un metodo che verrà usato in entrambe le esecuzioni. + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Tipi di Parametri Personalizzati {#custom-argument-types} + +Se vanilla non fornisce il tipo di parametro che ti serve, puoi creartene uno. Per fare questo, hai bisogno di creare una classe che implementa l'interfaccia `ArgumentType` dove `T` è il tipo del parametro. + +Avrai bisogno d'implementare il metodo `parse`, che farà il parsing della stringa in input nel tipo desiderato. + +Per esempio, puoi creare un tipo di parametro che fa il parsing di un `BlockPos` da una stringa con il formato seguente: `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Registrare i Tipi di Parametri Personalizzati {#registering-custom-argument-types} + +:::warning +Avrai bisogno di registrare i tipi di parametri personalizzati sia sul server sia sul client altrimenti il comando non funzionerà! +::: + +Puoi registrare il tuo tipo di parametro personalizzato nel metodo `onInitialize` dell'[inizializer della tua mod](./getting-started/project-structure#entrypoints) usando la classe `ArgumentTypeRegistry`: + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Usare i Tipi di Parametri Personalizzati {#using-custom-argument-types} + +Possiamo usare il nostro tipo di parametro personalizzato in un comando - passando un'istanza di esso nel metodo `.argument` del costruttore del comando. + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Eseguendo il comando possiamo testare se il tipo di parametro funziona o meno: + +![Parametro non valido](/assets/develop/commands/custom-arguments_fail.png) + +![Parametro valido](/assets/develop/commands/custom-arguments_valid.png) + +![Risultato del Comando](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/it_it/develop/commands/basics.md b/versions/1.21/translated/it_it/develop/commands/basics.md new file mode 100644 index 000000000..9047b3f0f --- /dev/null +++ b/versions/1.21/translated/it_it/develop/commands/basics.md @@ -0,0 +1,177 @@ +--- +title: Creare Comandi +description: Creare comandi con parametri e azioni complesse. +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple +--- + +# Creare Comandi {#creating-commands} + +Creare comandi può permettere a uno sviluppatore di mod di aggiungere funzionalità che possono essere usate attraverso un comando. Questo tutorial ti insegnerà come registrare comandi e qual è la struttura generale dei comandi di Brigadier. + +::: info +Brigadier is a command parser and dispatcher written by Mojang for Minecraft. It is a tree-based command library where +you build a tree of commands and arguments. + +Brigadier è open-source: +::: + +## L'interface `Command` {#the-command-interface} + +`com.mojang.brigadier.Command` è un'interfaccia funzionale, che esegue del codice specifico, e lancia una `CommandSyntaxException` in determinati casi. Ha un tipo generico `S`, che definisce il tipo della _sorgente del comando_. +La sorgente del comando fornisce del contesto in cui un comando è stato eseguito. In Minecraft, la sorgente del comando è tipicamente una `ServerCommandSource` che potrebbe rappresentare un server, un blocco comandi, una connessione remota (RCON), un giocatore o un'entità. + +L'unico metodo di `Command`, `run(CommandContext)` prende un `CommandContext` come unico parametro e restituisce un intero. Il contesto del comando contiene la tua sorgente del comando di `S` e ti permette di ottenere parametri, osservare i nodi di un comando di cui è stato effettuato il parsing e vedere l'input usato in questo comando. + +Come altre interfacce funzionali, viene solitamente usata come una lambda o come un riferimento a un metodo: + +```java +Command command = context -> { + return 0; +}; +``` + +L'intero può essere considerato il risultato del comando. Di solito valori minori o uguali a zero indicano che un comando è fallito e non farà nulla. Valori positivi indicano che il comando ha avuto successo e ha fatto qualcosa. Brigadier fornisce una costante per indicare +il successo; `Command#SINGLE_SUCCESS`. + +### Cosa Può Fare la `ServerCommandSource`? {#what-can-the-servercommandsource-do} + +Una `ServerCommandSource` fornisce del contesto aggiuntivo dipendente dall'implementazione quando un comando viene eseguito. Questo include la possibilità di ottenere l'entità che ha eseguito il comando, il mondo in cui esso è stato eseguito o il server su cui è stato eseguito. + +Puoi accedere alla sorgente del comando dal contesto del comando chiamando `getSource()` sull'istanza di `CommandContext`. + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## Registrare un Comando Basilare {#registering-a-basic-command} + +I comandi sono registrati all'interno del `CommandRegistrationCallback` fornito dall'API di Fabric. + +:::info +Per informazioni su come registrare i callback, vedi per favore la guida [Eventi](../events). +::: + +L'evento dovrebbe essere registrato nell'[initializer della tua mod](./getting-started/project-structure#entrypoints). + +Il callback ha tre parametri: + +- `CommandDispatcher dispatcher` - Usato per registrare, analizzare, ed eseguire comandi. `S` è il tipo di fonte di comando che il dispatcher supporta. +- `CommandRegistryAccess registryAccess` - Fornisce un'astrazione alle registry che potrebbero essere passate ad alcuni argomenti di metodi di comandi +- `CommandManager.RegistrationEnvironment environment` - Identifica il tipo di server su cui i comandi vengono registrati. + +Nell'initializer della mod, registriamo un semplice comando: + +@[code lang=java transcludeWith=:::test_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Nel metodo `sendFeedback()` il primo parametro è il testo che viene mandato, che è un `Supplier` per evitare d'istanziare oggetti Text quando non è necessario. + +Il secondo parametro determina se trasmettere il feedback agli altri operatori. In generale, se il comando deve ottenere informazioni senza effettivamente modificare il mondo, come il tempo corrente o una statistica di un giocatore, dovrebbe essere `false`. Se il comando fa qualcosa, come cambiare il tempo o modificare il punteggio di qualcuno, dovrebbe essere `true`. + +Se il comando fallisce, anziché chiamare `sendFeedback()`, puoi direttamente lanciare qualsiasi eccezione e il server o il client la gestiranno in modo appropriato. + +`CommandSyntaxException` generalmente viene lanciata per indicare errori di sintassi nel comando o negli argomenti. Puoi anche implementare la tua eccezione personalizzata. + +Per eseguire questo comando, devi scrivere `/test_command`, tutto minuscolo. + +:::info +Da ora in poi, estrarremo la logica scritta all'interno della lambda passata nei costruttori `.execute()` in metodi individuali. Potremo quindi passare a `.execute()` un riferimento al metodo. Faremo questo per chiarezza. +::: + +### Ambiente di Registrazione {#registration-environment} + +Se vuoi, puoi anche assicurarti che un comando venga registrato solo sotto circostanze specifiche, per esempio, solo nell'ambiente dedicato: + +@[code lang=java highlight={2} transcludeWith=:::dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Requisiti dei Comandi {#command-requirements} + +Immagina di avere un comando e vuoi che solo gli operatori lo possano eseguire. Questo è dove il metodo `requires()` entra in gioco. Il metodo `requires()` ha un solo argomento `Predicate` che fornirà una `ServerCommandSource` con cui testare e determinare se la `CommandSource` può eseguire il comando. + +@[code lang=java highlight={3} transcludeWith=:::required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Questo comando verrà eseguito solo se la fonte del comando è un operatore di livello 2 almeno, inclusi i blocchi comandi. Altrimenti, il comando non è registrato. + +Questo ha l'effetto collaterale di non mostrare il comando se si completa con tab a nessuno eccetto operatori di livello 2. Inoltre è il motivo per cui non puoi completare molti dei comandi con tab senza abilitare i comandi. + +### Sotto Comandi {#sub-commands} + +Per aggiungere un sotto comando, devi registrare il primo nodo letterale del comando normalmente. Per avere un sotto comando, devi aggiungere il nodo letterale successivo al nodo esistente. + +@[code lang=java highlight={3} transcludeWith=:::sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Similarmente agli argomenti, i nodi dei sotto comandi possono anch'essi essere opzionali. Nel caso seguente, sia `/command_two` che `/command_two sub_command_two` saranno validi. + +@[code lang=java highlight={2,8} transcludeWith=:::sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Comandi Lato Client {#client-commands} + +L'API di Fabric ha un `ClientCommandManager` nel package `net.fabricmc.fabric.api.client.command.v2` che può essere usato per registrare comandi lato client. Il codice dovrebbe esistere solo nel codice lato client. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## Reindirizzare Comandi {#command-redirects} + +I comandi reindirizzati - anche noti come alias - sono un modo di reindirizzare la funzionalità di un comando a un altro. Questo è utile quando vuoi cambiare il nome di un comando, ma vuoi comunque supportare il vecchio nome. + +:::warning +Brigadier [reinderizzerà soltanto i nodi di comandi contenenti parametri](https://github.com/Mojang/brigadier/issues/46). Se volessi reinderizzare il nodo di un comando senza parametri, fornisci un costruttore `.executes()` con un riferimento alla stessa logica presentata nell'esempio. +::: + +@[code lang=java transcludeWith=:::redirect_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_redirected_by](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Domande Frequenti (FAQ) {#faq} + +### Perché il Mio Codice Non Viene Compilato? {#why-does-my-code-not-compile} + +- Catturare o lanciare una `CommandSyntaxException` - `CommandSyntaxException` non è una `RuntimeException`. Se la lanci, dovresti farlo in metodi che lanciano una `CommandSyntaxException` nelle firme dei metodi, oppure dovresti catturarla. + Brigadier gestirà le eccezioni controllate e ti inoltrerà il messaggio d'errore effettivo nel gioco. + +- Problemi con i generic - Potresti avere un problema con i generic una volta ogni tanto. Se stai registrando comandi sul server (ovvero nella maggior parte dei casi), assicurati di star usando `CommandManager.literal` + o `CommandManager.argument` anziché `LiteralArgumentBuilder.literal` o `RequiredArgumentBuilder.argument`. + +- Controlla il metodo `sendFeedback()` - Potresti aver dimenticato di fornire un valore booleano come secondo argomento. Ricordati anche che, da Minecraft 1.20, il primo parametro è `Supplier` anziché `Text`. + +- Un Command dovrebbe restituire un intero - Quando registri comandi, il metodo `executes()` accetta un oggetto `Command`, che è solitamente una lambda. La lambda dovrebbe restituire un intero, anziché altri tipi. + +### Posso Registrare Comandi al Runtime? {#can-i-register-commands-at-runtime} + +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +Dopo averlo fatto, devi nuovamente inviare l'albero di comandi a ogni giocatore usando `CommandManager.sendCommandTree(ServerPlayerEntity)`. + +Questo è necessario perché il client mantiene una cache locale dell'albero dei comandi che riceve durante il login (o quando i pacchetti per operatori vengono mandati) per suggerimenti locali e messaggi di errore ricchi. +::: + +### Posso De-Registrare Comandi al Runtime? {#can-i-unregister-commands-at-runtime} + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +Per tenere le cose semplici, devi usare la reflection su Brigadier e rimuovere nodi. Dopodiché, devi mandare nuovamente l'albero di comandi a ogni giocatore usando `sendCommandTree(ServerPlayerEntity)`. + +Se non mandi l'albero di comandi aggiornato, il client potrebbe credere che il comando esista ancora, anche se fallirà l'esecuzione sul server. +::: diff --git a/versions/1.21/translated/it_it/develop/commands/suggestions.md b/versions/1.21/translated/it_it/develop/commands/suggestions.md new file mode 100644 index 000000000..9f2a13820 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/commands/suggestions.md @@ -0,0 +1,49 @@ +--- +title: Suggerimenti dei Comandi +description: Impara come suggerire i valori per gli argomenti dei comandi agli utenti. +authors: + - IMB11 +--- + +# Suggerimenti dei Comandi {#command-suggestions} + +Minecraft ha un potente sistema di suggerimento comandi che viene usato in molti posti, come nel comando `/give`. Questo sistema ti permette di suggerire valori per argomenti dei comandi all'utente, da cui possono poi selezionare - è un ottimo modo per rendere i tuoi comandi più user-friendly ed ergonomici. + +## Provider di Suggerimenti {#suggestion-providers} + +Un `SuggestionProvider` viene usato per creare una lista di suggerimenti che verrà mandata al client. Un provider di suggerimenti è un'interfaccia funzionale che prende un `CommandContext` e un `SuggestionBuilder` e restituisce alcune `Suggestions`. Il `SuggestionProvider` restituisce un `CompletableFuture` siccome i suggerimenti potrebbero non essere disponibili immediatamente. + +## Usare i Provider di Suggerimenti {#using-suggestion-providers} + +Per usare un provider di suggerimenti, devi chiamare il metodo `suggests` nel costruttore di argomenti. Questo metodo prende un `SuggestionProvider` e restituisce il costruttore di argomenti modificato con l'aggiunta del suggestion provider. + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Provider di Suggerimenti Predefiniti {#built-in-suggestion-providers} + +Ci sono alcuni provider di suggerimenti predefiniti che puoi usare: + +| Provider di Suggerimenti | Descrizione | +| ----------------------------------------- | ----------------------------------------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | Suggerisce tutte le entità che possono essere evocate. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | Suggerisce tutti i suoni che possono essere riprodotti. | +| `LootCommand.SUGGESTION_PROVIDER` | Suggerisce tutte le loot table disponibili. | +| `SuggestionProviders.ALL_BIOMES` | Suggerisce tutti i biomi disponibili. | + +## Creare un Provider di Suggerimenti Personalizzato {#creating-a-custom-suggestion-provider} + +Se un provider predefinito non soddisfa i tuoi requisiti, puoi creare il tuo provider di suggerimenti personalizzato. Per fare questo, devi creare una classe che implementa l'interfaccia `SuggestionProvider` e fare override del metodo `getSuggestions`. + +Per questo esempio, creeremo un provider di suggerimenti che suggerisce tutti i nomi utente dei giocatori sul server. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +Per usare questo provider di suggerimenti, passeresti semplicemente una sua istanza al metodo `.suggests` nel costruttore di comandi. + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Ovviamente, i provider di suggerimenti possono essere più complessi, siccome possono anche leggere il contesto dei comandi per fornire suggerimenti basati sullo stato del comando - per esempio quali argomenti sono già stati forniti. + +Ciò potrebbe essere ad esempio leggere l'inventario del giocatore e suggerire oggetti, o entità che sono vicine al giocatore. diff --git a/versions/1.21/translated/it_it/develop/data-generation/advancements.md b/versions/1.21/translated/it_it/develop/data-generation/advancements.md new file mode 100644 index 000000000..a24ae8b44 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/data-generation/advancements.md @@ -0,0 +1,167 @@ +--- +title: Generazione di Progressi +description: Una guida per configurare la generazione di progressi con datagen. +authors: + - skycatminepokie + - MattiDragon + - Spinoscythe +authors-nogithub: + - jmanc3 + - mcrafterzz +--- + +# Generazione di Progressi {#advancement-generation} + +:::info PREREQUISITI +Assicurati di aver prima completato il processo di [configurazione della datagen](./setup). +::: + +## Configurazione {#setup} + +Anzitutto, dobbiamo creare il nostro fornitore. Crea una classe che `extends FabricAdvancementProvider` e compilane i metodi di base: + +@[code lang=java transcludeWith=:::datagen-advancements:provider-start](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Per completare la configurazione, aggiungi questo fornitore alla tua `DataGeneratorEntrypoint` nel metodo `onInitializeDataGenerator`. + +@[code lang=java transclude={24-24}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Struttura dei Progressi {#advancement-structure} + +Un progresso è composto di alcune componenti diverse. Assieme ai requisiti, detti "criterio", potrebbe avere: + +- Un `AdvancementDisplay` che dice al gioco come mostrare il progresso ai giocatori, +- `AdvancementRequirements`, ovvero liste di liste di criteri, che richiedono che almeno un criterio di ogni sotto-lista sia soddisfatto, +- `AdvancementRewards`, che il giocatore riceverà per aver completato il progresso, +- Un `CriterionMerger`, che informa il progresso su come gestire criteri multipli, e +- Un `Advancement` genitore, che organizza la gerarchia che vedi nella schermata "Progressi". + +## Progressi Semplici {#simple-advancements} + +Ecco un semplice progresso per aver ottenuto un blocco di terra: + +@[code lang=java transcludeWith=:::datagen-advancements:simple-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +:::details Output JSON +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/advancement/fabric-docs-reference/get_dirt.json) +::: + +## Un Altro Esempio Ancora {#one-more-example} + +Solo per capirne il funzionamento, aggiungiamo un altro progresso. Faremo pratica con l'aggiunta di ricompense, l'utilizzo di criterio multiplo, e l'assegnazione di genitori: + +@[code lang=java transcludeWith=:::datagen-advancements:second-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Non dimenticare di generarli! Usa il comando da terminale qui sotto o esegui la configurazione in IntelliJ. + +::: code-group + +```sh [Windows] +gradlew runDatagen +``` + +```sh [Linux] +./gradlew runDatagen +``` + +::: + +## Criteri Personalizzati {#custom-criteria} + +:::warning +Anche se la datagen può avvenire lato client, i `Criterion` e i `Predicate` sono nell'insieme di codice main (entrambi i lati), poiché il server ne ha bisogno per innescarli e valutarli. +::: + +### Definizioni {#definitions} + +Un **criterio** (in inglese _criterion_, plurale _criteria_) è qualcosa che un giocatore può fare (o che succede a un giocatore) e che può essere considerata per quanto riguarda un progresso. Nel gioco ci sono già vari [criteri](https://minecraft.wiki/w/Advancement_definition#List_of_triggers), che si possono trovare nel package `net.minecraft.advancement.criterion`. In genere dovrai aggiungere un nuovo criterio solo se devi implementare una meccanica personalizzata nel gioco. + +Le **condizioni** sono valutate dai criteri. Un criterio viene preso in considerazione solo se tutte le condizioni rilevanti sono soddisfatte. Le condizioni di solito si esprimono come predicati. + +Un **predicato** è qualcosa che prende un valore e restituisce un `boolean`. Per esempio, un `Predicate` potrebbe restituire `true` se l'oggetto è un diamante, mentre un `Predicate` potrebbe restituire `true` se l'entità non è ostile ai villici. + +### Creare Criteri Personalizzati {#creating-custom-criteria} + +Anzitutto ci serve una meccanica da implementare. Informiamo il giocatore riguardo a quale strumento ha utilizzato ogni volta che rompe un blocco. + +@[code lang=java transcludeWith=:::datagen-advancements:entrypoint](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Nota che questo è del codice molto brutto. La `HashMap` non viene memorizzata persistentemente, quindi sarà resettata ad ogni riavvio del gioco. È solo per mostrare i `Criterion`. Avvia il gioco e provalo! + +Ora, creiamo il nostro criterio personalizzato, `UseToolCriterion`. Avrà bisogno di una sua classe `Conditions`, quindi creeremo entrambe insieme: + +@[code lang=java transcludeWith=:::datagen-advancements:criterion-base](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Wow, questo è un sacco! Analizziamolo poco per volta. + +- `UseToolCriterion` è un `AbstractCriterion`, al quale si possono applicare delle `Conditions`. +- `Conditions` ha un attributo `playerPredicate`. Tutte le `Conditions` dovrebbero avere un predicato del giocatore (tecnicamente un `LootContextPredicate`). +- `Conditions` ha anche un `CODEC`. Questo `Codec` è semplicemente il codec per il suo unico attributo, `playerPredicate`, con istruzioni aggiuntive per convertirlo tra di essi (`xmap`). + +:::info +Per saperne di più sui codec, controlla la pagina [Codec](../codecs). +::: + +Ci serve un modo per controllare se le condizioni sono soddisfatte. Aggiungiamo un metodo ausiliare a `Conditions`: + +@[code lang=java transcludeWith=:::datagen-advancements:conditions-test](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Ora che abbiamo un criterio e le sue condizioni, ci serve un modo per innescarlo. Aggiungi un metodo d'innesco a `UseToolCriterion`: + +@[code lang=java transcludeWith=:::datagen-advancements:criterion-trigger](@/reference/1.21/src/main/java/com/example/docs/advancement/UseToolCriterion.java) + +Ci siamo quasi! Ora, ci serve un'istanza del nostro criterio con cui lavorare. Mettiamola in una nuova classe, chiamata `ModCriteria`. + +@[code lang=java transcludeWith=:::datagen-advancements:mod-criteria](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +Per assicurarci che i nostri criteri siano inizializzati al tempo giusto, aggiungi un metodo vuoto `init`: + +@[code lang=java transcludeWith=:::datagen-advancements:mod-criteria-init](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +E chiamalo nell'initializer della tua mod: + +@[code lang=java transcludeWith=:::datagen-advancements:call-init](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Infine, dobbiamo innescare i nostri criteri. Aggiungi questo a dove inviamo un messaggio al giocatore nella classe main della mod. + +@[code lang=java transcludeWith=:::datagen-advancements:trigger-criterion](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Il tuo criterio nuovo e luccicante è ora pronto per l'uso! Aggiungiamolo al nostro fornitore: + +@[code lang=java transcludeWith=:::datagen-advancements:custom-criteria-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Esegui l'operazione di datagen di nuovo, e avrai con te un nuovo progresso con cui giocare! + +## Condizioni con Parametri {#conditions-with-parameters} + +Tutto questo è bello e tutto, ma, e se volessimo solo concedere il progresso dopo aver fatto qualcosa 5 volte? E perché non concederne un altro dopo 10 volte? Per questo dovremo dare alla nostra condizione un parametro. Puoi attenerti a `UseToolCriterion`, o andare avanti qui con un nuovo `ParameterizedUseToolCriterion`. Nella pratica dovresti solo avere quello parametrizzato, ma li terremo entrambi per questo tutorial. + +Lavoriamo dal basso verso l'alto. Dovremo verificare se i requisiti sono soddisfatti, quindi modifichiamo il nostro metodo `Conditions#requirementsMet`: + +@[code lang=java transcludeWith=:::datagen-advancements:new-requirements-met](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +`requiredTimes` non esiste, quindi rendilo un parametro di `Conditions`: + +@[code lang=java transcludeWith=:::datagen-advancements:new-parameter](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Ora il nostro codec dà errore. Scriviamo un nuovo codec per le nuove modifiche: + +@[code lang=java transcludeWith=:::datagen-advancements:new-codec](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Andando avanti, dobbiamo ora aggiustare il nostro metodo `trigger`: + +@[code lang=java transcludeWith=:::datagen-advancements:new-trigger](@/reference/1.21/src/main/java/com/example/docs/advancement/ParameterizedUseToolCriterion.java) + +Se hai creato un nuov criterio, dobbiamo aggiungerlo a `ModCriteria` + +@[code lang=java transcludeWith=:::datagen-advancements:new-mod-criteria](@/reference/1.21/src/main/java/com/example/docs/advancement/ModCriteria.java) + +E chiamarlo nella nostra classe principale, proprio dove c'è quello vecchio: + +@[code lang=java transcludeWith=:::datagen-advancements:trigger-new-criterion](@/reference/1.21/src/main/java/com/example/docs/advancement/FabricDocsReferenceDatagenAdvancement.java) + +Aggiungi il progresso al tuo fornitore: + +@[code lang=java transcludeWith=:::datagen-advancements:new-custom-criteria-advancement](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceAdvancementProvider.java) + +Esegui nuovamente la datagen, e hai finalmente finito! diff --git a/versions/1.21/translated/it_it/develop/data-generation/loot-tables.md b/versions/1.21/translated/it_it/develop/data-generation/loot-tables.md new file mode 100644 index 000000000..cdf470740 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/data-generation/loot-tables.md @@ -0,0 +1,57 @@ +--- +title: Generazione di Loot Table +description: Una guida per configurare la generazione di loot table con datagen. +authors: + - skycatminepokie + - Spinoscythe + - Alphagamer47 + - matthewperiut + - JustinHuPrime +authors-nogithub: + - mcrafterzz + - jmanc3 +--- + +# Generazione di Loot Table {#loot-table-generation} + +:::info PREREQUISITI +Assicurati di aver prima completato il processo di [configurazione della datagen](./setup). +::: + +Ti serviranno fornitori (classi) diversi per blocchi, bauli, ed entità. Ricorda di aggiungerli tutto al tuo pack nella tua `DataGeneratorEntrypoint` nel metodo `onInitializeDataGenerator`. + +@[code lang=java transclude={32-33}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Loot Table Spiegate {#loot-tables-explained} + +Le **loot table** definiscono cosa si ottiene dalla rottura di un blocco (esclusi i contenuti, per esempio per i bauli), uccisione di un'entità, o apertura di un contenitore appena generato. Ogni loot table ha dei **pool** fra cui gli oggetti sono selezionati. Le loot table hanno anche **funzioni**, che modificano il loot risultante in qualche modo. + +Le loot pool hanno **voci**, **condizioni**, funzioni, **roll** e **roll bonus**. Le voci sono gruppi, sequenze, o possibilità di oggetti, o solo oggetti. Le condizioni sono cose per cui si testa nel mondo, come incantesimi su uno strumento o una probabilità casuale. Il numero minimo di voci scelte da una pool è detto roll, e qualsiasi cosa sopra a ciò è detta una roll bonus. + +## Blocchi {#blocks} + +Perché i blocchi droppino oggetti - inclusi se stessi - dobbiamo creare una loot table. Crea una classe che `extends FabricBlockLootTableProvider`: + +@[code lang=java transcludeWith=:::datagen-loot-tables:block-provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java) + +Assicurati di aggiungere questo fornitore al tuo pack! + +Ci sono parecchi metodi ausiliari per aiutarti a costruire le tue loot table. Non li analizzeremo, per cui assicurati di controllarli nel tuo IDE. + +Aggiungiamo alcuni drop nel metodo `generate`: + +@[code lang=java transcludeWith=:::datagen-loot-tables:block-drops](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceBlockLootTableProvider.java) + +## Bauli {#chests} + +Il loot dei bauli è un po' più complesso del loot dei blocchi. Crea una classe che `extends SimpleFabricLootTableProvider` come nell'esempio sotto **e aggiungila al tuo pack**. + +@[code lang=java transcludeWith=:::datagen-loot-tables:chest-provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java) + +Ci servirà una `RegistryKey` per la nostra loot table. Mettiamola in una nuova classe chiamata `ModLootTables`. Assicurati che sia nel tuo insieme di sorgenti `main` se usi fonti suddivise. + +@[code lang=java transcludeWith=:::datagen-loot-tables:mod-loot-tables](@/reference/1.21/src/main/java/com/example/docs/ModLootTables.java) + +Poi possiamo generare una loot table nel metodo `generate` del tuo fornitore. + +@[code lang=java transcludeWith=:::datagen-loot-tables:chest-loot](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceChestLootTableProvider.java) diff --git a/versions/1.21/translated/it_it/develop/data-generation/recipes.md b/versions/1.21/translated/it_it/develop/data-generation/recipes.md new file mode 100644 index 000000000..55a0a6cd5 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/data-generation/recipes.md @@ -0,0 +1,50 @@ +--- +title: Generazione di Ricette +description: Una guida per configurare la generazione di ricette con datagen. +authors: + - skycatminepokie + - Spinoscythe +authors-nogithub: + - mcrafterzz + - jmanc3 +--- + +# Generazione di Ricette {#recipe-generation} + +:::info PREREQUISITI +Assicurati di aver prima completato il processo di [configurazione della datagen](./setup). +::: + +## Configurazione {#setup} + +Anzitutto, ci serve il nostro fornitore. Crea una classe che `extends FabricRecipeProvider`. Tutta la nostra generazione di ricette avverrà nel metodo `generate` del nostro fornitore. + +@[code lang=java transcludeWith=:::datagen-recipes:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +Per completare la configurazione, aggiungi questo fornitore alla tua `DataGeneratorEntrypoint` nel metodo `onInitializeDataGenerator`. + +@[code lang=java transclude={30-30}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Ricette Senza Forma {#shapeless-recipes} + +Le ricette senza forma non sono complesse. Basta aggiungerle al metodo `generate` nel tuo fornitore: + +@[code lang=java transcludeWith=:::datagen-recipes:shapeless](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +## Ricette Con Forma {#shaped-recipes} + +Per una ricetta con forma, dovrai definire la forma con una `String`, poi definire ciò che ogni `char` della `String` rappresenta. + +@[code lang=java transcludeWith=:::datagen-recipes:shaped](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +:::tip +Ci sono tanti metodi ausiliari per la creazione di ricette tipiche. Controlla ciò che `RecipeProvider` ha da offrire! Usa `Alt + 7` in IntelliJ per aprire la struttura di una classe, inclusa una lista dei metodi. +::: + +## Altre Ricette {#other-recipes} + +Altre ricette funzionano in maniera simile, ma richiedono alcuni parametri aggiuntivi. Per esempio, le ricette di fusioni devono includere la quantità di esperienza da assegnare. + +@[code lang=java transcludeWith=:::datagen-recipes:other](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceRecipeProvider.java) + +## Tipi di Ricette Personalizzati {#custom-recipe-types} diff --git a/versions/1.21/translated/it_it/develop/data-generation/setup.md b/versions/1.21/translated/it_it/develop/data-generation/setup.md new file mode 100644 index 000000000..6721afd92 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/data-generation/setup.md @@ -0,0 +1,88 @@ +--- +title: Configurazione della Generazione di Dati +description: Una guida per configurare la Generazione di Dati con l'API di Fabric. +authors: + - skycatminepokie + - modmuss50 + - earthcomputer + - shnupbups + - arkosammy12 + - haykam821 + - matthewperiut + - SolidBlock-cn + - Jab125 +authors-nogithub: + - jmanc3 + - macrafterzz +--- + +# Configurazione della Generazione di Dati {#data-generation-setup} + +## Cos'è la Generazione di Dati? {#what-is-data-generation} + +La generazione di dati (datagen) è un'API per generare programmaticamente ricette, progressi, tag, modelli di oggetti, file di lingua, loot table, e praticamente qualsiasi cosa basata su JSON. + +## Attivare la Generazione di Dati {#enabling-data-generation} + +### Durante la Creazione del Progetto {#enabling-data-generation-at-project-creation} + +Il modo più semplice per attivare la datagen è durante la creazione del progetto. Attiva la casella "Enable Data Generation" mentre usi il [generatore di mod modello](https://fabricmc.net/develop/template). + +![La casella "Data Generation" attiva nel generatore di mod modello](/assets/develop/data-generation/data_generation_setup_01.png) + +:::tip +Se la datagen è attiva, dovresti avere una configurazione di esecuzione "Data Generation" e un'operazione Gradle `runDatagen`. +::: + +### Manualmente {#manually-enabling-data-generation} + +Anzitutto, dobbiamo attivare la datagen nel file `build.gradle`. + +@[code lang=groovy transcludeWith=:::datagen-setup:configure](@/reference/build.gradle) + +Poi ci serve una classe entrypoint. È qui che comincia la nostra datagen. Mettila da qualche parte nel package `client` - questo esempio la inserisce in `src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java`. + +@[code lang=java transcludeWith=:::datagen-setup:generator](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +Infine, informiamo Fabric dell'entrypoint nel nostro `fabric.mod.json`: + +```json +{ + // ... + "entrypoints": { + // ... + "client": [ + // ... + ], + "fabric-datagen": [ // [!code ++] + "com.exmaple.docs.datagen.FabricDocsReferenceDataGenerator" // [!code ++] + ] // [!code ++] + } +} +``` + +:::warning +Non dimenticare di aggiungere una virgola (`,`) dopo il blocco entrypoint precedente! +::: + +Chiudi e riapri IntelliJ per creare una configurazione di esecuzione per la datagen. + +## Creare un Pack {#creating-a-pack} + +Nel metodo `onInitializeDataGenerator` del tuo entrypoint di datagen, dobbiamo creare un `Pack`. Dopo aggiungerai dei **fornitori**, che metteranno i dati generati in questo `Pack`. + +@[code lang=java transcludeWith=:::datagen-setup:pack](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Eseguire la Generazione di Dati {#running-data-generation} + +Per eseguire la datagen, usa la configurazione di esecuzione nel tuo IDE, o esegui `./gradlew runDatagen` nella console. I file generati saranno creati in `src/main/generated`. + +## Prossimi Passi {#next-steps} + +Ora che la datagen è configurata, dobbiamo aggiungerle dei **fornitori**. Questi sono ciò che genera i dati da aggiungere al tuo `Pack`. Le pagine successive mostrano come si fa questo. + +- [Progressi](./advancements) +- [Loot Table](./loot-tables) +- [Ricette](./recipes) +- [Tag](./tags) +- [Traduzioni](./translations) diff --git a/versions/1.21/translated/it_it/develop/data-generation/tags.md b/versions/1.21/translated/it_it/develop/data-generation/tags.md new file mode 100644 index 000000000..5dda48f48 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/data-generation/tags.md @@ -0,0 +1,44 @@ +--- +title: Generazione di Tag +description: Una guida per configurare la generazione di tag con datagen. +authors: + - skycatminepokie + - IMB11 + - Spinoscythe +authors-nogithub: + - mcrafterzz +--- + +# Generazione di Tag {#tag-generation} + +:::info PREREQUISITI +Assicurati di aver prima completato il processo di [configurazione della datagen](./setup). +::: + +## Configurazione {#setup} + +Anzitutto, crea la tua classe che `extends FabricTagProvider`, dove `T` è il tipo di cosa per la quale vuoi fornire un tag. Questo è il tuo **fornitore**. Qui mostreremo come creare tag di `Item`, ma lo stesso principio si applica ad altre cose. Lascia che il tuo IDE compili il codice richiesto, poi sostituisci il parametro `registryKey` del costruttore con la `RegistryKey` per il tuo tipo: + +@[code lang=java transcludeWith=:::datagen-tags:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) + +:::info NOTA +Ti servirà un fornitore diverso per ogni tipo di tag (per esempio un `FabricTagProvider>` e un `FabricTagProvider`). +::: + +Per completare la configurazione, aggiungi questo fornitore alla tua `DataGeneratorEntrypoint` nel metodo `onInitializeDataGenerator`. + +@[code lang=java transclude={28-28}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Creare un Tag {#creating-a-tag} + +Ora che hai creato un fornitore, aggiungiamoci un tag. Anzitutto, crea una `TagKey`: + +@[code lang=java transcludeWith=:::datagen-tags:tag-key](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) + +Poi, chiama `getOrCreateTagBuilder` nel metodo `configure` del tuo fornitore. Da lì, puoi aggiungere oggetti individualmente, aggiungere altri tag, o fare in modo che questo tag ne sostituisca di preesistenti. + +Se vuoi aggiungere un tag, usa `addOptionalTag`, poiché i contenuti del tag potrebbero non essere caricati durante la datagen. Se sei sicuro che il tag sia caricato, chiama `addTag`. + +Per aggiungere un tag forzatamente ignorando il formato errato, usa `forceAddTag`. + +@[code lang=java transcludeWith=:::datagen-tags:build](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceItemTagProvider.java) diff --git a/versions/1.21/translated/it_it/develop/data-generation/translations.md b/versions/1.21/translated/it_it/develop/data-generation/translations.md new file mode 100644 index 000000000..e996cb052 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/data-generation/translations.md @@ -0,0 +1,49 @@ +--- +title: Generazione di Traduzioni +description: Una guida per configurare la generazione di traduzioni con datagen. +authors: + - skycatminepokie + - MattiDragon + - IMB11 + - Spinoscythe +authors-nogithub: + - sjk1949 + - mcrafterzz + - jmanc3 +--- + +# Generazione di Traduzioni {#translation-generation} + +:::info PREREQUISITI +Assicurati di aver prima completato il processo di [configurazione della datagen](./setup). +::: + +## Configurazione {#setup} + +Anzitutto, creeremo il nostro **fornitore**. Ricorda: i fornitori sono ciò che ci genera effettivamente i dati. Crea una classe che `extends FabricLanguageProvider` e compilane i metodi di base: + +@[code lang=java transcludeWith=:::datagen-translations:provider](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) + +:::info NOTA +Ti servirà un fornitore diverso per ogni lingua che vorrai generare (per esempio un `ExampleEnglishLangProvider` e un `ExamplePirateLangProvider`). +::: + +Per completare la configurazione, aggiungi questo fornitore alla tua `DataGeneratorEntrypoint` nel metodo `onInitializeDataGenerator`. + +@[code lang=java transclude={26-26}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +## Creare Traduzioni {#creating-translations} + +Oltre a creare traduzioni crude, traduzioni da `Identifier`, e copiarli da un altro file esistente (passando un `Path`), ci sono metodi ausiliari per tradurre oggetti, blocchi, tag, statistiche, entità, effetti di stato, gruppi di oggetti, attributi di entità, e incantesimi. Basta chiamare `add` sul `translationBuilder` con ciò che vuoi tradurre e ciò a cui dovrebbe essere tradotto: + +@[code lang=java transcludeWith=:::datagen-translations:build](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceEnglishLangProvider.java) + +## Usare le Traduzioni {#using-translations} + +Le traduzioni generate prendono il posto di molte traduzioni aggiunte in altri tutorial, ma puoi anche usare ovunque dove usi un oggetto `Text`. Nel nostro esempio, se volessimo permettere ai pacchetti risorse di tradurre il nostro saluto, usiamo `Text.translatable` invece di `Text.of`: + +```java +ChatHud chatHud = MinecraftClient.getInstance().inGameHud.getChatHud(); +chatHud.addMessage(Text.literal("Hello there!")); // [!code --] +chatHud.addMessage(Text.translatable("text.fabric_docs_reference.greeting")); // [!code ++] +``` diff --git a/versions/1.21/translated/it_it/develop/entities/damage-types.md b/versions/1.21/translated/it_it/develop/entities/damage-types.md new file mode 100644 index 000000000..13f61df90 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/entities/damage-types.md @@ -0,0 +1,96 @@ +--- +title: Tipi di Danno +description: Impara come aggiungere tipi di danno personalizzati. +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# Tipi di Danno {#damage-types} + +I tipi di danno definiscono tipi di danno che le entità possono subire. A partire da Minecraft 1.19.4, la creazione di nuovi tipi di danno è basata sui dati, per cui essi sono creati tramite file JSON. + +## Creare un Tipo di Danno {#creating-a-damage-type} + +Creiamo un tipo di danno personalizzato chiamato _Tater_. Inizieremo creando un file JSON per il tuo danno personalizzato. Il file sarà posizionato nella cartella `data` della tua mod, in una sottocartella chiamata `damage_type`. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +Ha la struttura seguente: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +Questo tipo di danno personalizzato causa un aumento di 0.1 nel livello di esaurimento ([exhaustion level](https://minecraft.wiki/w/Hunger#Exhaustion_level_increase)) ogni volta che il giocatore prende danno, quando il danno è causato da una fonte vivente che non sia un giocatore (per esempio un blocco). Inoltre, la quantità di danno subita cambierà a seconda della difficoltà del mondo + +::: info + +Affidati alla [Minecraft Wiki](https://minecraft.wiki/w/Damage_type#JSON_format) per tutte le possibili chiavi e valori. + +::: + +### Accedere ai Tipi di Danno Tramite Codice {#accessing-damage-types-through-code} + +Quando abbiamo bisogno di accedere al nostro tipo di danno personalizzato tramite codice, useremo la sua `RegistryKey` per costruire un'istanza di `DamageSource`. + +La `RegistryKey` può essere ottenuta nel modo seguente: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### Usare i Tipi di Danno {#using-damage-types} + +Per mostrare l'uso dei tipi di danno personalizzati, useremo un blocco personalizzato chiamato _Blocco di Tater_. Facciamo in modo che quando un'entità calpesta un _Blocco di Tater_, esso causa danno _Tater_. + +Puoi fare override di `onSteppedOn` per infliggere questo danno. + +Cominciamo creando una `DamageSource` del nostro tipo di danno personalizzato. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Poi, chiamiamo `entity.damage()` con la nostra `DamageSource` e con una quantità. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +L'intera implementazione del blocco: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Ora quando un'entità vivente calpesta il nostro blocco personalizzato, subirà 5 di danno (2.5 cuori) usando il nostro tipo di danno personalizzato. + +### Messaggio di Morte Personalizzato {#custom-death-message} + +Puoi definire un messaggio di morte per il tipo di danno nel formato `death.attack.` nel file `en_us.json` della nostra mod. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +Al momento della morte dal nostro tipo di danno personalizzato, vedrete il messaggio di morte seguente: + +![Effetto nell'inventario del giocatore](/assets/develop/tater-damage-death.png) + +### Tag dei Tipi di Danno {#damage-type-tags} + +Alcuni tipi di danno possono bypassare armatura, bypassare effetti di stato, o simili. I tag sono usati per controllare questo genere di proprietà dei tipi di danno. + +Puoi trovare tipi di danno già esistenti in `data/minecraft/tags/damage_type`. + +::: info + +Affidati alla [Minecraft Wiki](https://minecraft.wiki/w/Tag#Damage_types) per una lista completa dei tag dei tipi di danno. + +::: + +Aggiungiamo il nostro tipo di danno Tater al tag `bypasses_armor` dei tipi di danno. + +Per aggiungere il nostro tipo di danno a uno di questi tag, creeremo un file JSON nel namespace `minecraft`. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +Con il contenuto seguente: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +Assicurati che il tuo tag non sostituisca il tag esistente impostando la chiave `replace` a `false`. diff --git a/versions/1.21/translated/it_it/develop/entities/effects.md b/versions/1.21/translated/it_it/develop/entities/effects.md new file mode 100644 index 000000000..8915641d5 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/entities/effects.md @@ -0,0 +1,87 @@ +--- +title: Effetti di Stato +description: Impara come aggiungere effetti di stato personalizzati. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil + - Manchick0 +authors-nogithub: + - siglong + - tao0lu +--- + +# Effetti di Stato {#status-effects} + +Gli effetti di stato, anche noti come effetti, sono una condizione che interessa un'entità. Possono essere positivi, negativi o neutrali in natura. Il gioco base applica questi effetti in vari modi, come cibi, pozioni ecc. + +Il comando `/effect` può essere usato per applicare effetti su un'entità. + +## Effetti di Stato Personalizzati {#custom-status-effects} + +In questo tutorial aggiungeremo un nuovo effetto personalizzato chiamato _Tater_ che ti darà un punto esperienza in ogni tick di gioco. + +### Estendere `StatusEffect` {#extend-statuseffect} + +Creiamo una classe per il nostro effetto personalizzato estendendo `StatusEffect`, che è la classe base per tutti gli effetti. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### Registrare il tuo Effetto Personalizzato {#registering-your-custom-effect} + +Come nella registrazione di blocchi e oggetti, usiamo `Registry.register` per registrare i nostri effetti personalizzati nella registry `STATUS_EFFECT`. Questo può essere fatto nel nostro initializer. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### Texture {#texture} + +L'icona dell'effetto è un PNG 18x18. Posiziona la tua icona personalizzata in: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + +Texture di Esempio + +### Traduzioni {#translations} + +Come ogni altra traduzione, puoi aggiungere una voce con formato ID `"effect..": "Valore"` al file di lingua. + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### Applicare l'Effetto {#applying-the-effect} + +Vale la pena di dare un'occhiata a come si aggiunge solitamente un effetto ad un'entità. + +::: tip +For a quick test, it might be a better idea to use the previously mentioned `/effect` command: + +```mcfunction +effect give @p fabric-docs-reference:tater +``` + +::: + +Per applicare un effetto internamente, vorrai usare il metodo `LivingEntity#addStatusEffect`, che prende una `StatusEffectInstance`, e restituisce un booleano, che indica se l'effetto è stato applicato con successo. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java) + +| Argomento | Tipo | Descrizione | +| ----------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `effect` | `RegistryEntry` | Una voce di registry che rappresenta l'effetto. | +| `duration` | `int` | La durata dell'effetto **in tick**; **non** in secondi | +| `amplifier` | `int` | L'amplificatore al livello dell'effetto. Non corrisponde al **livello** dell'effetto, ma è invece aggiunto al di sopra. Per cui un `amplifier` di `4` => livello `5` | +| `ambient` | `boolean` | Questo è un po' complesso. In pratica indica che l'effetto è stato aggiunto dall'ambiente (per esempio un **Faro**) e non ha una causa diretta. Se `true`, l'icona dell'effetto nel HUD avrà un overlay color ciano. | +| `particles` | `boolean` | Se si mostrano le particelle. | +| `icon` | `boolean` | Se si mostra un'icona dell'effetto nel HUD. L'effetto sarà mostrato nell'inventario indipendentemente da questo valore. | + +:::info +::: info +Per creare una pozione che usa questo effetto, per favore vedi la guida [Pozioni](../items/potions). +::: diff --git a/versions/1.21/translated/it_it/develop/events.md b/versions/1.21/translated/it_it/develop/events.md new file mode 100644 index 000000000..2f1a768cd --- /dev/null +++ b/versions/1.21/translated/it_it/develop/events.md @@ -0,0 +1,122 @@ +--- +title: Eventi +description: Una guida all'uso degli eventi forniti dall'API di Fabric. +authors: + - dicedpixels + - mkpoli + - daomephsta + - solidblock + - draylar + - jamieswhiteshirt + - PhoenixVX + - Juuxel + - YanisBft + - liach + - natanfudge +authors-nogithub: + - stormyfabric +--- + +# Eventi {#events} + +L'API di Fabric fornisce un sistema che permette alle mod di reagire ad azioni o circostanze, anche dette _eventi_ che accadono nel gioco. + +Gli eventi sono agganci che soddisfano usi comuni e/o permettono compatibilità e prestazioni migliori tra mod diverse che si agganciano alle stesse aree del codice. L'uso degli eventi spesso sostituisce l'uso dei mixin. + +L'API di Fabric fornisce eventi per aree importanti nel codice base di Minecraft ai quali molti modder potrebbero voler agganciarsi. + +Gli eventi sono rappresentati da istanze di `net.fabricmc.fabric.api.event.Event` che memorizza e chiama i _callback_. Spesso c'è una singola istanza di un evento per un callback, che è conservata in un attributo statico `EVENT` dell'interfaccia callback, ma ci sono anche altre organizzazioni. Per esempio, `ClientTickEvents` raggruppa vari eventi legati insieme. + +## Callback {#callbacks} + +I callback sono una parte di codice che viene passata come argomento a un evento. Quando l'evento viene innescato dal gioco, il pezzo di codice passato viene eseguito. + +### Interfacce di Callback {#callback-interfaces} + +A ogni evento corrisponde un'interfaccia di callback, convenzionalmente chiamata `Callback`. I callback sono registrati chiamando il metodo `register()` su un'istanza di un evento, con un'istanza dell'interfaccia callback come argomento. + +Tutti le interfacce callback degli eventi fornite dall'API di Fabric possono essere trovate nel package `net.fabricmc.fabric.api.event`. + +## Ascoltare gli Eventi {#listening-to-events} + +Questo esempio registra un `AttackBlockCallback` per danneggiare il giocatore quando egli colpisce dei blocchi che non droppano un oggetto se rotti senza strumenti. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +### Aggiungere Oggetti alle Loot Table Esistenti {#adding-items-to-existing-loot-tables} + +A volte potresti voler aggiungere oggetti alle loot table. Per esempio, fare in modo che un blocco o un'entità vanilla droppi un tuo oggetto. + +La soluzione più semplice, sostituire il file della loot table, può rompere altre mod. E se volessero cambiarli anche loro? Daremo un'occhiata a come puoi aggiungere oggetti alle loot table senza sovrascriverle. + +Aggiungeremo le uova alla loot table del minerale di carbone. + +#### Ascoltare il Caricamento delle Loot Table {#listening-to-loot-table-loading} + +L'API di Fabric ha un evento che si attiva quando le loot table sono caricate, `LootTableEvents.MODIFY`. Puoi registrare un callback per quell'evento nell'[initializer della tua mod](./getting-started/project-structure#entrypoints). Controlliamo anche che la loot table corrente sia quella del minerale di carbone. + +@[code lang=java transclude={38-40}](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +#### Aggiungere Oggetti alla Loot Table {#adding-items-to-the-loot-table} + +Nelle loot table, gli oggetti sono memorizzati come _loot pool entries_, e le voci sono memorizzate in _loot pools_. Per aggiungere un oggetto, dovremo aggiungere una pool con una voce oggetto alla loot table. + +Possiamo creare una pool con `LootPool#builder`, e aggiungerla alla loot table. + +La nostra pool non ha nemmeno un oggetto, quindi dovremo creare una voce oggetto usando `ItemEntry#builder` e aggiungerla alla pool. + +@[code highlight={6-7} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +## Eventi Personalizzati {#custom-events} + +Alcune aree del gioco non hanno agganci forniti dall'API di Fabric, quindi dovrai usare un mixin o creare il tuo evento personalizzato. + +Vedremo come creare un evento che viene innescato quando una pecora viene tosata. Il processo per la creazione di un evento è: + +- Creare l'interfaccia callback dell'evento +- Innescare l'evento da un mixin +- Creare un'implementazione di prova + +### Creare l'Interfaccia Callback dell'Evento {#creating-the-event-callback-interface} + +L'interfaccia callback descrive cosa deve essere implementato dai listener di eventi che ascolteranno il tuo evento. L'interfaccia callback descrive anche come l'evento verrà chiamato dal tuo mixin. È convenzione posizionare un oggetto `Event` come attributo nell'interfaccia callback, che identificherà effettivamente il nostro evento. + +Per la nostra implementazione di `Event`, sceglieremo di usare un evento basato su un vettore. Il vettore conterrà tutti i listener agli eventi che stanno ascoltando l'evento. + +La nostra implementazione chiamerà i listener di eventi in ordine finché uno di essi non restituisce `ActionResult.PASS`. Questo significa che con il valore restituito un listener può dire "_annulla questo_", "_approva questo_" o "_non m'interessa, lascialo al prossimo listener_". + +Usare `ActionResult` come valore restituito è una convenzione per far cooperare i gestori di eventi in questa maniera. + +Dovrai creare un'interfaccia che ha un'istanza `Event` e un metodo per implementare la risposta. Una semplice configurazione per il nostro callback di tosatura di una pecora è: + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Diamogli un'occhiata più precisa. Quando l'invocatore viene chiamato, iteriamo su tutti i listener: + +@[code lang=java transclude={21-22}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Poi chiamiamo il nostro metodo (in questo caso, `interact`) sul listener per ottenere la sua risposta: + +@[code lang=java transclude={33-33}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Se il listener dice che dobbiamo annullare (`ActionResult.FAIL`), oppure finire completamente (`ActionResult.SUCCESS`), il callback restituisce il risultato e finisce il loop. `ActionResult.PASS` si sposta sul prossimo listener, e nella maggior parte dei casi dovrebbe risultare in un successo se non ci sono altri listener registrati: + +@[code lang=java transclude={25-30}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Possiamo aggiungere commenti Javadoc in cima alle classi di callback per documentare cosa fa ogni `ActionResult`. Nel nostro caso, potrebbe essere: + +@[code lang=java transclude={9-16}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +### Innescare l'Evento da un Mixin {#triggering-the-event-from-a-mixin} + +Ora abbiamo lo scheletro di base dell'evento, ma dobbiamo anche innescarlo. Siccome vogliamo che l'evento venga chiamato quando un giocatore prova a tosare una pecora, chiamiamo l'`invoker` dell'evento in `SheepEntity#interactMob` quando `sheared()` viene chiamata (ovvero quando la pecora può essere tosata, e il giocatore sta tenendo delle cesoie): + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java) + +### Creare un Implementazione di Prova {#creating-a-test-implementation} + +Ora dobbiamo testare il nostro evento. Puoi registrare un listener nel tuo metodo d'inizializzazione (o in un'altra area, se preferisci) e aggiungere logica personalizzata lì. Qui c'è un esempio che droppa un diamante anziché lana ai piedi della pecora: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +Se entri nel gioco e tosi una pecora, un diamante dovrebbe essere droppato anziché lana. diff --git a/versions/1.21/translated/it_it/develop/getting-started/creating-a-project.md b/versions/1.21/translated/it_it/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..fbeae4782 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/getting-started/creating-a-project.md @@ -0,0 +1,71 @@ +--- +title: Creare un Progetto +description: Una guida passo per passo su come creare un nuovo progetto per una mod con il generatore di mod modello di Fabric. +authors: + - IMB11 + - Cactooz +--- + +# Creare un Progetto {#creating-a-project} + +Fabric offre un modo facile per creare un nuovo progetto per una mod attraverso il Generatore di Mod Modello di Fabric - se vuoi, puoi creare un nuovo progetto manualmente usando la repository della mod esempio, dovresti riferirti alla sezione [Creazione Manuale del Progetto](#creazione-manuale-del-progetto). + +## Generare un Progetto {#generating-a-project} + +Puoi usare il [Generatore di Mod Modello di Fabric](https://fabricmc.net/develop/template/) per generare un nuovo progetto per la tua mod - dovresti compilare i campi richiesti, come il nome della mod, quello del package, e la versione di Minecraft per la quale vuoi sviluppare. + +Il nome del package dovrebbe essere minuscolo, separato da punti, e unico per evitare conflitti con package di altri programmatori. Di solito viene formattato come un domain internet invertito, per esempio `com.example.modid`. + +![Anteprima del generatore](/assets/develop/getting-started/template-generator.png) + +Se avessi intenzione di usare Kotlin, usare i mapping ufficiali di Mojang invece dei mapping di Yarn, o volessi aggiungere generatori di dati, puoi selezionare le opzioni appropriate nella sezione `Advanced Options`. + +![Sezione Opzioni Avanzate](/assets/develop/getting-started/template-generator-advanced.png) + +Una volta che hai compilato i campi richiesti, premi il pulsante `Generate`, e il generatore creerà un nuovo progetto per te sotto forma di file zip. + +Dovresti estrarre questo file zip a una posizione che scegli tu, e poi aprire la cartella estratta in IntelliJ IDEA: + +![Prompt Apri Progetto](/assets/develop/getting-started/open-project.png) + +## Importare il Progetto {#importing-the-project} + +Non appena hai aperto il progetto in IntelliJ IDEA, l'ambiente di sviluppo dovrebbe automaticamente caricare la configurazione Gradle del progetto ed effettuare le operazioni di setup necessarie. + +Se ricevi una notifica riguardo a uno script di build Gradle, dovresti cliccare il pulsante `Importa Progetto Gradle`: + +![Prompt di Gradle](/assets/develop/getting-started/gradle-prompt.png) + +Quando il progetto sarà importato, dovresti vedere i file del progetto nell'explorer di progetto, e dovresti poter cominciare a sviluppare la tua mod. + +## Creazione Manuale del Progetto {#manual-project-creation} + +:::warning +Ti servirà che [Git](https://git-scm.com/) sia installato per clonare la repository della mod esempio. +::: + +Se non puoi usare il Generatore di Mod Modello di Fabric, dovresti creare un nuovo progetto manualmente seguendo questi passaggi. + +Anzitutto, clona la repository della mod esempio tramite Git: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ mio-progetto-mod +``` + +Questo clonerà la repository in una nuova cartella chiamata `mio-progetto-mod`. + +Dovresti poi eliminare la cartella `.git` dalla repository clonata, e poi aprire il progetto in IntelliJ IDEA. Se la cartella `.git` dovesse non apparire, dovresti attivare la visualizzazione dei file nascosti nel tuo gestore file. + +Quando avrai aperto il progetto in IntelliJ IDEA, esso dovrebbe automaticamente caricare la configurazione Gradle del progetto ed effettuare le operazioni di setup necessarie. + +Di nuovo, come già detto in precedenza, se ricevi una notifica riguardo a uno script di build Gradle, dovresti cliccare il pulsante `Importa Progetto Gradle`. + +### Modificare il Template {#modifying-the-template} + +Una volta che il progetto sarà importato, dovresti modificare i dettagli del progetto per corrispondere a quelli della tua mod: + +- Modifica il file `gradle.properties` del tuo progetto per cambiare le proprietà `maven_group` e `archive_base_name` e farle corrispondere con i dettagli della tua mod. +- Modifica il file `fabric.mod.json` per cambiare le proprietà `id`, `name`, e `descrizione` per farle corrispondere ai dettagli della tua mod. +- Assicurati di aggiornare le versioni di Minecraft, i mapping, il Loader e il Loom - tutte queste possono essere trovate attraverso - per farle corrispondere alle versioni che vorresti prendere di mira. + +Ovviamente puoi cambiare il nome del package e la classe principale della mod per farli corrispondere ai dettagli della tua mod. diff --git a/versions/1.21/translated/it_it/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/it_it/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..833205307 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Introduzione a Fabric e al Modding +description: "Una breve introduzione a Fabric e al modding in Minecraft: Java Edition." +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Introduzione a Fabric e al Modding {#introduction-to-fabric-and-modding} + +## Prerequisiti {#prerequisites} + +Prima d'iniziare, dovresti avere una comprensione basilare dello sviluppo con Java, e una comprensione della Programmazione Orientata agli Oggetti (OOP). + +Se questi concetti non ti sono familiari, potresti voler cercare qualche tutorial su Java e sulla OOP prima di cominciare a fare modding, ecco alcune risorse (in inglese) che puoi usare per imparare Java e OOP: + +- [W3: Java Tutorials](https://www.w3schools.com/java/) +- [Codecademy: Learn Java](https://www.codecademy.com/learn/learn-java) +- [W3: Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium: Introduction to OOP](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### Terminologia {#terminology} + +Prima di cominciare, chiariamo alcuni termini che incontrerai nel moddare con Fabric: + +- **Mod**: Una modifica al gioco, che aggiunge nuove funzionalità oppure ne modifica di esistenti. +- **Loader di Mod**: Uno strumento che carica le mod nel gioco, per esempio il Loader di Fabric. +- **Mixin**: Uno strumento per modificare il codice del gioco al runtime - vedi [Mixin Introduction](https://fabricmc.net/wiki/tutorial:mixin_introduction) per maggiori informazioni. +- **Gradle**: Uno strumento per l'automatizzazione del build usato per costruire e compilare mod, usato da Fabric per costruire le mod. +- **Mapping**: Un insieme di mapping che mappano codice offuscato a codice leggibile. +- **Offuscamento**: Il processo di rendere il codice difficile da comprendere, usato da Mojang per proteggere il codice di Minecraft. +- **Remapping**: Il processo di rimappare codice offuscato a codice leggibile. + +## Cos'è Fabric? {#what-is-fabric} + +Fabric è una toolchain di modding leggera per Minecraft: Java Edition. + +È progettato per essere una piattaforma per modding semplice e facile da usare. Fabric è un progetto guidato dalla comunità, ed è open-source, per cui chiunque può contribuire al progetto. + +Dovresti conoscere le quattro componenti principali di Fabric: + +- **Loader di Fabric**: Un loader di mod flessibile indipendente dalla piattaforma progettato per Minecraft e per altri giochi e applicazioni. +- **Loom di Fabric**: Un plugin Gradle che permette agli sviluppatori di sviluppare ed effettuare debug delle mod facilmente. +- **API di Fabric**: Un insieme di API e di strumenti per sviluppatori di mod da usare quando si creano mod. +- **Yarn**: Un insieme di mapping Minecraft aperti, gratuiti per tutti da usare sotto la licenza Creative Commons Zero. + +## Perché È Necessario Fabric per Moddare Minecraft? {#why-is-fabric-necessary-to-mod-minecraft} + +> Il modding è il processo di modifica del gioco per cambiarne il comportamento o per aggiungere nuove funzionalità - nel caso di Minecraft, questo può essere qualsiasi cosa dall'aggiungere nuovi oggetti, blocchi, o entità, al cambiare le meccaniche del gioco o aggiungere nuove modalità di gioco. + +Minecraft: Java Edition è offuscato da Mojang, il che rende la pura modifica difficile. Tuttavia, aiutandosi con strumenti di modding come Fabric, il modding diventa molto più facile. Ci sono vari sistemi di mapping che possono aiutare in questo processo. + +Loom rimappa il codice offuscato a un formato leggibile usando questi mapping, rendendo la comprensione e la modifica del codice del gioco più semplice per i modder. Yarn è una scelta popolare ed eccellente di mapping per questo, ma esistono anche altre opzioni. Ogni progetto di mapping potrebbe avere il suo punto forte o la sua focalizzazione. + +Loom ti permette di sviluppare e compilare mod facilmente in riferimento a codice rimappato, e il Loader di Fabric ti permette di caricare queste mod nel gioco. + +## Cosa Fornisce l'API di Fabric, e Perché È Necessaria? {#what-does-fabric-api-provide-and-why-is-it-needed} + +> L'API di Fabric è un insieme di API e di strumenti per sviluppatori di mod da usare quando si creano mod. + +L'API di Fabric fornisce un largo insieme di API che espandono le funzionalità esistenti di Minecraft - per esempio, fornendo nuovi hook ed eventi che i modder possono usare, o fornendo nuove utilità e strumenti per rendere il modding più facile - come access widener transitivi e la possibilità di accedere a registry interne, come la registry di oggetti compostabili. + +Anche se l'API di Fabric offre funzionalità potenti, alcune operazioni, come la registrazione basilare di blocchi, possono essere effettuate senza di essa usando le API vanilla. diff --git a/versions/1.21/translated/it_it/develop/getting-started/launching-the-game.md b/versions/1.21/translated/it_it/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..0f798f1a5 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/getting-started/launching-the-game.md @@ -0,0 +1,72 @@ +--- +title: Avviare il Gioco +description: Impara come usare i vari profili d'avvio per avviare ed effettuare debug delle tue mod in un ambiente di gioco dal vivo. +authors: + - IMB11 + - Tenneb22 +--- + +# Avviare il Gioco {#launching-the-game} + +Loom di Fabric fornisce una varietà di profili d'avvio che ti aiutano ad avviare ed effettuare debug delle tue mod in un ambiente di gioco live. Questa guida tratterà dei vari profili d'avvio e di come usarli per effettuare debug e per testare le tue mod nel gioco. + +## Profili d'Avvio {#launch-profiles} + +Se stai usando IntelliJ IDEA, puoi trovare i profili d'avvio nell'angolo in alto a destra della finestra. Clicca sul menu a tendina per vedere i profili d'avvio disponibili. + +Dovrebbe esserci un profilo client e uno server, con l'opzione di eseguire normalmente o in modalità debug: + +![Profili d'Avvio](/assets/develop/getting-started/launch-profiles.png) + +## Operazioni Gradle {#gradle-tasks} + +Se stai usando la linea di comando, puoi usare i comandi Gradle seguenti per avviare il gioco: + +- `./gradlew runClient` - Avvia il gioco in modalità client. +- `./gradlew runServer` - Avvia il gioco in modalità server. + +L'unico problema con questo approccio è che non puoi facilmente effettuare il debug del tuo codice. Se vuoi effettuare debug del tuo codice, avrai bisogno di usare i profili d'avvio in IntelliJ IDEA o tramite l'integrazione Gradle del tuo IDE. + +## Hotswapping delle Classi {#hotswapping-classes} + +Quando esegui il gioco in modalità debug, puoi fare hotswap ("scambio a caldo") delle tue classe senza riavviare il gioco. Questo è utile per testare cambiamenti al tuo codice velocemente. + +Tuttavia ci sono alcune limitazioni: + +- Non puoi aggiungere né rimuovere metodi +- Non puoi cambiare i parametri dei metodi +- Non puoi aggiungere né togliere attributi + +Tuttavia, usando il [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime), puoi raggirare la maggior parte dei limiti, e addirittura aggiungere o togliere classi e metodi. Questo dovrebbe permettere alla maggior parte delle modifiche di essere applicate senza riavviare il gioco. + +Non dimenticare di aggiungere ciò che segue all'opzione Argomenti VM nella tua configurazione d'avvio di Minecraft: + +```:no-line-numbers +-XX:+AllowEnhancedClassRedefinition +``` + +## Hotswapping dei Mixin {#hotswapping-mixins} + +Se stai usando i Mixin, puoi fare hotswap delle tue classi Mixin senza riavviare il gioco. Questo è utile per testare cambiamenti ai tuoi Mixin velocemente. + +Avrai bisogno d'installare l'agent Java Mixin perché questo funzioni. + +### 1. Trova il Jar della Libreria Mixin {#1-locate-the-mixin-library-jar} + +In IntelliJ IDEA, puoi trovare il jar della libreria Mixin nella sezione "Librerie Esterne" della sezione "Progetto": + +![Libreria Mixin](/assets/develop/getting-started/mixin-library.png) + +Dovrai copiare il "Percorso Assoluto" del jar per il prossimo passaggio. + +### 2. Aggiungi l'argomento VM `-javaagent` {#2-add-the--javaagent-vm-argument} + +Nella tua configurazione di avvio "Client Minecraft " e/o "Server Minecraft", aggiungi ciò che segue all'opzione Argomenti VM: + +```:no-line-numbers +-javaagent:"percorso al jar della libreria mixin qui" +``` + +![Screenshot di Argomenti VM](/assets/develop/getting-started/vm-arguments.png) + +Ora, dovresti poter modificare i contenuti dei tuoi metodi mixin durante il debugging e vedere gli effetti delle modifiche senza riavviare il gioco. diff --git a/versions/1.21/translated/it_it/develop/getting-started/project-structure.md b/versions/1.21/translated/it_it/develop/getting-started/project-structure.md new file mode 100644 index 000000000..9df71f63e --- /dev/null +++ b/versions/1.21/translated/it_it/develop/getting-started/project-structure.md @@ -0,0 +1,64 @@ +--- +title: Struttura del Progetto +description: Una panoramica sulla struttura di un progetto per una mod Fabric. +authors: + - IMB11 +--- + +# Struttura del Progetto {#project-structure} + +Questa pagina analizzerà la struttura di un progetto per una mod Fabric, e l'utilità di ogni file e cartella nel progetto. + +## `fabric.mod.json` {#fabric-mod-json} + +Il file `fabric.mod.json` è il file principale che descrive la tua mod al Loader di Fabric. Contiene informazioni come l'ID della mod, la versione, e le dipendenze. + +Gli attributi più importanti nel file `fabric.mod.json` sono: + +- `id`: L'ID della mod, che dovrebbe essere unico. +- `name`: Il nome della mod. +- `environment`: L'ambiente in cui la tua mod viene eseguita, come `client`, `server`, o `*` per entrambi. +- `entrypoints`: Gli entrypoint che la tua mod fornisce, come `main` o `client`. +- `depends`: Le mod da cui la tua mod dipende. +- `mixins`: I mixin che la tua mod fornisce. + +Puoi trovare un esempio del file `fabric.mod.json` sotto - questo è il file `fabric.mod.json` per il progetto di riferimento su cui è basato questo sito di documentazione. + +:::details `fabric.mod.json` del Progetto di Riferimento +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## Entrypoint {#entrypoints} + +Come detto in precedenza, il file `fabric.mod.json` contiene un attributo `entrypoints` - questo attributo è usato per specificare gli entrypoint che la tua mod fornisce. + +Il generatore di mod modello crea sia un entrypoint `main` che `client` predefiniti: + +- L'entrypoint `main` è usato per codice comune, ed è contenuto in una classe che implementi `ModInitializer` +- L'entrypoint `client` è usato per codice esclusivo del client, e la sua classe implementa `ClientModInitializer` + +Questi entrypoint vengono chiamati rispettivamente quando il gioco viene avviato. + +Ecco un esempio di un entrypoint `main` molto semplice che logga un messaggio alla console quando si avvia il gioco: + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +## `src/main/resources` {#src-main-resources} + +Nella cartella `src/main/resources` si memorizzano le risorse che la tua mod usa, come texture, modelli, e suoni. + +È anche la posizione di `fabric.mod.json` e di qualsiasi file di configurazione mixin che la tua mod usa. + +Le risorse sono memorizzate in una struttura che rispecchia la struttura dei pacchetti risorse - per esempio, una texture per un blocco verrebbe memorizzata in `assets/modid/textures/block/block.png`. + +## `src/client/resources` {#src-client-resources} + +Nella cartella `src/client/resources` si memorizzano risorse client specifiche, come texture, modelli, e suoni che sono solo usati dal lato client. + +## `src/main/java` {#src-main-java} + +La cartella `src/main/java` viene usata per memorizzare il codice sorgente Java per la tua mod - esiste sia su ambienti client sia server. + +## `src/client/java` {#src-client-java} + +La cartella `src/client/java` viene usata per memorizzare codice sorgente Java client specifico, come codice per il rendering o logica del lato client - come provider per il colore dei blocchi. diff --git a/versions/1.21/translated/it_it/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/it_it/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..896095fcf --- /dev/null +++ b/versions/1.21/translated/it_it/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: Impostare un Ambiente di Sviluppo +description: Una guida passo per passo su come impostare un ambiente di sviluppo per creare mod usando Fabric. +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# Impostare un Ambiente di Sviluppo {#setting-up-a-development-environment} + +Per iniziare a sviluppare mod con Fabric, avrai bisogno d'impostare un ambiente di sviluppo usando IntelliJ IDEA. + +## Installare JDK 21 {#installing-jdk-21} + +Per sviluppare mod per Minecraft 1.21, avrai bisogno del JDK 21. + +Se ti serve aiuto nell'installare Java, puoi fare riferimento alle varie guide per installazione di Java nella [sezione guide per il giocatore](../../players/index). + +## Installare IntelliJ IDEA {#installing-intellij-idea} + +:::info +Ovviamente puoi usare altri IDE, come Eclipse o Visual Studio Code, ma la maggior parte delle pagine su questo sito di documentazione supporrà che stai usando IntelliJ IDEA - dovresti fare riferimento alla documentazione del tuo IDE se ne stai usando un altro. +::: + +Se non hai IntelliJ IDEA installato, puoi scaricarlo dal [sito ufficiale](https://www.jetbrains.com/idea/download/) - segui i passaggi per l'installazione sul tuo sistema operativo. + +L'edizione Community di IntelliJ IDEA è gratuita e open-source, ed è la versione consigliata per il modding con Fabric. + +Potresti dover scorrere giù per trovare il link per scaricare l'edizione Community - ha il seguente aspetto: + +![Prompt per Scaricare l'Edizione Community di IDEA](/assets/develop/getting-started/idea-community.png) + +## Installare i Plugin IDEA {#installing-idea-plugins} + +Anche se questi plugin non sono strettamente necessari, essi rendono il modding con Fabric molto più semplice - dovresti installarli. + +### Minecraft Development {#minecraft-development} + +Il plugin Minecraft Development fornisce supporto per il modding con Fabric, ed è il plugin più importante da installare. + +Puoi installarlo aprendo IntelliJ IDEA, e poi navigando a `File > Impostazioni > Plugin > Scheda Marketplace` - cerca `Minecraft Development` nella barra di ricerca, e poi clicca il pulsante `Installa`. + +In alternativa, puoi scaricarlo dalla [pagina del plugin](https://plugins.jetbrains.com/plugin/8327-minecraft-development) e poi installarlo navigando a `File > Impostazioni > Plugin > Installa Plugin Dal Disco`. diff --git a/versions/1.21/translated/it_it/develop/ide-tips-and-tricks.md b/versions/1.21/translated/it_it/develop/ide-tips-and-tricks.md new file mode 100644 index 000000000..80e7c7e04 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/ide-tips-and-tricks.md @@ -0,0 +1,310 @@ +--- +title: Trucchi Riguardanti l'IDE +description: Informazioni utili su come gestire e navigare con l'IDE nel tuo progetto efficientemente. +authors: + - JR1811 + - AnAwesomGuy +--- + +# Trucchi Riguardanti l'IDE {#ide-tips-and-tricks} + +Questa pagina fornisce un po' di informazioni utili, per velocizzare e facilitare il workflow degli sviluppatori. Integrale nel tuo lavoro, se desideri. +Potrebbe servire del tempo per imparare e abituarsi alle scorciatoie e alle altre opzioni. Puoi usare questa pagina come riferimento per questo. + +:::warning +Le scorciatoie indicate si riferiscono alla mappatura di IntelliJ IDEA predefinita, se non specificato altrimenti. +Fai riferimento alle impostazioni in `File > Settings > Keymap` o cerca per la funzionalità altrove se usi un layout di tastiera diverso. +::: + +## Attraversare i Progetti {#traversing-projects} + +### Manualmente {#manually} + +IntelliJ ha molti modi diversi di navigare i progetti. Se hai generato le fonti con i comandi `./gradlew genSources` nel terminale o hai usato le operazioni Gradie `Tasks > fabric > genSources` nella finestra di Gradle, puoi aprire i file sorgente di Minecraft manualmente nelle Librerie Esterne della Schermata del Progetto. + +![Operazioni di Gradle](/assets/develop/misc/using-the-ide/traversing_01.png) + +Il codice sorgente di Minecraft si può trovare se cerchi `net.minecraft` nella schermata External Libraries della finestra del progetto. +Se il tuo progetto usa sorgenti suddivise dal [Generatore di Mod Modello](https://fabricmc.net/develop/template) online, troverai due sorgenti, indicate dal nome (client/common). +Inoltre altre sorgenti di progetti, librerie e dipendenze, importate con il file `build.gradle`, saranno anche disponibili. +Questo metodo si usa spesso mentre si cercano media, tag e altri file. + +![Libreria Esterna](/assets/develop/misc/using-the-ide/traversing_02_1.png) + +![Sorgenti Suddivise](/assets/develop/misc/using-the-ide/traversing_02_2.png) + +### Ricerca {#search} + +Premere Maiusc due volte apre una finestra Cerca. Lì puoi cercare i file e le classe del tuo progetto. Attivando la casella di controllo `include non-project items` o premendo Maiusc due volte di nuovo, la ricerca non includerà solo il tuo progetto, ma anche altri, come le Librerie Esterne. + +Puoi anche usare le scorciatoie ⌘/CTRL+N per cercare classi e ⌘/CTRL+Maiusc+N per cercare in tutti i _file_. + +![Finestra cerca](/assets/develop/misc/using-the-ide/traversing_03.png) + +### Finestra Recenti {#recent-window} + +Un altro strumento utile in IntelliJ è la finestra `Recent`. Puoi aprirla con la scorciatoia ⌘/CTRL+E. +Lì puoi saltare ai file che hai già visitato, e aprire finestre degli strumenti, come [Struttura](#structure-of-a-class) o [Preferiti](#bookmarks). + +![Finestra Recenti](/assets/develop/misc/using-the-ide/traversing_04.png) + +## Navigare il Codice {#traversing-code} + +### Salta alla Definizione / Utilizzo {#jump-to-definition-usage} + +Se devi controllare la definizione o gli utilizzi di variabili, metodi, classi e altre cose, puoi premere ⌘/CTRL+Clic Sinistro / B +o usare il Pulsante Centrale del Mouse (premere la rotellina) sul nome. Così eviterai lunghe sessioni di scorrimento o una ricerca manuale della definizione che troveresti in un altro file. + +Puoi anche usare ⌘/CTRL+⌥/Maiusc+Clic Sinistro / B per vedere tutte le implementazioni di una classe o di un'interfaccia. + +### Preferiti {#bookmarks} + +Puoi aggiungere linee di codice, file o anche schede aperte dell'Editor ai preferiti. +Specialmente se cerchi nel codice sorgente, aiuta a segnare posizioni che vuoi ritrovare velocemente nel futuro. + +Clicca con il tasto destro un file nella finestra `Project`, una scheda dell'editor o il numero di una linea in un file. +Creare `Preferiti Mnemonici` ti permette di passare velocemente a quei preferiti con le scorciatoie appropriate, ⌘/CTRL e il numero che hai scelto. + +![Imposta preferito](/assets/develop/misc/using-the-ide/traversing_05.png) + +È possibile creare più liste di preferiti nella finestra `Preferiti` contemporaneamente se vuoi separarli o ordinarli. +I [Punti di Interruzione](./basic-problem-solving#breakpoint) saranno anche presenti lì. + +![Finestra preferiti](/assets/develop/misc/using-the-ide/traversing_06.png) + +## Analizzare le Classi {#analyzing-classes} + +### Struttura di una Classe {#structure-of-a-class} + +Aprendo la finestra `Structure` (⌘/Alt+7) otterrai una panoramica della classe attualmente attiva. Puoi vedere quali Classi e quali Enum si trovano in quel file, quali metodi sono stati implementati e quali attributi e variabili sono dichiarate. + +A volte può essere utile attivare anche l'opzione `Inherited` in cima alle opzioni Visualizza, quando si cercano metodi specifici di cui fare override. + +![Finestra Structure](/assets/develop/misc/using-the-ide/analyzing_01.png) + +### Gerarchia dei Tipi di una Classe {#type-hierarchy-of-a-class} + +Posizionando il cursore sul nome di una classe e premendo ⌘/CTRL+H puoi aprire una nuova finestra Type Hierarchy, che mostra tutte le classi genitore e figlie. + +![Finestra Type Hierarchy](/assets/develop/misc/using-the-ide/analyzing_02.png) + +## Utilità del Codice {#code-utility} + +### Completamento del Codice {#code-completion} + +Il completamento del codice dovrebbe essere attivo in maniera predefinita. Otterrai consigli mentre scrivi il tuo codice in automatico. +Se l'hai per errore chiuso o hai spostato il cursore ad un altro punto, puoi usare ⌘/CTRL+Spazio per riaprirli nuovamente. + +Per esempio, usando espressioni lambda, puoi scriverli velocemente usando questo metodo. + +![Lambda con molti parametri](/assets/develop/misc/using-the-ide/util_01.png) + +### Generazione del Codice {#code-generation} + +Si può accedere velocemente al menu Generate con Alt+Ins (⌘ Comando+N su Mac) o andando su `Code` in cima e selezionando `Generate`. +In un file Java, potrai generare costruttori, getter, setter, fare override o implementare metodi, e molto altro. +Puoi anche generare accessori e invocatori se hai installato il [plugin per Sviluppo Minecraft](./getting-started/setting-up-a-development-environment#minecraft-development). + +Inoltre puoi fare velocemente override di metodi con ⌘/CTRL+O e implementare metodi con ⌘/CTRL+I. + +![Menu generazione di codice in un file Java](/assets/develop/misc/using-the-ide/generate_01.png) + +In un file di test Java, ti saranno fornite opzioni per generare metodi di test correlati, come segue: + +![Menu generazione di codice in un file di test Java](/assets/develop/misc/using-the-ide/generate_02.png) + +### Mostrare i Parametri {#displaying-parameters} + +La visualizzazione dei parametri dovrebbe essere attiva in maniera predefinita. Otterrai automaticamente i tipi e i nomi dei parametri mentre scrivi il tuo codice. +Se li hai per errore chiusi o hai spostato il cursore ad un altro punto, puoi usare ⌘/CTRL+P per riaprirli nuovamente. + +Metodi e classi possono avere più implementazioni con parametri diversi, fenomeno detto Overloading. In questo modo puoi decidere quale implementazione vuoi usare, mentre scrivi la chiamata al metodo. + +![Visualizzazione dei parametri del metodo](/assets/develop/misc/using-the-ide/util_02.png) + +### Refactoring {#refactoring} + +La riscrittura è il processo di ristrutturazione del codice senza cambiarne la funzionalità durante l'esecuzione. Rinonimare o eliminare in sicurezza parte del codice è un esempio di ciò, ma anche l'estrazione di codice in più metodi separati e l'introduzione di nuove variabili per parti di codice ripetute è detto "refactoring". + +Tanti ambienti di sviluppo hanno una vasta gamma di strumenti per assistere questo processo. In intelliJ basta cliccare con il tasto destro file o parti del codice per accedere agli strumenti di refactoring disponibili. + +![Refactoring](/assets/develop/misc/using-the-ide/refactoring_01.png) + +È soprattutto utile abituarsi alla scorciatoia dello strumento di refactoring `Rename`, ovvero Maiusc+F6, poiché probabilmente rinonimerai molte cose nel futuro. +Usando questa funzione, ogni occorrenza del codice rinonimato sarà rinonimata e la sua funzionalità rimarrà intatta. + +Puoi anche riformattare il codice secondo il tuo stile di codice. +Per fare questo, seleziona il codice che vuoi riformattare (se non selezioni niente, l'intero file sarà riformattato) e premi ⌘/CTRL+⌥/ALT+L. +Per cambiare il modo in cui IntelliJ formatta il codice, controlla le impostazioni presso `File > Settings > Editor > Code Style > Java`. + +#### Azioni Contestuali {#context-actions} + +Le azioni contestuali permettono di effettuare refactoring di sezioni di codice specifiche in base al contesto. +Per usarle, basta muovere il cursore sull'area di cui si vuol fare refactoring, e premere ⌥/ALT+Invio o cliccare la lampadina a sinistra. +Ci sarà un popup che mostrerà azioni contestuali che si possono usare per il codice selezionato. + +![Esempi di azioni contestuali](/assets/develop/misc/using-the-ide/context_actions_01.png) + +![Esempi di azioni contestuali](/assets/develop/misc/using-the-ide/context_actions_02.png) + +### Trova e Sostituisci i Contenuti di un File {#search-and-replace-file-content} + +A volte sono necessari strumenti più semplici per modificare le occorrenze del codice. + +| Scorciatoie | Funzione | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------- | +| ⌘/CTRL+F | Trova nel file corrente | +| ⌘/CTRL+R | Sostituisci nel file corrente | +| ⌘/CTRL+Maiusc+F | Trova in uno scope più grande (e imposta un filtro di tipo di file) | +| ⌘/CTRL+Maiusc+R | Sostituisci in uno scope più grande (e imposta un filtro di tipo di file) | + +Se si utilizzano, tutti questi strumenti permettono una ricerca più specifica grazie alle [Regex](https://en.wikipedia.org/wiki/Regular_expression). + +![Sostituzione regex](/assets/develop/misc/using-the-ide/search_and_replace_01.png) + +### Altre Scorciatoie Utili {#other-keybinds} + +Selezionare del testo e usare ⌘/CTRL+Maiusc+↑ Su / ↓ Giù muoverà il codice selezionato in alto o in basso. + +In IntelliJ, la scorciatoia per `Ripeti` potrebbe non essere quella solita, ovvero ⌘/CTRL+Y (Elimina Linea). +Potrebbe invece essere ⌘/CTRL+Maiusc+Z. Puoi cambiarla in **Keymap**. + + + +Per altre scorciatoie da tastiera, consulta la [documentazione di IntelliJ](https://www.jetbrains.com/help/idea/mastering-keyboard-shortcuts.html). + +## Commenti {#comments} + +Il buon codice dovrebbe essere facilmente leggibile e dovrebbe [documentarsi "da solo"](https://bytedev.medium.com/code-comment-anti-patterns-and-why-the-comment-you-just-wrote-is-probably-not-needed-919a92cf6758). +Scegliere nomi espressivi per variabili, classi e metodi aiuta molto, ma a volte i commenti sono necessari per lasciare note o per disattivare codice **temporaneamente** a fini di testing. + +Per commentare del codice velocemente, puoi selezionare del testo e usare le scorciatoie ⌘/CTRL+/ (commento linea) e ⌘/CTRL+⌥/Maiusc+/ (commento blocco). + +Ora puoi evidenziare il codice necessario (o basta che il cursore sia sopra ad esso) e usare le scorciatoie per commentare una sezione. + +```java +// private static final int PROTECTION_BOOTS = 2; +private static final int PROTECTION_LEGGINGS = 5; +// private static final int PROTECTION_CHESTPLATE = 6; +private static final int PROTECTION_HELMET = 1; +``` + +```java +/* +ModItems.initialize(); +ModSounds.initializeSounds(); +ModParticles.initialize(); +*/ + +private static int secondsToTicks(float seconds) { + return (int) (seconds * 20 /*+ 69*/); +} +``` + +### Compressione del Codice {#code-folding} + +In IntelliJ, vicino ai numeri di linea, potresti vedere delle piccole freccie. +Possono essere usate per comprimere temporaneamente metodi, istruzioni if, classi e molte altre cose su cui non stai lavorando attivamente. +Per creare un blocco personalizzato che possa essere compresso, usa i commenti `region` e `endregion`. + +```java +// region collapse block name + ModBlocks.initialize(); + ModBlockEntities.registerBlockEntityTypes(); + ModItems.initialize(); + ModSounds.initializeSounds(); + ModParticles.initialize(); +// endregion +``` + +![Compressione di una regione](/assets/develop/misc/using-the-ide/comments_02.png) + +:::warning +Se noti che ne stai usando troppi, considera una riscrittura del codice per renderlo più leggibile! +::: + +### Disattivare il Formattatore {#disabling-formatter} + +Si possono inoltre usare dei commenti per disattivare il formattatore durante il refactoring del codice menzionato sopra, rinchiudendo una sezione di codice così: + +```java +//formatter:off (disable formatter) + public static void disgustingMethod() { /* ew this code sucks */ } +//formatter:on (re-enable the formatter) +``` + +### Sopprimere le Ispezioni {#noinspection} + +I commenti `//noinspection` possono essere usati per sopprimere ispezioni e avvisi. +Funzionalmente sono identici all'annotazione `@SuppressWarnings`, ma non hanno la limitazione di essere un'annotazione e possono quindi essere usati per le istruzioni. + +```java +// below is bad code and IntelliJ knows that + +@SuppressWarnings("rawtypes") // annotations can be used here +List list = new ArrayList(); + +//noinspection unchecked (annotations cannot be here so we use the comment) +this.processList((List)list); + +//noinspection rawtypes,unchecked,WriteOnlyObject (you can even suppress multiple!) +new ArrayList().add("bananas"); +``` + +:::warning +Se noti che stai sopprimendo troppi avvisi, considera una riscrittura del codice per non produrne così tanti! +::: + +### Note TODO e FIXME {#todo-and-fixme-notes} + +Lavorando sul codice, può tornarti utile lasciare note su ciò che devi ancora completare. A volte potresti notare un problema nel codice, ma vuoi continuare a lavorare su ciò che stai facendo. In questi casi, usa i commenti `TODO` o `FIXME`. + +![Commenti TODO e FIXME](/assets/develop/misc/using-the-ide/comments_03.png) + +IntelliJ terrà conto di essi nella finestra `TODO` e ti notificherà se stai per fare commit di codice che usa questo tipo di commento. + +![Commenti TODO e FIXME](/assets/develop/misc/using-the-ide/comments_04.png) + +![Commit con TODO](/assets/develop/misc/using-the-ide/comments_05.png) + +### Javadocs {#javadocs} + +Un ottimo modo di documentare il tuo codice è usare i JavaDoc. +I JavaDoc non solo forniscono informazioni utili per l'implementazione di metodi e classi, ma sono anche profondamente integrati in IntelliJ. + +Passando il mouse sopra ai nomi di metodi o classi ai quali sono stati aggiunti commenti JavaDoc, essi mostreranno queste informazioni nella finestra apposita. + +![JavaDoc](/assets/develop/misc/using-the-ide/comments_06.png) + +Per iniziare, ti basta scrivere `/**` sopra al metodo o alla definizione della classe e premere Invio. IntelliJ genererà automaticamente linee per il valore restituito e per i parametri, ma le puoi modificare come ti pare. Ci sono parecchie funzioni personalizzate disponibili e puoi addirittura usare HTML se ti serve. + +La classe `ScreenHandler` di Minecraft ti mostra alcuni esempi. Per attivare o disattivare la finestra di rendering, usa il pulsante penna vicino ai numeri di linea. + +![Modifica dei JavaDoc](/assets/develop/misc/using-the-ide/comments_07.png) + +## Ottimizzare IntelliJ Ulteriormente {#optimizing-intellij-further} + +Ci sono parecchie altre scorciatoie e tanti trucchi utili, che però oltrepasserebbero gli obiettivi di questa pagina. +Jetbrains ha tanti buoni discorsi, video e pagine di documentazione riguardo a come personalizzare il tuo ambiente di lavoro ancora di più. + +### Completamento PostFix {#postfix-completion} + +Usa il Completamento PostFix per alterare il codice velocemente dopo averlo scritto. Esempi spesso citati comprendono `.not`, `.if`, `.var`, `.null`, `.nn`, `.for`, `.fori`, `.return` e `.new`. +Oltre a quelli già esistenti, puoi anche aggiungerne di tuoi nelle Impostazioni di IntelliJ. + + + +### Modelli Live {#live-templates} + +Usa i Modelli Live per generare il tuo codice ripetitivo personalizzato più velocemente. + + + +### Altri Trucchi {#more-tips} + +Anton Arhipov di Jetbrains ha anche avuto un discorso approfondito riguardo a Corrispondenza Regex, Completamento di Codice, Debugging e molti altri argomenti legati a IntelliJ. + + + +Per ulteriori informazioni, controlla il [sito di Trucchi e Consigli di Jetbrains](https://blog.jetbrains.com/idea/category/tips-tricks) e la [documentazione di IntelliJ](https://www.jetbrains.com/help/idea/getting-started). +Tanti dei loro post possono essere applicati anche all'ecosistema Fabric. diff --git a/versions/1.21/translated/it_it/develop/index.md b/versions/1.21/translated/it_it/develop/index.md new file mode 100644 index 000000000..2bc91b677 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/index.md @@ -0,0 +1,14 @@ +--- +title: Guide per Sviluppatori +description: Le nostre guide scritte dalla community trattano di tutto, dalla configurazione del tuo ambiente di sviluppo ad argomenti avanzati come rendering e reti. +--- + +# Guide per Sviluppatori {#developer-guides} + +Scritte dalla community, queste guide trattano una vasta gamma di argomenti, dalla configurazione del tuo ambiente di sviluppo ad aree più avanzate come rendering e networking. + +Controlla la barra laterale per una lista delle guide disponibili. Se cerchi qualcosa in particolare, la barra di ricerca in cima alla pagina è la tua migliore amica. + +Ricorda: è disponibile una mod completamente funzionante con tutto il codice di questa documentazione nella [cartella `/reference` su GitHub](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21). + +Se vuoi contribuire alla Documentazione di Fabric, puoi trovare il codice sorgente su [GitHub](https://github.com/FabricMC/fabric-docs), e le corrispondenti [linee guida per la contribuzione](../contributing). diff --git a/versions/1.21/translated/it_it/develop/items/custom-armor.md b/versions/1.21/translated/it_it/develop/items/custom-armor.md new file mode 100644 index 000000000..48688313b --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/custom-armor.md @@ -0,0 +1,160 @@ +--- +title: Armature Personalizzate +description: Impara come creare i tuoi set di armature personalizzati. +authors: + - IMB11 +--- + +# Armature Personalizzate {#custom-armor} + +Un'armatura fornisce al giocatore una difesa migliore contro attacchi di mob e di altri giocatori. + +## Creare una Classe per un Materiale delle Armature {#creating-an-armor-materials-class} + +Proprio come gli oggetti e i blocchi, i materiali delle armature devono essere registrati. Per mettere ordine, creeremo una classe `ModArmorMaterials` in cui memorizzare il nostro materiale personalizzato. + +Dovrai aggiungere un metodo statico `initialize()` a questa classe, e chiamarlo dall'[initializer della tua mod](./getting-started/project-structure#entrypoints) perché i materiali vengano registrati. + +```java +// Within the ModArmorMaterials class +public static void initialize() {}; +``` + +:::warning +Assicurati di chiamare questo metodo **prima** di registrare i tuoi oggetti, poiché sarà necessario che i materiali siano registrati prima che gli oggetti vengano creati. +::: + +```java +@Override +public void onInitialize() { + ModArmorMaterials.initialize(); +} +``` + +--- + +All'interno di questa classe `ModArmorMaterials`, dovrai creare un metodo statico che registrerà il materiale dell'armatura. Questo metodo dovrebbe restituire una voce di registry per il materiale, perché questa voce verrà usata dal costruttore di ArmorItem per creare le componenti dell'armatura. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Proprietà dei Materiali delle Armature {#armor-material-properties} + +:::tip +Se ti è difficile decidere un buon valore per queste proprietà, potresti prendere ispirazione ai materiali delle armature vanilla nella classe `ArmorMaterials`. +::: + +Durante la creazione di un materiale delle armature, dovrai definire le seguenti proprietà: + +### Punti Difesa {#defense-points} + +:::warning +Assicurati di assegnare un valore a ogni pezzo di armatura che intendi creare e registrare come oggetto. Se creassi un oggetto per un pezzo di armatura senza impostare un valore per i punti di difesa, il gioco andrà in crash. +::: + +La mappa `defensePoints` viene usata per definire il numero di punti difesa che ciascun pezzo dell'armatura fornirà. Più alto è il numero, maggiore la protezione fornita dal pezzo di armatura. La mappa dovrebbe contenere una voce per ciascun tipo di pezzo di armatura. + +### Incantabilità {#enchantability} + +La proprietà `enchantability` definisce la facilità con cui l'armatura può essere incantata. Più alto è il numero, maggiore la quantità di incantesimi che può ricevere l'armatura. + +### Suono Appena Indossata {#equip-sound} + +La proprietà `equipSound` è il suono che verrà riprodotto quando l'armatura viene indossata. Questo suono dovrebbe essere una voce di registry di un `SoundEvent`. Potresti voler dare un'occhiata alla pagina sui [SoundEvent personalizzati](../sounds/custom) se avessi in mente di creare suoni personalizzati invece di affidarti ai suoni vanilla dalla classe `SoundEvents`. + +### Ingredienti per il Riparo {#repair-ingredient} + +La proprietà `repairIngredientSupplier` fornisce un `Ingredient` che viene usato per riparare l'armatura. Questo ingrediente può essere quasi qualsiasi cosa, consigliamo di sceglierlo in modo che sia lo stesso materiale con cui si creano gli oggetti dell'armatura. + +### Tenacità {#toughness} + +La proprietà `toughness` definisce quanto danno l'armatura assorbirà. Più alto è il numero, maggiore il danno che l'armatura assorbirà. + +### Resistenza al Contraccolpo {#knockback-resistance} + +La proprietà `knockbackResistance` definisce quanto contraccolpo verrà riflesso dal giocatore quando viene colpito. Più alto è il numero, minore il contraccolpo che riceverà il giocatore. + +### Tingibile {#dyeable} + +La proprietà `dyeable` è un booleano che definisce se l'armatura può essere tinta. Se fosse `true`, l'armatura potrebbe essere tinta coi coloranti in un banco da lavoro. + +Se scegliessi di rendere la tua armatura tingibile, lo strato della tua armatura e le texture degli oggetti devono essere **pensati per essere tinti**, poiché il colorante si sovrapporrà alla texture, non la sostituirà. Prendi per esempio l'armatura di cuoio vanilla: le texture sono in scala di grigi e il colorante viene applicato in sovrapposizione, il che cambia il colore dell'armatura. + +## Registrare il Materiale dell'Armatura {#registering-the-armor-material} + +Ora che hai creato un metodo di utilità che può essere usato per registrare materiali di armature, puoi registrare i tuoi materiali di armature personalizzati come attributo statico nella classe `ModArmorMaterials`. + +Per questo esempio, creeremo l'armatura di Guidite, con le seguenti proprietà: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Creare gli Oggetti dell'Armatura {#creating-the-armor-items} + +Ora che hai registrato il materiale, puoi creare gli oggetti dell'armatura nella tua classe `ModItems`: + +Ovviamente, un set di armatura non deve per forza essere completo, puoi avere un set con solo stivali, o solo gambiere... - il carapace di tartaruga vanilla è un buon esempio di un set di armatura con elementi mancanti. + +### Durabilità {#durability} + +A differenza di `ToolMaterial`, `ArmorMaterial` non memorizza alcuna informazione riguardo alla durabilità degli oggetti. +Per questo motivo la durabilità deve essere aggiunta manualmente a `Item.Settings` degli oggetti dell'armatura quando li si registra. + +Questo si fa con il metodo `maxDamage` nella classe `Item.Settings`. +Le varie parti dell'armatura hanno durabilità base diverse, solitamente ottenute come prodotto di un fattore condiviso a livello del materiale dell'armatura, ma si possono anche scegliere valori fissi. + +Per l'armatura di Guidite useremo un fattore condiviso memorizzato assieme al materiale dell'armatura: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +Possiamo quindi creare gli oggetti dell'armatura con la costante di durabilità: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Dovrai anche **aggiungere gli oggetti ad un gruppo** se vorrai che essi siano accessibili dall'inventario in creativa. + +Come per tutti gli oggetti, dovresti creare chiavi di traduzione anche per questi. + +## Texture e Modelli {#texturing-and-modelling} + +Dovrai creare due insiemi di texture: + +- Texture e modelli per gli oggetti stessi. +- Texture per l'armatura in sé, visibile quando un'entità la indossa. + +### Texture e Modello dell'Oggetto {#item-textures-and-model} + +Queste texture non differiscono da quelle di altri oggetti - devi creare le texture, e creare un modello di oggetto generico generato - tutto questo è coperto dalla guida [Creare il Tuo Primo Oggetto](./first-item#adding-a-texture-and-model). + +Come esempio, puoi usare le seguenti texture e modelli JSON come riferimento. + +Texture degli Oggetti + +:::info +Ti serviranno modelli in file JSON per tutti gli oggetti, non solo l'elmo, stesso principio di altri modelli di oggetti. +::: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json) + +Come puoi notare, gli oggetti dell'armatura avranno i modelli appropriati nel gioco: + +![Modelli degli oggetti dell'armatura](/assets/develop/items/armor_1.png) + +## Texture e Modello dell'Armatura {#armor-textures-and-model} + +Quando un'entità indossa la tua armatura, per ora apparirà la texture mancante: + +![Modello di armatura corrotto su un giocatore](/assets/develop/items/armor_2.png) + +Ci sono due strati per le texture dell'armatura, entrambi devono essere presenti. + +Poiché il nome del materiale dell'armatura è nel nostro caso `guidite`, i percorsi delle texture saranno: + +- `assets//textures/models/armor/guidite_layer_1.png` +- `assets//textures/models/armor/guidite_layer_2.png` + +Texture dei Modelli delle Armature + +Il primo strato contiene texture per elmo e corazza, mentre il secondo strato contiene texture per gambiere e stivali. + +Quando queste texture sono presenti, dovresti poter vedere la tua armatura sulle entità che la indossano: + +![Modello di armatura funzionante su un giocatore](/assets/develop/items/armor_3.png) diff --git a/versions/1.21/translated/it_it/develop/items/custom-data-components.md b/versions/1.21/translated/it_it/develop/items/custom-data-components.md new file mode 100644 index 000000000..b61c44663 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/custom-data-components.md @@ -0,0 +1,271 @@ +--- +title: Componenti di Dati Personalizzate +description: Impara come si aggiungono dati personalizzati ai tuoi oggetti usando il nuovo sistema di componenti di 1.20.5. +authors: + - Romejanic +--- + +# Componenti di Dati Personalizzate {#custom-data-components} + +Più i tuoi oggetti crescono in complessità, più troverai la necessità di memorizzare dati personalizzati associati con ogni oggetto. Il gioco permette di memorizzare dati persistenti in un `ItemStack`, e a partire da 1.20.5 il modo di fare ciò è usare le **Componenti di Dati**. + +Le Componenti di Dati sostituiscono i dati NBT di versioni precedenti, con tipi di dati strutturati che possono essere applicati a un `ItemStack` per memorizzare dati su quello stack. Le componenti di dati sfruttano namespace, il che significa che possiamo implementare le nostre componenti di dati per memorizzare dati personalizzati su un `ItemStack` e accederci successivamente. Una lista completa delle componenti di dati vanilla si trova su questa [pagina della Minecraft Wiki](https://minecraft.wiki/w/Data_component_format#List_of_components). + +Assieme alla registrazione delle componenti personalizzate, questa pagina copre l'utilizzo generale dell'API delle componenti, il che si applica anche alle componenti vanilla. Puoi vedere e accedere alle definizioni di tutte le componenti vanilla nella classe `DataComponentTypes`. + +## Registrare una Componente {#registering-a-component} + +Come per qualsiasi altra cosa nella tua mod dovrai registrare la tua componente personalizzata usando un `ComponentType`. Questo tipo di componente prende un parametro generico contenente il tipo del valore della tua componente. Ci concentreremo su questo più in basso quando tratteremo le componenti [basilari](#basic-data-components) e [avanzate](#advanced-data-components). + +Scegli sensibilmente una classe in cui mettere ciò. Per questo esempio creeremo un nuovo package chiamato `component` e una classe che conterrà tutti i tipi delle nostre componenti chiamate `ModComponents`. Assicurati di richiamare `ModComponents.initialize()` nell'[initializer della tua mod](./getting-started/project-structure#entrypoints). + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Questo è il modello generico per registrare un tipo di componente: + +```java +public static final ComponentType MY_COMPONENT_TYPE = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "my_component"), + ComponentType.builder().codec(null).build() +); +``` + +Ci sono un paio di cose qui da far notare. Nelle linee prima e quarta, noti un `?`. Questo sarà sostituito con il tipo del valore della tua componente. Lo compileremo presto. + +Secondo, devi fornire un `Identifier` che contenga l'ID voluto per la tua componente. Questo avrà il namespace con l'ID della tua mod. + +Infine, abbiamo un `ComponentType.Builder` che crea l'istanza `ComponentType` effettiva da registrare. Questo contiene un altro dettaglio cruciale che dovremmo analizzare: il `Codec` della tua componente. Questo per ora è `null` ma presto dobbiamo scriverlo. + +## Componenti di Dati Basilari {#basic-data-components} + +Le componenti di dati basilari (come `minecraft:damage`) consiste di un valore di dati singolo, come un `int`, `float`, `boolean` o `String`. + +Per questo esempio, creiamo un valore `Integer` che traccierà quante volte il giocatore ha cliccato con il tasto destro mente teneva il nostro oggetto. Aggiorniamo la registrazione della nostra componente alla seguente: + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Puoi ora notare che abbiamo passato `` come nostro tipo generico, indicando che questa componente sarà memorizzata come un valore `int` singolo. Per il nostro codec, cusiamo il codec `Codec.INT` fornito. Possiamo cavarcela usando codec basilari per componenti semplici come questa, ma scenari più complessi potrebbero richiedere un codec personalizzato (questo sarà trattato tra poco). + +Se avviassi il gioco, dovresti poter inserire un comando come questo: + +![Comando /give che mostra la componente personalizzata](/assets/develop/items/custom_component_0.png) + +Quando esegui il comando, dovresti ricevere l'oggetto contenente la componente. Tuttavia, non possiamo ancora sfruttare la componente per fare qualcosa di utile. Iniziamo leggendo il valore della componente in modo da poterlo vedere. + +## Leggere il Valore della Componente {#reading-component-value} + +Aggiungiamo un nuovo oggetto che aumenterà il contatore ogni volta che viene cliccato con il tasto destro. Dovresti leggere la pagina [Interazioni tra Oggetti Personalizzate](./custom-item-interactions) che tratterà delle tecniche utilizzate in questa guida. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Ricorda come sempre di registrare l'oggetto nella tua classe `ModItems`. + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings() +), "counter"); +``` + +Aggiungeremo del codice del tooltip per mostrare il valore corrente del contatore di clic quando passiamo il mouse sopra al nostro oggetto nell'inventario. Possiamo usare il metodo `get()` sul nostro `ItemStack` per ottenere il valore della nostra componente, così: + +```java +int clickCount = stack.get(ModComponents.CLICK_COUNT_COMPONENT); +``` + +Questo restituirà il valore corrente della componente nel tipo che abbiamo definito quando abbiamo registrato la nostra componente. Possiamousare questo valore per aggiungere una voce al tooltip. Aggiungi questa linea al metodo `appendTooltip` nella classe `CounterItem`: + +```java +public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + int count = stack.get(ModComponents.CLICK_COUNT_COMPONENT); + tooltip.add(Text.translatable("item.fabric-docs-reference.counter.info", count).formatted(Formatting.GOLD)); +} +``` + +Non dimenticare di aggiornare il tuo file di lingua (`/assets//lang/en_us.json`) e aggiungere queste due linee: + +```json +{ + "item.fabric-docs-reference.counter": "Counter", + "item.fabric-docs-reference.counter.info": "Used %1$s times" +} +``` + +Avvia il gioco e esegui questo comando per darti un nuovo oggetto Counter con un conto di 5. + +```mcfunction +/give @p fabric-docs-reference:counter[fabric-docs-reference:click_count=5] +``` + +Quando passi il mouse sopra a questo oggetto nell'inventario, dovresti notare il conto nel tooltip! + +![Tooltip che mostra "Used 5 times"](/assets/develop/items/custom_component_1.png) + +Tuttavia, se ti dai un nuovo oggetto Counter _senza_ la componente personalizzata, il gioco crasherà quando passi il mouse sull'oggetto nel suo inventario. Dovresti vedere un errore come il seguente nel report di crash: + +```log +java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "net.minecraft.item.ItemStack.get(net.minecraft.component.ComponentType)" is null + at com.example.docs.item.custom.CounterItem.appendTooltip(LightningStick.java:45) + at net.minecraft.item.ItemStack.getTooltip(ItemStack.java:767) +``` + +Come ci aspettavamo, poiché l'`ItemStack` non contiene per ora un'istanza della nostra componente personalizzata, chiamare `stack.get()` con il tipo della nostra componente restituirà `null`. + +Ci sono tre soluzioni a questo problema. + +### Impostare un Valore Predefinito della Componente {#setting-default-value} + +Quando registri il tuo oggetto e passi un'istanza di `Item.Settings` al suo costruttore, puoi anche fornire una lista di componenti predefinite applicate a tutti i nuovi oggetti. Tornando alla nostra classe `ModItems`, dove registriamo il `CounterItem`, possiamo aggiungere un valore predefinito alla nostra componente. Aggiungi questo così i nuovi oggetti mostreranno un conto di `0`. + +@[code transcludeWith=::_13](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Quando un nuovo oggetto viene creato, applicherà automaticamente la nostra componente personalizzata con il valore dato. + +:::warning +Usando i comandi, è possibile togliere la componente predefinita da un `ItemStack`. Dovresti affidarti alle prossime due sezioni per gestire lo scenario della mancanza della componente sul tuo oggetto correttamente. +::: + +### Leggere con un Valore Predefinito {#reading-default-value} + +Inoltre, leggendo il valore della componente, possiamo usare il metodo `getOrDefault()` sul nostro `ItemStack` per restituire un valore predefinito indicato se la componente non è presente nello stack. Questo ci tutelerà contro errori risultanti da una componente mancante. Possiamo modificare il codice del nostro tooltip così: + +```java +int clickCount = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); +``` + +Come puoi notare, questo metodo prende due parametri: il tipo della nostra componente come prima, e un valore predefinito restituito se la componente non esiste. + +### Controllare se una Componente Esiste {#checking-if-component-exists} + +Puoi anche verificare se una componente specifica esiste in un `ItemStack` con il metodo `contains()`. Questo prende il tipo della componente come parametro e restituisce `true` o `false` se lo stack contiene o meno quella componente. + +```java +boolean exists = stack.contains(ModComponents.CLICK_COUNT_COMPONENT); +``` + +### Risolvere l'Errore {#fixing-the-error} + +Sceglieremo la terza opzione. Quindi, oltre ad aggiungere un valore predefinito alla componente, controlleremo anche se la componente esiste sullo stack, e mostreremo il tooltip solo se lo è. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Riavvia il gioco e passa il mouse sopra all'oggetto senza la componente, dovresti notare che mostra "Used 0 times" e non fa più crashare il gioco. + +![Tooltip che mostra "Used 0 times"](/assets/develop/items/custom_component_2.png) + +Prova a darti un Counter rimuovendo la nostra componente personalizzata. Puoi usare il comando per fare ciò: + +```mcfunction +/give @p fabric-docs-reference:counter[!fabric-docs-reference:click_count] +``` + +Passando il mouse sopra all'oggetto, dovrebbe mancare il tooltip. + +![Oggetto Counter senza tooltip](/assets/develop/items/custom_component_7.png) + +## Aggiornare il Valore della Componente {#setting-component-value} + +Ora proviamo ad aggiornare il valore della nostra componente. Aumenteremo il conto dei clic ogni volta che usiamo il nostro oggetto Counter. Per cambiare il valore di una componente su un `ItemStack` usiamo il metodo `set()` come segue: + +```java +stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Questo prende il tipo della nostra componente e il valore che le vogliamo assegnare. In questo caso sarà il nuovo conto dei clic. Questo metodo restituisce anche il vecchio valore della componente (se ne esiste uno), e questo potrebbe essere utile in alcune situazioni. Per esempio: + +```java +int oldValue = stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Configuriamo un nuovo metodo `use()` per leggere il vecchio conto dei clic, aumentarlo di uno, e impostare il conto dei clic aggiornato. + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Ora prova ad avviare il gioco e a cliccare con il tasto destro l'oggetto Counter nella tua mano. Aprendo l'inventario dovresti notare che il numero di utilizzi dell'oggetto è aumentato di tante volte quante hai cliccato. + +![Tooltip che mostra "Used 8 times"](/assets/develop/items/custom_component_3.png) + +## Rimuovere il Valore della Componente {#removing-component-value} + +Puoi anche rimuovere una componente dal tuo `ItemStack` se non serve più. Questo si fa usando il metodo `remove()`, che prende il tipo della componente. + +```java +stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +Questo metodo restituisce anche il valore della componente prima di essere rimossa, per cui puoi usarlo come segue: + +```java +int oldCount = stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +## Dati Avanzati delle Componenti {#advanced-data-components} + +Potresti avere bisogno di memorizzare più attributi in una componente singola. Un esempio da vanilla è la componente `minecraft:food`, che memorizza più valori legati al cibo come `nutrition`, `saturation`, `eat_seconds` e altro ancora. In questa guida le chiameremo componenti "composite". + +Per le componenti composite, devi creare una classe `record` per memorizzare i dati. Questo è il tipo che registreremo nel tipo della componente e che leggeremo e scriveremo interagendo con un `ItemStack`. Inizia creando una nuova classe record nel package `component` che abbiamo creato prima. + +```java +public record MyCustomComponent() { +} +``` + +Nota che c'è un paio di parentesi dopo il nome della classe. Questo è dove definiremo la lista di proprietà che vogliamo dare alla nostra componente. Aggiungiamo un float e un booleano chiamati `temperature` e `burnt` rispettivamente. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Poiché stiamo definendo una struttura dai personalizzata, non ci sarà un `Codec` preesistente per il nostro caso come c'era per le [componenti basilari](#basic-data-components). Questo significa che dovremo costruire il nostro codec. Definiamone uno nella nostra classe record con un `RecordCodecBuilder` a cui potremo far riferimento quando registriamo la componente. Per maggiori dettagli sull'utilizzo di un `RecordCodecBuilder` fai riferimento a [questa sezione della pagina sui Codec](../codecs#merging-codecs-for-record-like-classes). + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Puoi notare che stiamo definendo una lista di attributi personalizzati basata sui tipi di `Codec` primitivi. Tuttavia, stiamo anche indicando come si chiamano i nostri attributi con `fieldOf()`, e poi usando `forGetter()` per dire al gioco quale attributo del nostro record deve essere riempito. + +Puoi anche definire attributi opzionali usando `optionalFielfOf()` e passando un valore predefinito come secondo parametro. Qualsiasi attributo non opzionale sarà richiesto quando si impostano le componenti con `/give`, quindi assicurati di segnare i parametri opzionali quando crei il tuo codec. + +Infine, possiamo chiamare `apply()` e passare il costruttore del nostro record. Per maggiori dettagli su come costruire codec e su casi più avanzati, assicurati di leggere la pagina sui [Codec](../codecs). + +Registrare una componente composita funziona come prima. Basta passare la nostra classe record come tipo generico, e il nostro `Codec` personalizzato al metodo `codec()`. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Ora avvia il gioco. Usando il comando `/give`, prova ad applicare la componente. I valori delle componenti composite si passano come oggetto racchiuso da `{}`. Se lasci le graffe vuote, vedrai un errore che ti dice che la chiave `temperature` necessaria è mancante. + +![Comando give che mostra la chiave "temperature" mancante](/assets/develop/items/custom_component_4.png) + +Aggiungi un valore di temperatura all'oggetto con la sintassi `temperature:8.2`. Puoi anche passare opzionalmente un valore per `burnt` con la stessa sintassi ma con `true` o `false`. Dovresti ora notare che il comando è valido, e che può darti un oggetto che contiene la componente. + +![Comando give valido che mostra entrambe le proprietà](/assets/develop/items/custom_component_5.png) + +### Ottenere, Impostare e Rimuovere le Componenti Avanzate {#getting-setting-removing-advanced-comps} + +Usare la componente nel codice funziona proprio come prima. Usare `stack.get()` restituirà un'istanza della tua classe `record`, che puoi quindi usare per leggere i valori. Poiché i record sono a sola lettura, dovrai creare una nuova istanza del tuo record per aggiornare i valori. + +```java +// read values of component +MyCustomComponent comp = stack.get(ModComponents.MY_CUSTOM_COMPONENT); +float temp = comp.temperature(); +boolean burnt = comp.burnt(); + +// set new component values +stack.set(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(8.4f, true)); + +// check for component +if (stack.contains(ModComponents.MY_CUSTOM_COMPONENT)) { + // do something +} + +// remove component +stack.remove(ModComponents.MY_CUSTOM_COMPONENT); +``` + +Puoi anche impostare un valore predefinito per una componente composita passando un oggetto componente alle tue `Item.Settings`. Per esempio: + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings().component(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(0.0f, false)) +), "counter"); +``` + +Ora puoi memorizzare dati personalizzati su un `ItemStack`. Usa in modo responsabile! + +![Oggetto che mostra un tooltip per numero di clic, temperatura e bruciato](/assets/develop/items/custom_component_6.png) diff --git a/versions/1.21/translated/it_it/develop/items/custom-enchantment-effects.md b/versions/1.21/translated/it_it/develop/items/custom-enchantment-effects.md new file mode 100644 index 000000000..265620d9f --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/custom-enchantment-effects.md @@ -0,0 +1,62 @@ +--- +title: Effetti d'Incantesimi Personalizzati +description: Impara come creare i tuoi effetti d'incantesimi. +authors: + - krizh-p +--- + +# Incantesimi Personalizzati {#custom-enchantments} + +A partire dalla versione 1.21, gli incantesimi personalizzati in Minecraft usano un approccio basato sui dati. Questo rende l'aggiunta d'incantesimi semplici, come aumentare il danno da attacco, più semplice, ma complica la creazione d'incantesimi più complessi. Il processo prevede la suddivisione degli incantesimi in _componenti degli effetti_. + +Una componente di un effetto contiene il codice che definisce gli effetti speciali di un incantesimo. Minecraft supporta vari effetti predefiniti, come danno degli oggetti, contraccolpo, ed esperienza. + +:::tip +Assicurati di controllare se gli effetti predefiniti di Minecraft soddisfano le tue necessità visitando [la pagina sulle Componenti degli Effetti d'Incantesimi della Wiki di Minecraft](https://minecraft.wiki/w/Enchantment_definition#Effect_components). Questa guida suppone che tu comprenda come si configurino incantesimi "semplici" basati su dati, e si focalizza sulla creazione di effetti d'incantesimi personalizzati che non sono supportati in maniera predefinita. +::: + +## Effetti d'Incantesimi Personalizzati {#custom-enchantment-effects} + +Inizia con la creazione di una cartella `enchantment`, e in essa crea una cartella `effect`. In questa creeremo il record `LightningEnchantmentEffect`. + +Poi possiamo creare un costruttore e fare override dei metodi dell'interfaccia `EnchantmentEntityEffect`. Creeremo anche una variabile `CODEC` per codificare e decodificare il nostro effetto; puoi leggere di più [riguardo ai Codec qui](../codecs). + +La maggior parte del nostro codice andrà nell'evento `apply()`, che viene chiamato quando i criteri perché il tuo incantesimo funzioni sono soddisfatti. Dopo di che configureremo questo `Effect` in modo che sia chiamato quando un'entità è colpita, ma per ora scriviamo codice semplice per colpire l'obiettivo con un fulmine. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/enchantment/effect/LightningEnchantmentEffect.java) + +Qui, la variabile `amount` indica un valore ridimensionato in base al livello dell'incantesimo. Possiamo usare questa per modificare l'efficacia dell'incantesimo in base al livello. Nel codice sopra, stiamo usando il livello dell'incantesimo per determinare quanti fulmini vengono generati. + +## Registrare l'Effetto dell'Incantesimo {#registering-the-enchantment-effect} + +Come ogni altra componente della tua mod, dovremo aggiungere questo `EnchantmentEffect` alla registry di Minecraft. Per fare ciò, aggiungi una classe `ModEnchantmentEffects` (o un qualsiasi nome che tu voglia darle) e un metodo ausiliare per registrare l'incantesimo. Assicurati di chiamare il `registerModEnchantmentEffects()` nella tua classe principale, che contiene il metodo `onInitialize()`. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/enchantment/ModEnchantmentEffects.java) + +## Creare l'Incantesimo {#creating-the-enchantment} + +Ora abbiamo un effetto d'incantesimo! Il passaggio finale è creare un incantesimo che applica il nostro effetto personalizzato. Anche se questo si potrebbe fare creando un file JSON in maniera simile a quella dei datapack, questa guida ti mostrerà come generare il JSON dinamicamente usando gli strumenti di generazione di dati di Fabric. Per cominciare, crea una classe `EnchantmentGenerator`. + +All'interno di questa classe registreremo anzitutto un nuovo incantesimo, e poi useremo il metodo `configure()` per creare il nostro JSON programmaticamente. + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/client/java/com/example/docs/datagen/EnchantmentGenerator.java) + +Prima di procedere dovresti assicurarti che il tuo progetto sia configurato per la generazione di dati; se non sei sicuro, [controlla la pagina corrispondente della documentazione](../data-generation/setup). + +Infine, dobbiamo dire alla nostra mod di aggiungere il nostro `EnchantmentGenerator` alla lista di operazioni di generazione dati. Per fare questo, basta aggiungere il `EnchantmentGenerator` a questo all'interno del metodo `onInitializeDataGenerator`. + +@[code transclude={22-22}](@/reference/1.21/src/client/java/com/example/docs/datagen/FabricDocsReferenceDataGenerator.java) + +Ora, eseguendo l'operazione di generazione dati della tua mod, i file JSON degli incantesimi verranno generati nella cartella `generated`. Ecco un esempio qua sotto: + +@[code](@/reference/1.21/src/main/generated/data/fabric-docs-reference/enchantment/thundering.json) + +Dovresti anche aggiungere le traduzioni al tuo file `en_us.json` per dare al tuo incantesimo un nome leggibile: + +```json +"enchantment.FabricDocsReference.thundering": "Thundering", +``` + +Dovresti ora avere un effetto d'incantesimo personalizzato funzionante! Testalo incantando un'arma con l'incantesimo e colpendo un mob. Ecco un esempio nel video seguente: + + diff --git a/versions/1.21/translated/it_it/develop/items/custom-item-groups.md b/versions/1.21/translated/it_it/develop/items/custom-item-groups.md new file mode 100644 index 000000000..47651bc56 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/custom-item-groups.md @@ -0,0 +1,38 @@ +--- +title: Gruppi di Oggetti Personalizzati +description: Impara come creare il tuo gruppo di oggetti e come aggiungerci oggetti. +authors: + - IMB11 +--- + +# Gruppi di Oggetti Personalizzati {#custom-item-groups} + +I gruppi di oggetti sono le schede nell'inventario in creativa che memorizzano oggetti. Puoi creare il tuo gruppo di oggetti personalizzato per memorizzare i tuoi oggetti in una scheda separata. Questo è piuttosto utile se la tua mod aggiunge molti oggetti e vuoi tenerli organizzati in una sola posizione per facilitarne l'accesso per i giocatori. + +## Creare il Gruppo di Oggetti {#creating-the-item-group} + +È sorprendentemente facile creare un gruppo di oggetti. Basta creare un nuovo attributo `static final` nella classe dei tuoi oggetti per memorizzare il gruppo di oggetti e una chiave di registry per esso, puoi quindi usare l'evento del gruppo di oggetti come quando hai aggiunti i tuoi oggetti ai gruppi vanilla: + +@[code transcludeWith=:::9](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::_12](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +
+ +Dovresti notare che il gruppo di oggetti è ora nel menu dell'inventario in creativa. Tuttavia, è rimasto senza traduzione - devi aggiungere una chiave al tuo file di traduzioni - come quando hai tradotto il tuo primo oggetto. + +![Gruppo di oggetti senza traduzione nel menu creativo](/assets/develop/items/itemgroups_0.png) + +## Aggiungere una Chiave di Traduzione {#adding-a-translation-key} + +Se avessi per caso usato `Text.translatable` per il metodo `displayName` del costruttore del gruppo di oggetti, dovrai aggiungere la traduzione al tuo file di lingua. + +```json +{ + "itemGroup.fabric_docs_reference": "Fabric Docs Reference" +} +``` + +Ora, come puoi notare, il gruppo di oggetti dovrebbe avere il nome corretto: + +![Gruppo di oggetti completo con traduzione e oggetti](/assets/develop/items/itemgroups_1.png) diff --git a/versions/1.21/translated/it_it/develop/items/custom-item-interactions.md b/versions/1.21/translated/it_it/develop/items/custom-item-interactions.md new file mode 100644 index 000000000..f4590a096 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/custom-item-interactions.md @@ -0,0 +1,71 @@ +--- +title: Interazioni tra Oggetti Personalizzate +description: Impara come si crea un oggetto che usa gli eventi vanilla integrati. +authors: + - IMB11 +--- + +# Interazioni tra Oggetti Personalizzate {#custom-item-interactions} + +Gli oggetti basilari non possono arrivare lontano - prima o poi ti servirà un oggetto che interagisce con il mondo quando lo si usa. + +Ci sono alcune classi chiave che devi comprendere prima di dare un'occhiata agli eventi degli oggetti vanilla. + +## TypedActionResult {#typedactionresult} + +Per gli oggetti, il `TypedActionResult` che incontrerai più comunemente è per gli `ItemStacks` - questa classe informa il gioco riguardo a cosa sostituire (o non) nello stack di oggetti dopo che l'evento è avvenuto. + +Se non è successo nulla nell'evento, dovresti usare il metodo `TypedActionResult#pass(stack)`, dove `stack` è lo stack di oggetti corrente. + +Puoi ottenere lo stack di oggetti corrente ottenendo il contenuto della mano del giocatore. Di solito gli eventi che richiedono un `TypedActionResult` passano la mano al metodo dell'evento. + +```java +TypedActionResult.pass(user.getStackInHand(hand)) +``` + +Se passi lo stack corrente - nulla cambierà, anche dichiarando l'evento come fallito, saltato/ignorato o riuscito. + +Se volessi eliminare lo stack corrente, dovresti passarne uno vuoto. Lo stesso si può dire per la riduzione, puoi analizzare lo stack corrente e diminuirlo della quantità che vuoi: + +```java +ItemStack heldStack = user.getStackInHand(hand); +heldStack.decrement(1); +TypedActionResult.success(heldStack); +``` + +## ActionResult {#actionresult} + +Similmente, un `ActionResult` informa il gioco sullo stato dell'evento, sia che sia saltato/ignorato, fallito o riuscito. + +## Event con Override {#overridable-events} + +Fortunatamente, la classe Item ha molti metodi di cui si può fare override per aggiungere funzionalità ai tuoi oggetti. + +:::info +Un ottimo esempio di questi eventi in uso si trova nella pagina [Riprodurre Suoni](../sounds/using-sounds), che usa l'evento `useOnBlock` per riprodurre un suono quando il giocatore clicca un blocco con il tasto destro. +::: + +| Metodo | Informazioni | +| --------------- | ------------------------------------------------------------------------------------------------------- | +| `postHit` | Eseguito dopo che il giocatore colpisce un'entità. | +| `postMine` | Eseguito dopo che il giocatore rompe un blocco. | +| `inventoryTick` | Eseguito ad ogni tick mentre l'oggetto è nell'inventario. | +| `onCraft` | Eseguito quando l'oggetto viene craftato. | +| `useOnBlock` | Eseguito quando il giocatore clicca un blocco con il tasto destro, mentre ha l'oggetto. | +| `use` | Eseguito quando il giocatore clicca con il tasto destro mentre ha l'oggetto. | + +## L'Evento `use()` {#use-event} + +Immaginiamo che tu voglia fare in modo che l'oggetto crei un lampo davanti al giocatore - dovrai creare una classe personalizzata. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +L'evento `use` è probabilmente il più utile tra tutti - puoi usare questo evento per generare il lampo, dovresti generarlo 10 blocchi davanti al giocatore, nella direzione verso cui è diretto. + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Come sempre, dovresti registrare il tuo oggetto, aggiungere un modello e una texture. + +Come puoi notare, il lampo dovrebbe essere generato 10 blocchi davanti a te, giocatore. + + diff --git a/versions/1.21/translated/it_it/develop/items/custom-tools.md b/versions/1.21/translated/it_it/develop/items/custom-tools.md new file mode 100644 index 000000000..59a472b28 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/custom-tools.md @@ -0,0 +1,104 @@ +--- +title: Utensili e Armi +description: Impara come si crea il tuo strumento e configurarne le proprietà. +authors: + - IMB11 +--- + +# Strumenti {#tools} + +Gli strumenti sono essenziali per la sopravvivenza e l'avanzamento, poiché permettono ai giocatori di raccogliere risorse, costruire edifici, e difendere sé stessi. + +## Creare un Materiale dello Strumento {#creating-a-tool-material} + +::: info +If you're creating multiple tool materials, consider using an `Enum` to store them. Vanilla does this in the `ToolMaterials` class, which stores all the tool materials that are used in the game. + +Questa classe può anche essere usata per determinare le proprietà del materiale del tuo strumento, legate a quelle dei materiali di strumenti vanilla. +::: + +Puoi creare un materiale dello strumento creando una nuova classe che lo eredita - in questo esempio, creeremo strumenti di "Guidite": + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Quando avrai creato il materiale del tuo strumento e l'avrai modificato a piacere, puoi creare un'istanza di esso da usare nei costruttori degli oggetti. + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Il materiale dello strumento informa il gioco sulle seguenti proprietà: + +### Durabilità - `getDurability()` {#durability} + +Quante volte si può usare lo strumento prima che si rompa: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Velocità di Rottura - `getMiningSpeedMultiplier()` {#mining-speed} + +Se lo strumento viene usato per rompere blocchi, quanto velocemente deve fare ciò? + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Per darti un riferimento, il materiale diamante ha come velocità di rottura `8.0F`, mentre quello di pietra ha come velocità `4.0F`. + +### Danno da Attacco - `getAttackDamage()` {#attack-damage} + +Quanti punti di danno deve causare lo strumento quando lo si usa come arma contro un'altra entità? + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Tag Invertito - `getMiningLevel()` {#inverse-tag} + +Il tag invertito mostra ciò che l'oggetto _**non**_ può rompere. Per esempio, usare il tag `BlockTags.INCORRECT_FOR_WOODEN_TOOL` non permette allo strumento di rompere certi blocchi: + +```json +{ + "values": [ + "#minecraft:needs_diamond_tool", + "#minecraft:needs_iron_tool", + "#minecraft:needs_stone_tool" + ] +} +``` + +Questo significa che lo strumento non può rompere blocchi che richiedono strumenti di diamante, ferro o pietra. + +Usiamo il tag degli strumenti di ferro. Questo non permetterà agli strumenti di Guidite di rompere blocchi che richiedono uno strumento più forte del ferro. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Puoi usare `TagKey.of(...)` per creare una chiave di tag personalizzata se vuoi usare un tag personalizzato. + +### Incantabilità - `getEnchantability()` {#enchantability} + +Quanto facile è ottenere livelli maggiori e migliori degli incantesimi con questo oggetto? Per riferimento, l'oro ha incantabilità 22, mentre la netherite ha incantabilità 15. + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### Ingredienti di Riparo - `getRepairIngredient()` {#repair-ingredient} + +Quale oggetto o oggetti si usano per riparare lo strumento? + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +## Creare Oggetti per gli Strumenti {#creating-tool-items} + +Con la stessa funzione di utilità della guida [Creare il Tuo Primo Oggetto](./first-item), puoi creare gli oggetti dei tuoi strumenti: + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Ricorda di aggiungerli ad un gruppo di oggetti se vuoi accedere ad essi dall'inventario in creativa! + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Dovrai anche aggiungere una texture, una traduzione e un modello per l'oggetto. Tuttavia, per i modelli, dovrai usare il modello `item/handheld` come genitore. + +Per questo esempio, useremo il modello e la texture seguenti per l'oggetto "Spada di Guidite": + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json) + +Texture + +Questo è praticamente tutto! Se passi al gioco dovresti vedere gli oggetti dei tuoi strumenti nella scheda strumenti del menu inventario in creativa. + +![Strumenti nell'inventario](/assets/develop/items/tools_1.png) diff --git a/versions/1.21/translated/it_it/develop/items/first-item.md b/versions/1.21/translated/it_it/develop/items/first-item.md new file mode 100644 index 000000000..8d2b21f0b --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/first-item.md @@ -0,0 +1,151 @@ +--- +title: Creare il Tuo Primo Oggetto +description: Impara come registrare un semplice oggetto e come aggiungergli texture, modello e nome. +authors: + - IMB11 + - dicedpixels +--- + +# Creare il Tuo Primo Oggetto {#creating-your-first-item} + +Questa pagina ti presenterà alcuni concetti chiave legati agli oggetti, e come registrargli e aggiungere loro texture, modello e nome. + +Se non ne sei al corrente, tutto in Minecraft è memorizzato in registry, e gli oggetti non fanno eccezione. + +## Preparare la Tua Classe dei Oggetti {#preparing-your-items-class} + +Per semplificare la registrazione degli oggetti, puoi creare un metodo che accetta un'istanza di un oggetto e una stringa come identificatore. + +Questo metodo creerà un oggetto con l'identificatore fornito e lo registrano nella registry degli oggetti del gioco. + +Puoi mettere questo metodo in una classe chiamata `ModItems` (o qualsiasi altro nome). + +Anche Mojang fa lo stesso per i suoi oggetti! Prendi ispirazione dalla classe `Items`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Registrare un Oggetto {#registering-an-item} + +Puoi ora registrare un oggetto con il metodo. + +Il costruttore dell'oggetto prende come parametro un'istanza della classe `Items.Settings`. Questa classe ti permette di configurare le proprietà dell'oggetto con vari metodi costruttori. + +::: tip +If you want to change your item's stack size, you can use the `maxCount` method in the `Items.Settings`/`FabricItemSettings` class. + +Questo non funzionerà se hai segnato un oggetto come danneggiabile, poiché la dimensione di uno stack è sempre 1 per oggetti danneggiabili per evitare duplicazioni. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Tuttavia, provando ora ad eseguire il client modificato, noterai che il nostro oggetto non esiste ancora nel gioco! Questo perché non hai inizializzato la classe staticamente. + +Per fare questo puoi aggiungere un metodo `initialize()` pubblico e statico alla tua classe e richiamarlo dall'[initializer della tua mod](./getting-started/project-structure#entrypoints). Per ora il metodo non deve contenere nulla. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java) + +Chiamare un metodo su una classe la inizializza staticamente se non è mai stata caricata prima - questo significa che tutti gli attributi `static` vengono calcolati. Questo è il motivo di questo metodo `initialize` fasullo. + +## Aggiungere l'Oggetto ad un Gruppo di Oggetti {#adding-the-item-to-an-item-group} + +:::info +Se volessi aggiungere l'oggetto a un `ItemGroup` personalizzato, consulta la pagina [Gruppi di Oggetti Personalizzati](./custom-item-groups) per maggiori informazioni. +::: + +Per questo esempio, aggiungeremo questo oggetto all'`ItemGroup` ingredienti, dovrai usare gli eventi dei gruppi di oggetti dell'API di Fabric - in particolare `ItemGroupEvents.modifyEntriesEvent` + +Questo si può fare nel metodo `initialize` della tua classe degli oggetti. + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Appena caricato il gioco, vedrai che il nostro oggetto è stato registrato, ed è nel gruppo di oggetti Ingredienti: + +![Oggetto nel gruppo ingredienti](/assets/develop/items/first_item_0.png) + +Tuttavia, gli manca il seguente: + +- Modello dell'Oggetto +- Texture +- Traduzione (nome) + +## Dare un Nome all'Oggetto {#naming-the-item} + +L'oggetto per ora non ha una traduzione, per cui dovrai aggiungerne una. La chiave di traduzione è già stata fornita da Minecraft: `item.mod_id.suspicious_substance`. + +Crea un nuovo file JSON presso: `src/main/resources/assets//lang/en_us.json` e mettici la chiave di traduzione, e il suo valore: + +```json +{ + "item.mod_id.suspicious_substance": "Suspicious Substance" +} +``` + +Puoi riavviare il gioco, o ricostruire la tua mod e premere F3+T per applicare le modifiche. + +## Aggiungere Texture e Modello {#adding-a-texture-and-model} + +Per dare al tuo oggetto una texture e un modello, ti basta creare un'immagine 16x16 come texture per il tuo oggetto e salvarla nella cartella `assets//textures/item`. Il nome del file è l'identificatore dell'oggetto, con estensione `.png`. + +Per questo esempio, puoi usare questa texture di esempio per `suspicious_substance.png` + +Texture + +Appena riavviato/ricaricato il gioco - dovresti vedere che l'oggetto ancora non ha texture, questo perché devi aggiungere un modello che usi questa texture. + +Creeremo un semplice modello `item/generated`, che prende come input solo una texture. + +Crea il modello JSON nella cartella `assets//models/item`, con lo stesso nome dell'oggetto; `suspicious_substance.json` + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) + +### Comprendere il Modello in JSON {#breaking-down-the-model-json} + +- `parent`: Questo è il modello genitore da cui questo modello erediterà. In questo caso è il modello `item/generated`. +- `textures`: Qui è dove definisci le texture per il modello. La chiave `layer0` è la texture che il modello userà. + +La maggior parte degli oggetti usa il modello `item/generated` come genitore, perché è un modello semplice che mostra semplicemente la texture. + +Ci sono alternative, tra cui `item/handheld` che si usa per oggetto da tenere nella mano del giocatore, come gli strumenti. + +Il tuo oggetto dovrebbe ora avere questo aspetto nel gioco: + +![Oggetto con il modello corretto](/assets/develop/items/first_item_2.png) + +## Rendere l'Oggetto Compostabile o Combustibile {#making-the-item-compostable-or-a-fuel} + +L'API di Fabric fornisce varie registry che si possono usare per aggiungere altre proprietà al tuo oggetto. + +Per esempio, per rendere il tuo oggetto compostabile, puoi usare la `CompostableItemRegistry`: + +@[code transcludeWith=:::_10](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +In alternativa, se vuoi rendere il tuo oggetto combustibile, puoi usare la classe `FuelRegistry`: + +@[code transcludeWith=:::_11](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Aggiungere una Ricetta Basilare {#adding-a-basic-crafting-recipe} + + + +Se vuoi aggiungere una ricetta per il tuo oggetto, devi posizione un file JSON della ricetta nella cartella `data//recipe`. + +Per maggiori informazioni sul formato delle ricette, consulta queste risorse: + +- [Generatore di Ricette JSON](https://crafting.thedestruc7i0n.ca/) +- [Minecraft Wiki - Recipe JSON](https://minecraft.wiki/w/Recipe#JSON_Format) + +## Tooltip Personalizzati {#custom-tooltips} + +Se vuoi che il tuo oggetto abbia un tooltip personalizzato, dovrai creare una classe che estenda `Item` e faccia override del metodo `appendTooltip`. + +:::info +Questo esempio usa la classe `LightningStick` creata nella pagina [Interazioni Personalizzate tra Oggetti](./custom-item-interactions). +::: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Ogni chiamata di `add()` aggiungerà una linea al tooltip. + +![Anteprima del Tooltip](/assets/develop/items/first_item_3.png) diff --git a/versions/1.21/translated/it_it/develop/items/food.md b/versions/1.21/translated/it_it/develop/items/food.md new file mode 100644 index 000000000..16bc8e81a --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/food.md @@ -0,0 +1,52 @@ +--- +title: Alimenti +description: Impara come aggiungere una FoodComponent ad un oggetto per renderlo edibile, e come configurarlo. +authors: + - IMB11 +--- + +# Alimenti {#food-items} + +Gli alimenti sono un aspetto cruciale di sopravvivenza in Minecraft, per cui quando si creano oggetti edibili devi considerare l'utilizzo del cibo con altri oggetti edibili. + +A meno che tu non voglia creare una mod con oggetti troppo potenti, dovresti tenere in considerazione: + +- Quanta fame aggiunge o toglie l'oggetto edibile? +- Quali effetti di pozione fornisce? +- È accessibile presto o tardi nel gioco? + +## Aggiungere la Componente Alimento {#adding-the-food-component} + +Per aggiungere la componente alimentare ad un oggetto, possiamo passarla all'istanza `Item.Setttings`: + +```java +new Item.Settings().food(new FoodComponent.Builder().build()) +``` + +Per ora questo rende l'oggetto edibile, e nulla di più. + +La classe `FoodComponent.Builder` ha molti metodo che ti permettono di modificare cosa succede quando un giocatore mangia il tuo oggetto: + +| Metodo | Descrizione | +| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `nutrition` | Imposta la quantità di punti fame che l'oggetto sazierà. | +| `saturationModifier` | Imposta la quantita di punti di saturazione che l'oggetto aggiungerà. | +| `alwaysEdible` | Permette al tuo oggetto di essere consumato indipendentemente dal livello di fame. | +| `snack` | Dichiara il tuo oggetto come snack. | +| `statusEffect` | Aggiunge un effetto di stato quando si mangia l'oggetto. Di solito si passa a questo metodo un'istanza di un effetto di stato e una probabilità, come percentuale decimale (`1f = 100%`) | + +Quando avrai modificato il costruttore come preferisci, puoi chiamare il metodo `build()` per ottenere la `FoodComponent`. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Come nell'esempio della pagina [Creare il Tuo Primo Oggetto](./first-item), useremo la componente sopra: + +@[code transcludeWith=:::poisonous_apple](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Questo rende l'oggetto: + +- Sempre edibile, può essere mangiato indipendentemente dal livello di fame. +- Uno "snack". +- Fornisce sempre Avvelenamento II per 6 secondi appena consumato. + + diff --git a/versions/1.21/translated/it_it/develop/items/potions.md b/versions/1.21/translated/it_it/develop/items/potions.md new file mode 100644 index 000000000..29296b702 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/items/potions.md @@ -0,0 +1,49 @@ +--- +title: Pozioni +description: Impara come aggiungere pozioni personalizzate per vari effetti di stato. +authors: + - dicedpixels + - PandoricaVi + - Drakonkinst + - JaaiDead +--- + +# Pozioni {#potions} + +Le pozioni sono oggetti consumabili che conferiscono un effetto a un'entità. Un giocatore può preparare delle pozioni usando l'Alambicco oppure ottenerle come oggetti attraverso varie meccaniche di gioco. + +## Pozioni Personalizzate {#custom-potions} + +Proprio come gli oggetti e i blocchi, le pozioni devono essere registrate. + +### Creare la Pozione {#creating-the-potion} + +Iniziamo dichiarando un attributo per conservare la tua istanza `Potion`. Useremo direttamente una classe che implementi `ModInitializer` per conservarla. + +@[code lang=java transclude={18-27}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +Passiamo una istanza di `StatusEffectInstance`, che prende 3 parametri: + +- `RegistryEntry type` - Un effetto. Qui usiamo il nostro effetto personalizzato. In alternativa puoi accedere agli effetti vanilla attraverso la classe vanilla `StatusEffects`. +- `int duration` - Durata dell'effetto espressa in tick di gioco. +- `int amplifier` - Un amplificatore per l'effetto. Per esempio, Sollecitudine II avrebbe un amplificatore di 1. + +:::info +Per creare il tuo effetto personalizzato per la pozione, per favore guarda la guida [Effetti](../entities/effects). +::: + +### Registrare la Pozione {#registering-the-potion} + +Nel nostro initializer, useremo l'evento `FabricBrewingRecipeRegistryBuilder.BUILD` per registrare la nostra pozione usando il metodo `BrewingRecipeRegistry.registerPotionRecipe`. + +@[code lang=java transclude={29-42}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +`registerPotionRecipe` prende 3 parametri: + +- `RegistryEntry input` - La voce di registry della pozione iniziale. Solitamente questa può essere una Ampolla d'Acqua o una Pozione Strana. +- `Item item` - L'oggetto che rappresenta l'ingrediente principale della pozione. +- `RegistryEntry output` - La voce di registry della pozione risultante. + +Una volta registrato, puoi distillare una pozione Tater usando una patata. + +![Effetto nell'inventario del giocatore](/assets/develop/tater-potion.png) diff --git a/versions/1.21/translated/it_it/develop/rendering/basic-concepts.md b/versions/1.21/translated/it_it/develop/rendering/basic-concepts.md new file mode 100644 index 000000000..7b42a8498 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/rendering/basic-concepts.md @@ -0,0 +1,162 @@ +--- +title: Concetti Base del Rendering +description: Impara i concetti base del rendering usando il motore grafico di Minecraft. +authors: + - IMB11 + - "0x3C50" +--- + +# Concetti Base del Rendering {#basic-rendering-concepts} + +::: warning +Although Minecraft is built using OpenGL, as of version 1.17+ you cannot use legacy OpenGL methods to render your own things. Instead, you must use the new `BufferBuilder` system, which formats rendering data and uploads it to OpenGL to draw. + +Per riassumere, devi usare il sistema di rendering di Minecraft, o crearne uno tuo che usa `GL.glDrawElements()`. +::: + +Questa pagina tratterà le basi del rendering usando il nuovo sistema, presentando terminologia e concetti chiave. + +Anche se molto del rendering in Minecraft viene astratto attraverso i vari metodi `DrawContext`, e probabilmente non ti servirà toccare nulla di quel che viene menzionato qui, è comunque importante capire le basi di come funziona il rendering. + +## Il `Tessellator` {#the-tessellator} + +Il `Tessellator` è la principale classe usata per renderizzare le cose in Minecraft. È un singleton, cioè solo un'istanza è presente in gioco. Puoi ottenere l'istanza usando `Tessellator.getInstance()`. + +## Il `BufferBuilder` {#the-bufferbuilder} + +Il `BufferBuilder` è la classe usata per formattare e caricare i dati di rendering su OpenGL. Viene usata per creare un buffer, che viene caricato su OpenGL per essere disegnato. + +Il `Tessellator` viene usato per creare un `BufferBuilder`, che viene usato per formattare e caricare i dati di rendering su OpenGL. + +### Inizializzare il `BufferBuilder` {#initializing-the-bufferbuilder} + +Prima di poter scrivere al `BufferBuilder`, devi inizializzarlo. Questo viene fatto usando `Tessellator#begin(...)`, che prende un `VertexFormat` e una modalità di disegno e restituisce un `BufferBuilder`. + +#### Formati dei Vertici {#vertex-formats} + +Il `VertexFormat` definisce gli elementi che includiamo nel nostro buffer di dati e precisa come questi elementi debbano essere trasmessi a OpenGL. + +I seguenti elementi `VertexFormat` sono disponibili: + +| Elemento | Formato | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | +| `BLIT_SCREEN` | `{ position (3 floats: x, y and z), uv (2 floats), color (4 ubytes) }` | +| `POSITION_COLOR_TEXTURE_LIGHT_NORMAL` | `{ position, color, texture uv, texture light (2 shorts), texture normal (3 sbytes) }` | +| `POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL` | `{ position, color, texture uv, overlay (2 shorts), texture light, normal (3 sbytes) }` | +| `POSITION_TEXTURE_COLOR_LIGHT` | `{ position, texture uv, color, texture light }` | +| `POSITION` | `{ position }` | +| `POSITION_COLOR` | `{ position, color }` | +| `LINES` | `{ position, color, normal }` | +| `POSITION_COLOR_LIGHT` | `{ position, color, light }` | +| `POSITION_TEXTURE` | `{ position, uv }` | +| `POSITION_COLOR_TEXTURE` | `{ position, color, uv }` | +| `POSITION_TEXTURE_COLOR` | `{ position, uv, color }` | +| `POSITION_COLOR_TEXTURE_LIGHT` | `{ position, color, uv, light }` | +| `POSITION_TEXTURE_LIGHT_COLOR` | `{ position, uv, light, color }` | +| `POSITION_TEXTURE_COLOR_NORMAL` | `{ position, uv, color, normal }` | + +#### Modalità di Disegno {#draw-modes} + +La modalità di disegno definisce come sono disegnati i dati. Sono disponibili le seguenti modalità di disegno: + +| Modalità di Disegno | Descrizione | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DrawMode.LINES` | Ogni elemento è fatto da 2 vertici ed è rappresentato come una linea singola. | +| `DrawMode.LINE_STRIP` | Il primo elemento richiede 2 vertici. Elementi addizionali vengono disegnati con un solo nuovo vertice, creando una linea continua. | +| `DrawMode.DEBUG_LINES` | Simile a `DrawMode.LINES`, ma la linea è sempre esattamente larga un pixel sullo schermo. | +| `DrawMode.DEBUG_LINE_STRIP` | Come `DrawMode.LINE_STRIP`, ma le linee sono sempre larghe un pixel. | +| `DrawMode.TRIANGLES` | Ogni elemento è fatto da 3 vertici, formando un triangolo. | +| `DrawMode.TRIANGLE_STRIP` | Inizia con 3 vertici per il primo triangolo. Ogni vertice aggiuntivo forma un nuovo triangolo con gli ultimi due vertici. | +| `DrawMode.TRIANGLE_FAN` | Inizia con 3 vertici per il primo triangolo. Ogni vertice aggiuntivo forma un triangolo con il primo e l'ultimo vertice. | +| `DrawMode.QUADS` | Ogni elemento è fatto da 4 vertici, formando un quadrilatero. | + +### Scrivere al `BufferBuilder` {#writing-to-the-bufferbuilder} + +Una volta che il `BufferBuilder` è inizializzato, puoi scriverci dei dati. + +Il `BufferBuilder` permette di costruire il nostro buffer, un vertice dopo l'altro. Per aggiungere un vertice, usiamo il metodo `buffer.vertex(matrix, float, float, float)`. Il parametro `matrix` è la matrice di trasformazione, che discuteremo più dettagliatamente in seguito. I tre parametri float rappresentano le coordinate (x, y, z) della posizione del vertice. + +Questo metodo restituisce un costruttore di vertice, che possiamo usare per specificare informazioni addizionali per il vertice. È cruciale seguire l'ordine del nostro `VertexFormat` definito quando aggiungiamo questa informazione. Se non lo facciamo, OpenGL potrebbe non interpretare i nostri dati correttamente. Dopo aver finito la costruzione di un vertice, se vuoi puoi continuare ad aggiungere altri vertici e dati al buffer. + +Importante è anche capire il concetto di culling. Il culling è il processo con cui si rimuovono facce di una forma 3D che non sono visibili dalla prospettiva dell'osservatore. Se i vertici per una faccia sono specificati nell'ordine sbagliato, la faccia potrebbe non essere renderizzata correttamente a causa del culling. + +#### Cos'è una Matrice di Trasformazione? {#what-is-a-transformation-matrix} + +Una matrice di trasformazione è una matrice 4x4 che viene usata per trasformare un vettore. In Minecraft, la matrice di trasformazione sta solo trasformando le coordinate che diamo nella chiamata del vertice. Le trasformazioni possono scalare il nostro modello, muoverlo e ruotarlo. + +A volte viene chiamata anche matrice di posizione, o matrice modello. + +Solitamente è ottenuta dalla classe `MatrixStack`, che può essere ottenuta attraverso l'oggetto `DrawContext`: + +```java +drawContext.getMatrices().peek().getPositionMatrix(); +``` + +#### Renderizzare una Striscia di Triangoli {#rendering-a-triangle-strip} + +Spiegare come scrivere al `BufferBuilder` è più semplice con un esempio pratico. Immaginiamo di voler renderizzare qualcosa usando la modalità di disegno `DrawMode.TRIANGLE_STRIP` e il formato vertice `POSITION_COLOR`. + +Disegneremo vertici nelle seguenti posizioni sul HUD (in ordine): + +```txt +(20, 20) +(5, 40) +(35, 40) +(20, 60) +``` + +Questo dovrebbe darci un diamante carino - siccome stiamo usando la modalità di disegno `TRIANGLE_STRIP`, il renderizzatore eseguirà i seguenti passaggi: + +![Quattro passaggi che mostrano il posizionamento dei vertici sullo schermo per formare due triangoli](/assets/develop/rendering/concepts-practical-example-draw-process.png) + +Siccome stiamo disegnando sulla HUD in questo esempio, useremo l'evento `HudRenderCallback`: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +Questo risulta nel seguente disegno sul HUD: + +![Risultato Finale](/assets/develop/rendering/concepts-practical-example-final-result.png) + +:::tip +Prova a giocare coi colori e le posizioni dei vertici per vedere che succede! Puoi anche provare a usare modalità di disegno e formati vertice differenti. +::: + +## La `MatrixStack` {#the-matrixstack} + +Dopo aver imparato come scrivere al `BufferBuilder`, ti starai chiedendo come trasformare il tuo modello - anche animarlo magari. Qui è dove entra in gioco la classe `MatrixStack`. + +La classe `MatrixStack` ha i seguenti metodi: + +- `push()` - Spinge una nuova matrice sullo stack. +- `pop()` - Elimina la matrice in cima allo stack. +- `peek()` - Restituisce la matrice in cima allo stack. +- `translate(x, y, z)` - Trasla la matrice in cima allo stack. +- `scale(x, y, z)` - Scala la matrice in cima allo stack. + +Puoi anche moltiplicare la matrice in cima allo stack usando i quaternioni, che tratteremo nella prossima sezione. + +Usando l'esempio di prima, possiamo ingrandire e rimpicciolire il nostro diamante usando la `MatrixStack` e il `tickDelta` - che è il tempo passato dall'ultimo frame. + +::: warning +You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. + +Assicurati di spingere lo stack di matrici prima di prendere una matrice di trasformazione! +::: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +![Un video che mostra il diamante ingrandito e rimpicciolito](/assets/develop/rendering/concepts-matrix-stack.webp) + +## Quaternioni (Cose che Ruotano) {#quaternions-rotating-things} + +I quaternioni sono un modo di rappresentare rotazioni in uno spazio 3D. Vengono usate per ruotare la matrice in cima al `MatrixStack` usando il metodo `multiply(Quaternion, x, y, z)`. + +Difficilmente dovrai usare una classe Quaternion direttamente, siccome Minecraft fornisce varie istanze Quaternion pre-costruite nella sua classe di utilità `RotationAxis`. + +Immaginiamo di voler ruotare il nostro diamante attorno all'asse z. Possiamo farlo usando il `MatrixStack` e il metodo `multiply(Quaternion, x, y, z)`. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +Il risultato è il seguente: + +![Un video che mostra il diamante che ruota attorno all'asse z](/assets/develop/rendering/concepts-quaternions.webp) diff --git a/versions/1.21/translated/it_it/develop/rendering/draw-context.md b/versions/1.21/translated/it_it/develop/rendering/draw-context.md new file mode 100644 index 000000000..012d72a79 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/rendering/draw-context.md @@ -0,0 +1,94 @@ +--- +title: Usare il Contesto di Disegno +description: Impara a usare la classe DrawContext per renderizzare varie forme, testi e texture. +authors: + - IMB11 +--- + +# Usare il Contesto di Disegno {#using-the-drawing-context} + +Questa pagina suppone che tu abbia guardato la pagina [Concetti Base del Rendering](./basic-concepts). + +La classe `DrawContext` è la principale classe usata per il rendering nel gioco. Viene usata per renderizzare forme, testi e texture, e come visto in precedenza, usata per manipolare le `MatrixStack` e i `BufferBuilder`. + +## Disegnare Forme {#drawing-shapes} + +La classe `DrawContext` può essere usata per disegnare facilmente forme **basate su quadrati**. Se vuoi disegnare triangoli, o altre forme non rettangolari, dovrai usare un `BufferBuilder`. + +### Disegnare Rettangoli {#drawing-rectangles} + +Puoi usare il metodo `DrawContext.fill(...)` per disegnare un rettangolo pieno. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Un rettangolo](/assets/develop/rendering/draw-context-rectangle.png) + +### Disegnare Contorni/Bordi {#drawing-outlines-borders} + +Immaginiamo di voler aggiungere un contorno al rettangolo che abbiamo disegnato. Possiamo usare il metodo `DrawContext.drawBorder(...)` per disegnare un contorno. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Rettangolo con bordo](/assets/develop/rendering/draw-context-rectangle-border.png) + +### Disegnare Linee Singole {#drawing-individual-lines} + +Possiamo usare i metodi `DrawContext.drawHorizontalLine(...)` e `DrawContext.drawVerticalLine(...)` per disegnare linee. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Linee](/assets/develop/rendering/draw-context-lines.png) + +## Il Gestore di Tagli {#the-scissor-manager} + +La classe `DrawContext` ha un gestore di tagli predefinito. Questo ti permette di ritagliare il rendering a un'area specifica. Questo è utile per renderizzare cose come consigli, o altri elementi che non dovrebbero essere renderizzati al di fuori di un'area specifica. + +### Usare il Gestore di Tagli {#using-the-scissor-manager} + +:::tip +Le regioni di taglio possono essere annidate! Ma assicurati di disabilitare il gestore di tagli tante volte quante lo abiliti. +::: + +Per abilitare il gestore di tagli, semplicemente usa il metodo `DrawContext.enableScissor(...)`. Similarmente per disabilitarlo usa il metodo `DrawContext.disableScissor()`. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Regione di taglio in azione](/assets/develop/rendering/draw-context-scissor.png) + +Come puoi vedere, anche se diciamo al gioco di renderizzare il gradiente attraverso tutto lo schermo, lo renderizza solo nella regione del taglio. + +## Disegnare Texture {#drawing-textures} + +Non c'è un solo modo "corretto" per disegnare texture su uno schermo, siccome il metodo `drawTexture(...)` ha tanti overload diversi. Questa sezione coprirà gli usi più comuni. + +### Disegnare una Texture Intera {#drawing-an-entire-texture} + +Generalmente, è raccomandato usare l'overload che specifica i parametri `textureWidth` e `textureHeight`. Questo perché la classe `DrawContext` assumerà questi valori se non li specifichi, e a volte potrebbe sbagliare. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Esempio di tutta la texture disegnata](/assets/develop/rendering/draw-context-whole-texture.png) + +### Disegnare una Porzione di una Texture {#drawing-a-portion-of-a-texture} + +Qui è dove `u` e `v` entrano in gioco. Questi parametri specificano l'angolo in alto a sinistra della texture da disegnare, e i parametri `regionWidth` e `regionHeight` specificano la dimensione della porzione della texture da disegnare. + +Prendiamo questa texture come esempio. + +![Texture del Libro di Ricette](/assets/develop/rendering/draw-context-recipe-book-background.png) + +Se vogliamo solo disegnare una regione che contiene la lente, possiamo usare i seguenti valori per `u`, `v`, `regionWidth` e `regionHeight`: + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Regione di Texture](/assets/develop/rendering/draw-context-region-texture.png) + +## Disegnare Testo {#drawing-text} + +La classe `DrawContext` ha vari metodi autoesplicativi per renderizzare testo - per brevità, non verranno trattati qui. + +Immaginiamo di voler disegnare "Hello World" sullo schermo. Possiamo usare il metodo `DrawContext.drawText(...)` per farlo. + +@[code lang=java transcludeWith=:::7](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Disegnare testo](/assets/develop/rendering/draw-context-text.png) diff --git a/versions/1.21/translated/it_it/develop/rendering/gui/custom-screens.md b/versions/1.21/translated/it_it/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..1134a2171 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/rendering/gui/custom-screens.md @@ -0,0 +1,64 @@ +--- +title: Schermate Personalizzate +description: Impara come creare schermate personalizzate per la tua mod. +authors: + - IMB11 +--- + +# Schermate Personalizzate {#custom-screens} + +:::info +Questa pagina si riferisce a schermate normali, non quelle gestite - queste schermate sono quelle aperte dal giocatore sul client, non quelle gestite dal server. +::: + +Le schermate sono essenzialmente le GUI con cui il giocatore interagisce, come la schermata del titolo, la schermata di pausa ecc. + +Puoi creare le tue schermate per mostrare contenuti personalizzati, un menu delle impostazioni personalizzato, e altro. + +## Creare una Schermata {#creating-a-screen} + +Per creare una schermata, devi estendere la classe `Screen` e fare override del metodo `init` - puoi anche eventualmente fare override del metodo `render` - ma assicurati di chiamare il suo metodo super altrimenti non renderizzerà lo sfondo, i widget ecc. + +Dovresti prendere nota del fatto che: + +- I Widget non vengono creati nel costruttore perché la schermata non è stata ancora inizializzata a quel punto - e alcune variabili, come `width` e `height`, non sono ancora disponibili o non sono ancora accurate. +- Il metodo `init` viene chiamato quando lo schermo viene inizializzato, e questo è il posto migliore per creare i widget. + - Si aggiungono widget usando il metodo `addDrawableChild`, che accetta qualsiasi widget disegnabile. +- Il metodo `render` viene chiamato ogni frame - puoi accedere al contesto di disegno, e alla posizione del mouse da questo metodo. + +Ad esempio, possiamo creare una semplice schermata che ha un pulsante e un'etichetta al di sopra. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Schermata Personalizzata 1](/assets/develop/rendering/gui/custom-1-example.png) + +## Aprire la Schermata {#opening-the-screen} + +Puoi aprire la schermata usando il metodo `setScreen` di `MinecraftClient` - puoi farlo da vari posti, come un'associazione a un tasto, un comando, o un gestore dei pacchetti del client. + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## Chiudere la Schermata {#closing-the-screen} + +Se vuoi chiudere lo schermo, semplicemente imposta la schermata a `null`: + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +Se vuoi essere sofisticato, e tornare alla schermata precedente, puoi passare la schermata corrente nel costruttore `CustomScreen` e conservala in una variabile, per poi tornare alla schermata precedente usando il metodo `close`. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +Ora, aprendo la schermata personalizzata, puoi passare la schermata corrente come secondo argomento - quindi quando chiami `CustomScreen#close` - ritornerà alla schermata precedente. + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/translated/it_it/develop/rendering/gui/custom-widgets.md b/versions/1.21/translated/it_it/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..bd992c29b --- /dev/null +++ b/versions/1.21/translated/it_it/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,39 @@ +--- +title: Widget Personalizzati +description: Impara come creare widget personalizzati per la tua schermata. +authors: + - IMB11 +--- + +# Widget Personalizzati {#custom-widgets} + +I Widget sono essenzialmente componenti di rendering containerizzate che possono essere aggiunti a una schermata, e i giocatori possono interagirci attraverso vari eventi come clic del mouse, pressione di tasti, e altro. + +## Creare un Widget {#creating-a-widget} + +Si possono seguire varie strade per creare una classe widget, come estendere `ClickableWidget`. Questa classe fornisce un sacco di utilità, come la gestione di larghezza, altezza, posizione, e quella degli eventi - implementa le interfacce `Drawable`, `Element`, `Narratable`, e `Selectable`: + +- `Drawable` - per il rendering - Necessario per registrare il widget alla schermata usando il metodo `addDrawableChild`. +- `Element` - per eventi - Necessario se vuoi gestire gli eventi come clic del mouse, pressione di tasti, e altro. +- `Narratable` - per l'accessibilità - Necessario per rendere il tuo widget accessibile a lettori di schermi e ad altri strumenti per l'accessibilità. +- `Selectable` - per la selezione - Necessario se vuoi rendere il tuo widget selezionabile usando il tasto Tab - anche questo aiuta per l'accessibilità. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## Aggiungere il Widget alla Schermata {#adding-the-widget-to-the-screen} + +Come tutti i widget, devi aggiungerlo alla schermata usando il metodo `addDrawableChild`, che è fornito dalla classe `Screen`. Assicurati di farlo nel metodo `init`. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Widget personalizzato sullo schermo](/assets/develop/rendering/gui/custom-widget-example.png) + +## Eventi di Widget {#widget-events} + +Puoi gestire eventi come clic del mouse, pressione di tasti, facendo override dei metodi `onMouseClicked`, `onMouseReleased`, `onKeyPressed`, e altri. + +Per esempio, puoi far cambiare colore al widget quando il mouse ci passa sopra usando il metodo `isHovered()` fornito dalla classe `ClickableWidget`: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![Esempio Evento Hovering](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/translated/it_it/develop/rendering/hud.md b/versions/1.21/translated/it_it/develop/rendering/hud.md new file mode 100644 index 000000000..3e2a07335 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/rendering/hud.md @@ -0,0 +1,30 @@ +--- +title: Rendering nel Hud +description: Impara a usare l'evento HudRenderCallback per renderizzare sul hud. +authors: + - IMB11 +--- + +# Rendering nel Hud {#rendering-in-the-hud} + +Abbiamo già parlato brevemente di come renderizzare cose sulla Hud nelle pagine [Concetti di Rendering di Base](./basic-concepts) e [Usare il Drawing Context](./draw-context), per cui in questa pagina ci concentreremo sull'evento `HudRenderCallback` e sul parametro `deltaTick`. + +## HudRenderCallback {#hudrendercallback} + +L'evento `HudRenderCallback` - fornito dall'API di Fabric - viene chiamato ogni frame, e viene usato per renderizzare cose sul HUD. + +Per registrarsi a questo evento, puoi semplicemente chiamare `HudRenderCallback.EVENT.register` e passare una lambda che prende come parametri un `DrawContext` e un `float` (deltaTick). + +Il contesto di disegno può essere usato per accedere a varie utilità di rendering fornite dal gioco, e per accedere allo stack di matrici puro. + +Dovresti dare un'occhiata alla pagina [Usare il Contesto di Disegno](./draw-context) per saperne di più riguardo al contesto di disegno. + +### DeltaTick {#deltatick} + +Il `deltaTick` è il tempo trascorso dall'ultimo frame, in secondi. Questo può essere usato per fare animazioni e altri effetti basati sul tempo. + +Per esempio, immagina di voler interpolare linearmente un colore nel tempo. Puoi usare il `deltaTickManager` per ottenere il deltaTick, e memorizzarlo nel tempo per interpolare il colore: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java) + +![Interpolare un colore nel tempo](/assets/develop/rendering/hud-rendering-deltatick.webp) diff --git a/versions/1.21/translated/it_it/develop/rendering/particles/creating-particles.md b/versions/1.21/translated/it_it/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..320076082 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/rendering/particles/creating-particles.md @@ -0,0 +1,72 @@ +--- +title: Creare Particelle Personalizzate +description: Impara come creare particelle personalizzate usando l'API di Fabric. +authors: + - Superkat32 +--- + +# Creare Particelle Personalizzate {#creating-custom-particles} + +Le particelle sono uno strumento potente. Possono aggiungere atmosfera a una bella scena, o aggiungere tensione durante una battaglia contro il boss. Aggiungiamone una! + +## Registrare una Particella Personalizzata {#register-a-custom-particle} + +Aggiungeremo una nuova particella "sparkle" che mimerà il movimento di una particella di una barra dell'End. + +Devi prima registrare un `ParticleType` nell'[initializer della tua mod](./getting-started/project-structure#entrypoints) usando l'id della mod. + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +La stringa "sparkle_particle" in minuscolo è il percorso JSON per la texture della particella. Dovrai successivamente creare un nuovo file JSON con lo stesso nome. + +## Registrazione Lato-Client {#client-side-registration} + +Dopo aver registrato la particella nell'initializer della tua mod, dovrai anche registrare la particella nell'initializer lato client. + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +In questo esempio, stiamo registrando la nostra particella dal lato client. Stiamo dando un po' di movimento alla particella usando la fabbrica della particella della barra dell'End. Questo vuol dire che la nostra particella si muoverà proprio come una particella di una barra dell'End. + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- Combinazione per IntelliJ: Ctrl+Alt+B +- Combinazione per Visual Studio Code: Ctrl+F12 + ::: + +## Creare un File JSON e Aggiungere le Texture {#creating-a-json-file-and-adding-textures} + +Dovrai creare 2 cartelle all'interno della cartella `resources/assets//`. + +| Percorso della Cartella | Spiegazione | +| ----------------------- | ----------------------------------------------------------------------------------------------- | +| `/textures/particle` | La cartella `particle` conterrà tutte le texture per tutte le tue particelle. | +| `/particles` | La cartella `particles` conterrà tutti i file json per tutte le tue particelle. | + +Per questo esempio, avremo una sola texture in `textures/particle` chiamata "sparkle_particle_texture.png". + +Dopo, crea un nuovo file JSON in `particles` con lo stesso nome del percorso JSON che hai usato quando hai registrato il tuo ParticleType. Per questo esempio, dovremo creare `sparkle_particle.json`. Questo file è importante perché fa conoscere a Minecraft quali texture dovrebbe usare la nostra particella. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +:::tip +Puoi aggiungere altre texture al vettore `textures` per creare un animazione per la particella. La particella scorrerà attraverso le texture nel vettore, iniziando dalla prima. +::: + +## Testare la Nuova Particella {#testing-the-new-particle} + +Una volta completato il file JSON e salvato il tuo lavoro, puoi aprire Minecraft e testare tutto! + +Puoi controllare se tutto ha funzionato scrivendo il comando seguente: + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![Dimostrazione della particella](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +:::info +La particella comparirà all'interno del giocatore con questo comando. Probabilmente dovrai camminare all'indietro per vederla effettivamente. +::: + +In alternativa, puoi anche usare un blocco comandi per far apparire la particella usando lo stesso comando. diff --git a/versions/1.21/translated/it_it/develop/sounds/custom.md b/versions/1.21/translated/it_it/develop/sounds/custom.md new file mode 100644 index 000000000..2482190e4 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/sounds/custom.md @@ -0,0 +1,63 @@ +--- +title: Creare Suoni Personalizzati +description: Impara a usare e aggiungere un nuovo suono con la registry. +authors: + - JR1811 +--- + +# Creare Suoni Personalizzati {#creating-custom-sounds} + +## Preparare il File Audio {#preparing-the-audio-file} + +I tuoi file audio devono essere formattati in un modo specifico. OGG Vorbis è un formato container aperto per dati multimediali, tra cui audio, e viene usato per i file audio di Minecraft. Per evitare problemi nel modo in cui Minecraft gestisce le distanze, il tuo audio deve essere solo su un singolo canale (Mono). + +Molti software DAW (Digital Audio Workstation) odierni riescono a importare ed esportare usando questo formato. Nell'esempio seguente il software open-source gratuito "[Audacity](https://www.audacityteam.org/)" sarà usato per portare i file audio al formato corretto, tuttavia qualunque altro DAW sarà più che sufficiente. + +![File audio non preparato in Audacity](/assets/develop/sounds/custom_sounds_0.png) + +In questo esempio, il suono di un [fischio](https://freesound.org/people/strongbot/sounds/568995/) viene importato in Audacity. Attualmente questo è salvato come file `.wav` e ha due canali audio (Stereo). Modifica il suono come preferisci e assicurati di cancellare uno dei canali usando il menu a tendina in cima alla "testina". + +![Separare traccia Stereo](/assets/develop/sounds/custom_sounds_1.png) + +![Eliminare uno dei canali](/assets/develop/sounds/custom_sounds_2.png) + +Quando devi esportare o renderizzare un file audio, assicurati di scegliere il formato del file OGG. Alcuni DAW, come REAPER, potrebbero supportare formati audio OGG a più strati. In questo caso OGG Vorbis dovrebbe funzionare senza problemi. + +![Esportare come file OGG](/assets/develop/sounds/custom_sounds_3.png) + +Inoltre tieni a mente che un file audio può aumentare drasticamente le dimensioni del file della tua mod. Se necessario, comprimi l'audio quando stai modificando ed esportando il file, per mantenere le sue dimensioni al minimo. + +## Caricare il File Audio {#loading-the-audio-file} + +Aggiungi un nuovo percorso `resources/assets//sounds` per i suoni della tua mod, e trasferisci qui il file audio esportato `metal_whistle.ogg`. + +Se non esiste ancora, crea il file `resources/assets//sounds.json` e aggiungici i tuoi suoni. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json) + +La voce subtitle fornisce un contesto più approfondito per il giocatore. Il nome del sottotitolo è usato nei file di lingua nel percorso `resources/assets//lang` e verrà visualizzato se l'impostazione dei sottotitoli nel gioco è attiva e se questo suono personalizzato viene riprodotto. + +## Registrare il Suono Personalizzato {#registering-the-custom-sound} + +Per aggiungere il suono personalizzato alla mod, registra un SoundEvent nell'[initializer della tua mod](./getting-started/project-structure#entrypoints). + +```java +Registry.register(Registries.SOUND_EVENT, Identifier.of(MOD_ID, "metal_whistle"), + SoundEvent.of(Identifier.of(MOD_ID, "metal_whistle"))); +``` + +## Ripulire il Disordine {#cleaning-up-the-mess} + +A seconda di quante voci ci sono nella Registry, le cose potrebbero presto sfuggire di mano. Per evitare che ciò accada, possiamo fare uso di una nuova classe ausiliaria. + +Aggiungi due nuovi metodi alla classe ausiliaria appena creata. Uno che registra tutti i suoni, e uno che viene usato per inizializzare questa classe in primo luogo. Dopo di che, puoi comodamente aggiungere nuovi attributi `SoundEvent` statici personalizzati a seconda delle necessità. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java) + +Facendo così, basta che l'initializer della tua mod implementi una riga sola per registrare tutti i SoundEvent personalizzati. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java) + +## Usare il SoundEvent Personalizzato {#using-the-custom-soundevent} + +Usa la classe ausiliaria per accedere al SoundEvent personalizzato. Consulta la pagina [Riprodurre Suoni](./using-sounds) per imparare come riprodurre i suoni. diff --git a/versions/1.21/translated/it_it/develop/sounds/dynamic-sounds.md b/versions/1.21/translated/it_it/develop/sounds/dynamic-sounds.md new file mode 100644 index 000000000..a7c1e7b50 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/sounds/dynamic-sounds.md @@ -0,0 +1,354 @@ +--- +title: Suoni Dinamici +description: Crea suoni più dinamici e interattivi +authors: + - JR1811 +--- + +# Suoni Dinamici {#create-dynamic-and-interactive-sounds} + +:::info +Questa pagina è basata sulle pagine [Riprodurre Suoni](../sounds/using-sounds) e [Creare Suoni Personalizzati](../sounds/custom)! +::: + +## Problemi con i `SoundEvents` {#problems-with-soundevents} + +Come abbiamo imparato nella pagina [Usare i Suoni](../sounds/using-sounds), è preferibile usare i `SoundEvent` sul lato logico server, anche se è un po' controintuitivo. Dopo tutto, è il client che deve gestire il suono, trasmesso alle tue cuffie, no? + +Questo modo di pensare è corretto. Tecnicamente è il lato client che dovrebbe gestire l'audio. Tuttavia, per la semplice riproduzione di un `SoundEvent`, il lato server ha preparato un passo enorme che potrebbe non essere ovvio a prima vista. Quali client dovrebbero poter sentire quel suono? + +Usare il suono sul lato logico server risolverà il problema della trasmissione dei `SoundEvent`. Per farla semplice, a ogni client (`ClientPlayerEntity`) nel raggio tracciato viene inviato un pacchetto di rete per riprodurre un certo suono specifico. L'evento audio viene praticamente trasmesso dal lato logico server, a ogni client partecipante, senza che tu te ne debba preoccupare. Il suono è riprodotto una volta sola, con i valori di volume e tono specificati. + +Ma, e se questo non bastasse? E se il suono dovesse essere riprodotto in loop? E se dovesse cambiare il volume e il tono in maniera dinamica durante la riproduzione? Tutto questo magari in base a valori provenienti da cose come `Entities` o `BlockEntities`? + +La semplice strategia di usare i `SoundEvent` sul lato logico server non basta in questo caso. + +## Preparare il File Audio {#preparing-the-audio-file} + +Creeremo un nuovo audio che andrà in **loop** per un altro `SoundEvent`. Se riesci a trovare un file audio che già va in loop perfettamente, ti basta seguire i passaggi da [Creare Suoni Personalizzati](../sounds/custom). Se il suono non va ancora in loop perfettamente, dobbiamo prepararlo affinché faccia ciò. + +Ripeto, la maggior parte delle DAW (Workstation Audio Digitali) moderne dovrebbero essere in grado di fare questo, ma preferisco usare [Reaper](https://www.reaper.fm/) se la modifica dell'audio è un po' più avanzata. + +### Configurazione {#set-up} + +Il [suono da cui partiamo](https://freesound.org/people/el-bee/sounds/644881/) proverrà da un motore. + + + +Carichiamo il file nella DAW che abbiamo scelto. + +![Reaper in cui si è caricato il file audio](/assets/develop/sounds/dynamic-sounds/step_0.png) + +Possiamo sentire e notare che il motore viene avviato all'inizio e interrotto alla fine, il che non è ottimo per i suoni in loop. Tagliamo via quelle parti e regoliamo le maniglie della selezione del tempo perché corrispondano con la nuova lunghezza. Attiva anche la modalità `Toggle Repeat` così che l'audio vada in loop mentre lo regoliamo. + +![File audio tagliato](/assets/develop/sounds/dynamic-sounds/step_1.png) + +### Rimuovere Elementi Audio Dirompenti {#removing-disruptive-audio-elements} + +Se ascoltiamo con attenzione, c'è un segnale acustico sullo sfondo, che potrebbe provenire dalla macchina. Penso che questo non suonerebbe bene nel gioco, per cui proviamo a toglierlo. + +È un suono costante, la cui frequenza rimane al di sopra della lunghezza dell'audio. Per questo un semplice filtro EQ dovrebbe essere sufficiente per filtrarlo. + +Reaper include già un filtro EQ chiamato "ReaEQ". Questo potrebbe essere localizzato in altri posti o avere nomi diversi in altre DAW, ma l'utilizzo dell'EQ è uno standard nella maggior parte delle DAW odierne. + +Se sei sicuro che la tua DAW non disponga di un filtro EQ, cerca alternative VST gratuite online che tu possa installare sulla DAW di tua scelta. + +In Reaper usa la Finestra Effetti per aggiungere l'effetto audio "ReaEQ", o altri EQ. + +![Aggiungere un filtro EQ](/assets/develop/sounds/dynamic-sounds/step_2.png) + +Riproducendo adesso l'audio, tenendo la finestra del filtro EQ aperta, il filtro EQ mostrerà l'audio in entrata sul display. +Lì si notano tante protuberanze. + +![Identificazione del problema](/assets/develop/sounds/dynamic-sounds/step_3.png) + +Se non sei un ingegnere audio allenato, questa parte è abbastanza sperimentazione, andando a tentativi. C'è una protuberanza piuttosto notevole tra i nodi 2 e 3. Muoviamo i nodi in modo che si abbassi la frequenza solo per quella parte. + +![Frequenza problematica abbassata](/assets/develop/sounds/dynamic-sounds/step_4.png) + +Inoltre altri effetti si possono ottenere con un semplice filtro EQ. Per esempio, tagliare le frequenze alte e/o basse può dare l'impressione di suoni trasmessi via audio. + +Puoi anche sovrapporre più file audio, cambiare il tono, aggiungere del riverbero o usare effetti di suono più elaborati come "bit-crusher". La progettazione di suoni può essere divertente, soprattutto se trovi delle belle variazioni di suono dei tuoi audio per caso. La sperimentazione è la chiave, e magari alla fine il tuo suono sarà meglio di come è cominciato. + +Andremo avanti con il filtro EQ soltanto, poiché l'abbiamo usato per togliere la frequenza problematica. + +### Paragone {#comparison} + +Confrontiamo il file originale con la versione ritoccata. + +Nel suono originale puoi distinguere un segnale acustico proveniente forse da un elemento elettrico del motore. + + + +Con il filtro EQ siamo riusciti a toglierlo quasi del tutto. Sicuramente è più piacevole da sentire. + + + +### Fare in Modo che Vada in Loop {#making-it-loop} + +Se lasciassimo che il suono si riproduca fino alla fine e ricominci dall'inizio, possiamo chiaramente sentire quando avviene la transizione. L'obiettivo è liberarci di questo applicando una transizione fluida. + +Inizia tagliando via una parte dal fondo, grande quanto vuoi che sia lunga la transizione, e posizionala all'inizio di una nuova traccia audio. +In Reaper puoi dividere l'audio semplicemente muovendo il cursore dalla posizione del taglio e premendo S. + +![Tagliare il fondo e muoverlo ad una nuova traccia](/assets/develop/sounds/dynamic-sounds/step_6.png) + +Potresti dover copiare l'effetto audio EQ della prima traccia audio anche sulla seconda. + +Ora lascia che la parte in fondo della nuova traccia si dissolva in chiusura, e che l'inizio della prima traccia audio si dissolva in apertura. + +![Loop con effetti di dissolvenza sulle tracce audio](/assets/develop/sounds/dynamic-sounds/step_7.png) + +### Esportazione {#exporting} + +Esporta l'audio con le due tracce, ma con un solo canale audio (Mono) e crea un nuovo `SoundEvent` per quel file `.ogg` nella tua mod. +Se non sei certo di come farlo, controlla la pagina [Creare Suoni Personalizzati](../sounds/custom). + +Ciò che abbiamo chiamato `ENGINE_LOOP` è il suono in loop del motore completato per il `SoundEvent`. + + + +## Usare una `SoundInstance` {#using-a-soundinstance} + +Per riprodurre suoni sul lato client, è necessaria una `SoundInstance`. Tuttavia utilizzano comunque un `SoundEvent`. + +Se vuoi solo riprodurre qualcosa come un clic su un elemento dell'interfaccia grafica, esiste già la classe `PositionedSoundInstance`. + +Tieni a mente che questo sarà riprodotto solo sul client che ha eseguito questa parte del codice in particolare. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java) + +:::warning +Si prega di notare che la classe `AbstractSoundInstance`, da cui le `SoundInstance` ereditano, ha l'annotazione `@Environment(EnvType.CLIENT)`. + +Questo significa che questa classe (e tutte le sue sottoclassi) saranno disponibili solo lato client. + +Se provassi ad usarla in un contesto logico lato server, potresti non notare inizialmente il problema in Giocatore Singolo, ma un server in ambiente Multiplayer crasherà, poiché non riuscirà a trovare quella parte del codice. + +Se trovi difficoltà con queste questioni, si consiglia di creare la tua mod dal [Generatore di Mod Modello online](https://fabricmc.net/develop/template) +attivando l'opzione `Split client and common sources`. +::: + +--- + +Una `SoundInstance` può essere molto più potente rispetto a una semplice riproduzione di un suono una volta. + +Dai un'occhiata alla classe `AbstractSoundInstance` e a quali tipi di valori può tenere in considerazione. +A parte le solite variabili di volume e tono, memorizza anche le coordinate XYZ, e un'opzione perché si ripeta dopo aver finito il `SoundEvent`. + +Poi, dando un'occhiata alla sua sottoclasse `MovingSoundInstance, viene anche introdotta l'interfaccia `TickableSoundInstance`, che aggiunge funzionalità legate ai tick alla `SoundInstance\`. + +Per cui per sfruttare queste utilità, basta creare una nuova classe per la tua `SoundInstance` personalizzata ed estendere `MovingSoundInstance`. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/CustomSoundInstance.java) + +Usare la tua `Entity` o il tuo `BlockEntity` personalizzati invece dell'istanza basilare `LivingEntity` può darti ancora più controllo, per esempio nel metodo `tick()` basato su metodi accessori, ma non devi per forza far riferimento ad una fonte di suono del genere. Invece di ciò puoi anche accedere alla `BlockPos` da altrove, o addirittura impostarla manualmente una volta sola nel costruttore soltanto. + +Tieni solo a mente che tutti gli oggetti a cui fai riferimento nella `SoundInstance` sono le versioni lato client. +In certe circostanze specifiche, le proprietà di un'entità dal lato logico server possono differire dalla controparte lato client. +Se noti che i tuoi valori non si allineano, assicurati che siano sincronizzati o con i `TrackedData` dell'entità, o con pacchetti S2C (da server a client) di `BlockEntity` o con pacchetti di rete S2C completamente personalizzati. + +Dopo aver finito di creare la tua `SoundInstance` personalizzata, è tutto pronto per usarla ovunque, a condizione che venga eseguita lato client con il gestore di suoni. +Allo stesso modo, puoi anche fermare la `SoundInstance` personalizzata manualmente, se necessario. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/FabricDocsDynamicSound.java) + +Il loop di suono sarà adesso riprodotto solo sul client che ha eseguito quella `SoundInstance`. In questo caso, il suono seguirà la `ClientPlayerEntity` stessa. + +Così abbiamo concluso la spiegazione di come creare e usare una semplice `SoundInstance` personalizzata. + +## SoundInstance Avanzate {#advanced-soundinstances} + +:::warning +Il contenuto seguente tratta di un argomento avanzato. + +Da questo punto in poi è necessaria una conoscenza solida di Java, programmazione a oggetti, tipi generici e sistemi di callback. + +Conoscere anche le `Entities`, i `BlockEntities` e il networking personalizzato aiuterà anche molto nella comprensione di questi casi e delle applicazioni pratiche dei suoni avanzati. +::: + +Per mostrare un esempio di come si possano creare sistemi di `SoundInstance` più elaborati, aggiungeremo funzionalità ulteriori, astrazioni e utilità per rendere il lavoro con suoni del genere in contesti più larghi più semplice, dinamico e flessibile. + +### Teoria {#theory} + +Ragioniamo un po' riguardo al nostro obiettivo con la `SoundInstance`. + +- Il suono deve rimanere in loop fintanto che il `EngineBlockEntity` personalizzato a esso collegato è in esecuzione +- La `SoundInstance` dovrebbe muoversi, seguendo la posizione del `EngineBlockEntity` personalizzato _(La `BlockEntity` non si muoverà, per cui questo sarebbe più utile con le `Entities`)_ +- Ci servono transizioni fluide. L'accensione e lo spegnimento non dovrebbero mai essere istantanei. +- Cambiare il volume e il tono in base a fattori esterni (per esempio della fonte del suono) + +Insomma, dobbiamo tener traccia di un'istanza di un `BlockEntity` personalizzato, regolare i valori di volume e tono mentre la `SoundInstance` è in esecuzione in base a valori provenienti da quel `BlockEntity` personalizzato, e implementare "Stati di Transizione". + +Se hai intenzione di creare più `SoundInstance` diverse, che si comportino in maniere diverse, consiglierei di creare una nuova classe astratta `AbstractDynamicSoundInstance`, che implementi il comportamento predefinito e lasciare che le classi `SoundInstance` la estendano. + +Se invece ne userai solo una, puoi saltare la creazione della superclasse astratta, e implementare invece quella funzionalità direttamente nella tua classe `SoundInstance` personalizzata. + +Sarebbe anche una buona idea avere una posizione centralizzata dove le `SoundInstance` vengono tracciate, riprodotte e interrotte. In altre parole deve gestire i segnali in ingresso, come quelli provenienti da pacchetti di rete S2C personalizzati, elencare tutte le istanze in esecuzione e gestire i casi particolari, per esempio quali suoni è permesso riprodurre allo stesso tempo e quali suoni disattiverebbero potenzialmente altri suoni se attivati. +Per fare ciò si può creare una nuova classe `DynamicSoundManager`, per interagire con questo sistema sonoro facilmente. + +Tutto sommato il nostro sistema sonoro potrebbe avere questo aspetto, una volta completato. + +![Struttura del Sistema Sonoro Personalizzato](/assets/develop/sounds/dynamic-sounds/custom-dynamic-sound-handling.jpg) + +:::info +Tutti questi enum, interfacce e classi saranno create da zero. Adatta il sistema e le utilità alla tua situazione specifica. +Questo è solo un esempio su come ci si può approcciare ad argomenti del genere. +::: + +### Interfaccia `DynamicSoundSource` {#dynamicsoundsource-interface} + +Se scegli di creare una nuova classe `AbstractDynamicSoundInstance` personalizzata e più modulare, da usare come superclasse, potresti voler fare riferimento non solo ad un tipo singolo di `Entity` ma a più tipi diversi, o anche ad un `BlockEntity`. + +In quel caso la chiave è sfruttare l'astrazione. +Invece di fare riferimento, per esempio, direttamente a un `BlockEntity` personalizzato, tener solo conto di un'interfaccia che fornisce i dati risolve quel problema. + +D'ora in poi useremo un'interfaccia personalizzata chiamata `DynamicSoundSource`. È da implementare in tutte le classi che vogliono sfruttare quelle funzionalità di suoni dinamici, come il tuo `BlockEntity` personalizzato, le entità o addirittura, usando Mixin, su classi preesistenti come `ZombieEntity`. In pratica contiene solo i dati necessari della fonte di suono. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/DynamicSoundSource.java) + +Dopo aver creato questa interfaccia, assicurati di implementarla anche nelle classi ove necessario. + +:::info +Questa è un'utilità che potrebbe essere usata sia lato client sia lato logico server. + +Per cui questa interfaccia dovrebbe essere memorizzata nei package comuni, non in quelli esclusivi del client, se usi l'opzione "split sources". +::: + +### Enum `TransitionState` {#transitionstate-enum} + +Come detto prima, puoi interrompere la `SoundInstance` con il `SoundManager` del client, ma questo farà in modo che la `SoundInstance` si zittisca immediatamente. +Il nostro obiettivo non è, quando si riceve un segnale di stop, di interrompere il suono ma di eseguire una fase di chiusura del suo "Stato di Transizione". Solo dopo che la fase di chiusura è stata completata, si deve interrompere la `SoundInstance` personalizzata. + +Uno `TransitionState` è un enum appena creato, che contiene tre valori. Essi verranno usati per tener traccia della fase in cui si trova il suono. + +- Fase `STARTING`: iniziando dal silenzio, il volume del suono aumenta lentamente +- Fase `RUNNING`: il suono viene riprodotto normalmente +- Fase `ENDING`: iniziando dal volume originario esso diminuisce lentamente fino al silenzio + +Tecnicamente basterebbe un semplice enum con le fasi. + +```java +public enum TransitionState { + STARTING, RUNNING, ENDING +} +``` + +Ma quando quei valori vengono inviati tramite rete, potresti voler definire un `Identifier` per esse o anche aggiungere altri valori personalizzati. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/TransitionState.java) + +:::info +Ripeto, se stai usando le "split sources" devi ragionare su dove si posiziona questo enum. +Tecnicamente, solo le `SoundInstance` personalizzate, che sono solo disponibili lato client, useranno quei valori dell'enum. + +Ma se questo enum venisse usato altrove, per esempio in pacchetti di rete personalizzati, potresti anche dover mettere l'enum nei package comuni invece dei package esclusivi del client. +::: + +### Interfaccia `SoundInstanceCallback` {#soundinstancecallback-interface} + +Questa interfaccia viene usata come callback. Per ora ci basta un metodo `onFinished`, ma puoi anche aggiungere i tuoi metodi personalizzati se dovessi inviare anche altri segnali dall'oggetto `SoundInstance`. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/SoundInstanceCallback.java) + +Implementa quest'interfaccia in qualsiasi classe che deve poter gestire segnali in ingresso, per esempio la `AbstractDynamicSoundInstance` che presto creeremo, e aggiungi le funzionalità nella `SoundInstance` personalizzata stessa. + +### Classe `AbstractDynamicSoundInstance` {#abstractdynamicsoundinstance-class} + +Finalmente cominciamo a lavorare sul cuore del sistema di `SoundInstance` dinamiche. `AbstractDynamicSoundInstance` è la classe `abstract` che dobbiamo creare. +Essa implementa le funzioni e utilità predefinite caratteristiche della nostra `SoundInstance` personalizzata, che da essa erediterà. + +Possiamo considerare la `CustomSoundInstance` di [poco fa](#using-a-soundinstance) e migliorarla. +Invece della `LivingEntity` faremo ora riferimento alla `DynamicSoundSource`. +Inoltre definiremo altre proprietà. + +- `TransitionState` per tener conto della fase attuale +- Durate in tick di quanto lunghe sono le fasi d'inizio e di fine +- Valori minimi e massimi per volume e tono +- Valore booleano per indicare se questa istanza è terminata e può essere ripulita +- Gestori dei tick per tener traccia del progresso corrente del suono +- Un callback che restituisce un segnale finale al `DynamicSoundManager` per la ripulizia, quando la `SoundInstance` è terminata + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Poi configuriamo i valori iniziali predefiniti per la `SoundInstance` personalizzata nel costruttore della classe astratta. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Dopo aver finito il costruttore, devi permettere alla `SoundInstance` di essere riprodotta. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Ecco qui la parte fondamentale di questa `SoundInstance` dinamica. In base al tick corrente dell'istanza, può applicare vari valori e comportamenti. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Come puoi notare, non abbiamo ancora applicato alcuna modulazione a volume e tono qui. Applichiamo solo il comportamento condiviso. +Per cui, in questa classe `AbstractDynamicSoundInstance`, forniamo solo la struttura basilare e gli strumenti per le sottoclassi, e saranno queste a decidere il genere di modulazione che vogliono applicare. + +Diamo un'occhiata ad alcuni esempi di strategie per quella modulazione del suono. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +Come noti, valori normalizzati combinati con interpolazione lineare (lerp) permettodo di adattare i valori ai limiti sonori preferiti. +Tieni a mente che, aggiungendo metodi multipli che modificano lo stesso valore, devi fare attenzione e regolare il modo in cui lavorano insieme tra loro. + +Ora dobbiamo solo aggiungere il resto dei metodi di utilità, e abbiamo finito la classe `AbstractDynamicSoundInstance`. + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/sound/AbstractDynamicSoundInstance.java) + +### Esempio d'Implementazione di `SoundInstance` {#example-soundinstance-implementation} + +Dando un'occhiata all'effettiva classe `SoundInstance` personalizzata, che estende l'`AbstractDynamicSoundInstance` appena creata, dobbiamo solo pensare a quali condizioni porterebbero all'interruzione del suono e a quale modulazione vogliamo applicare al suono. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/instance/EngineSoundInstance.java) + +### Classe `DynamicSoundManager` {#dynamicsoundmanager-class} + +Abbiamo discusso [poco fa](#using-a-soundinstance) come si riproduce e interrompe una `SoundInstance`. Per ripulire, centralizzare e gestire quelle interazioni, puoi creare un tuo gestore di `SoundInstance` personalizzato basato su di esso. + +Questa nuova classe `DynamicSoundManager` gestirà le `SoundInstance` personalizzate, quindi anch'essa sarà solo disponibile lato client. Oltre a ciò, un client dovrebbe permettere l'esistenza solo di un'istanza di questa classe. Gestori multipli di suoni per un client solo non hanno molto senso, e complicano ulteriormente le interazioni. +Usiamo quindi il ["Modello di Progettazione Singleton"](https://refactoring.guru/design-patterns/singleton/java/example). + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java) + +Dopo aver creato la corretta struttura basilare, puoi aggiungere i metodi necessari per interagire con il sistema sonoro. + +- Riprodurre suoni +- Interrompere suoni +- Controllare se un suono è attualmente in riproduzione + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/sound/DynamicSoundManager.java) + +Invece di avere solo una lista di tutte le `SoundInstance` attualmente in riproduzione, puoi anche tener traccia di quali fonti sonore stanno riproducendo quali suoni. +Per esempio, un motore che riproduce due suoni di un motore allo stesso tempo non ha senso, però più motori, ciascuno dei quali riproduce i propri suoni, è un caso valido. Per semplicità abbiamo solo creato una `List`, ma spesso una `HashMap` di una `DynamicSoundSource` e una `AbstractDynamicSoundInstance` potrebbe essere una scelta migliore. + +### Usare il Sistema Sonoro Avanzato {#using-the-advanced-sound-system} + +Per usare questo sistema sonoro, basta sfruttare i metodi di `DynamicSoundManager` o di `SoundInstance`. Usando `onStartedTrackingBy` e `onStoppedTrackingBy` delle entità, o anche solo networking S2C personalizzato, puoi ora avviare e interrompere le tue `SoundInstance` dinamiche personalizzate. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/network/ReceiveS2C.java) + +Il prodotto finale può regolare il proprio volume in base alla fase di suono, per rendere fluide le transizioni, e cambiare il tono in base a un valore di stress che proviene dalla fonte sonora. + + + +Potresti anche volendo aggiungere un altro valore alla tua fonte sonora, che tiene traccia di un valore "surriscaldamento", e fare in modo che una `SoundInstance` di un fischio/sibilo aumenti lentamente se il valore è sopra a 0; o ancora aggiungere una nuova interfaccia alla tua `SoundInstance` dinamica personalizzata, che assegni un valore di priorità ai tipi di suono, e permette di scegliere quale suono riprodurre se questi vanno in conflitto tra loro. + +Con il sistema corrente, puoi facilmente gestire più `SoundInstance` insieme e progettare l'audio secondo i tuoi bisogni. diff --git a/versions/1.21/translated/it_it/develop/sounds/using-sounds.md b/versions/1.21/translated/it_it/develop/sounds/using-sounds.md new file mode 100644 index 000000000..6b9de3032 --- /dev/null +++ b/versions/1.21/translated/it_it/develop/sounds/using-sounds.md @@ -0,0 +1,34 @@ +--- +title: Riprodurre Suoni +description: Impara come riprodurre eventi sonori. +authors: + - JR1811 +--- + +# Riprodurre Suoni {#playing-sounds} + +Minecraft ha una grande selezione di suoni da cui puoi scegliere. Controlla la classe `SoundEvents` per vedere tutte le istanze di eventi sonori vanilla che Mojang ha predisposto. + +## Usare Suoni nella Tua Mod {#using-sounds} + +Assicurati di eseguire il metodo `playSound()` sul lato del server logico quando usi i suoni! + +In questo esempio, i metodi `useOnEntity()` e `useOnBlock()` per un oggetto interattivo personalizzato sono usati per riprodurre un suono "piazzando blocco di rame" e un suono "predone". + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +Il metodo `playSound()` è usato con l'oggetto `LivingEntity`. Solo il SoundEvent, il volume e il tono devono essere specificati. Puoi anche usare il metodo `playSound()` dall'istanza del mondo per avere un livello di controllo più alto. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +### SoundEvent e SoundCategory {#soundevent-and-soundcategory} + +Il SoundEvent definisce quale suono verrà riprodotto. Puoi anche [registrare i tuoi SoundEvents](./custom) per includere il tuo suono. + +Minecraft ha vari slider audio nelle impostazioni del gioco. L'enum `SoundCategory` è usato per determinare quale slider controllerà il volume del tuo suono. + +### Volume e Tono {#volume-and-pitch} + +Il parametro volume può causare un po' di confusione. Nell'intervallo `0.0f - 1.0f` il volume reale del suono può essere cambiato. Se il numero diventa più grande di ciò, il volume di `1.0f` verrà usato e soltanto la distanza, nella quale il tuo suono può essere udito, viene cambiata. La distanza in blocchi può essere approssimativamente calcolata come `volume * 16`. + +Il parametro pitch alza o abbassa il valore del tono e cambia anche la durata del suono. Nell'intervallo `(0.5f - 1.0f)` il tono e la velocità si abbassano, mentre valori maggiori alzano il tono e la velocità. Numeri al di sotto di `0.5f` rimarranno al valore di tono `0.5f`. diff --git a/versions/1.21/translated/it_it/develop/text-and-translations.md b/versions/1.21/translated/it_it/develop/text-and-translations.md new file mode 100644 index 000000000..19fb3116a --- /dev/null +++ b/versions/1.21/translated/it_it/develop/text-and-translations.md @@ -0,0 +1,132 @@ +--- +title: Testo e Traduzioni +description: Documentazione esaustiva riguardo alla gestione di testo e traduzioni formattate in Minecraft. +authors: + - IMB11 + - LordEnder-Kitty +--- + +# Testo e Traduzioni {#text-and-translations} + +Ogni volta che Minecraft mostra testo nel gioco, è con tutta probabilità definito da un oggetto `Text`. +Questo tipo personalizzato è preferito ad una `String` per permettere formattazione più avanzata, che comprende colori, grassetto, offuscamento, ed eventi ai clic. Permettono inoltre accesso più semplice al sistema di traduzione, rendendo semplice la traduzione di qualsiasi elemento dell'interfaccia. + +Se hai mai lavorato con datapack o con funzioni prima d'ora, potresti notare similarità con il formato testo json usato per i displayName, i libri, e i cartelli tra le altre cose. Come probabilmente riuscirai ad indovinare, quella è solo una rappresentazione json di un oggetto `Text`, e può essere convertita tramite `Text.Serializer`. + +Quando si crea una mod, si preferisce generalmente costruire i tuoi oggetti `Text` direttamente nel codice, sfruttando ove possibile le traduzioni. + +## Testo Letterale {#text-literals} + +Il modo più semplice di creare un oggetto `Text` è creare un testo letterale. Questa è proprio solo una stringa che verrà visualizzata com'è, senza alcuna formattazione predefinita. + +Questi sono creati tramite i metodi `Text.of` o `Text.literal`, che agiscono in modi un po' diversi. `Text.of` accetta null come input, e restituirà un'istanza di `Text`. Viceversa, `Text.literal` deve non ricevere come input null, ma restituisce un `MutableText`, che è una sotto-classe di `Text` facilmente stilizzata e concatenata. Ne parleremo di più dopo. + +```java +Text literal = Text.of("Hello, world!"); +MutableText mutable = Text.literal("Hello, world!"); +// Keep in mind that a MutableText can be used as a Text, making this valid: +Text mutableAsText = mutable; +``` + +## Testo Traducibile {#translatable-text} + +Se volessi fornire traduzioni multiple della stessa stringa di testo, puoi usare il metodo `Text.translatable` per fare riferimento ad una chiave di traduzione in qualsiasi file lingua. Se la chiave di traduzione non esistesse, verrebbe convertita in testo letterale. + +```java +Text translatable = Text.translatable("my_mod.text.hello"); + +// Similarly to literals, translatable text can be easily made mutable. +MutableText mutable = Text.translatable("my_mod.text.bye"); +``` + +Il file di lingua, `en_us.json`, ha il seguente aspetto: + +```json +{ + "my_mod.text.hello": "Hello!", + "my_mod.text.bye": "Goodbye :(" +} +``` + +Se volessi usare variabili nella traduzione, in maniera simile a come i messaggi di morte ti permettodo di usare i giocatori e gli oggetti coinvolti nella traduzione, puoi aggiungere queste variabili come parametri. Puoi aggiungerne quanti ne vuoi. + +```java +Text translatable = Text.translatable("my_mod.text.hello", player.getDisplayName()); +``` + +Puoi fare riferimento a queste variabili nella traduzione così: + +```json +{ + "my_mod.text.hello": "%1$s said hello!" +} +``` + +Nel gioco, %1\$s sarà sostituito dal nome del giocatore a cui hai fatto riferimento nel codice. Usare `player.getDisplayName()` farà in modo che certe informazioni aggiuntive sull'entità appaiano in un tooltip mentre si passa il mouse sopra al nome nel messaggio in chat, e ciò in contrasto con `player.getName()`, che mostrerà comunque il nome, ma non i dettagli aggiuntivi. Qualcosa di simile si può fare con gli itemStack, usando `stack.toHoverableText()`. + +Per quanto riguarda il significato di %1\$s, ti basti sapere che il numero corrisponde a quale variabile provi ad usare. Immagina di usare tre variabili. + +```java +Text translatable = Text.translatable("my_mod.text.whack.item", victim.getDisplayName(), attacker.getDisplayName(), itemStack.toHoverableText()); +``` + +Se vuoi fare riferimento a ciò che, nel nostro caso, è l'attaccante, useresti %2\$s perché è la seconda variabile che abbiamo passato. Allo stesso modo, %3\$s fa riferimento all'itemStack. Una traduzione con questo numero di parametri aggiuntivi potrebbe avere questo aspetto: + +```json +{ + "my_mod.text.whack.item": "%1$s was whacked by %2$s using %3$s" +} +``` + +## Serializzare Testo {#serializing-text} + + + +Come già accennato prima, puoi serializzare testo a JSON con il codec di testo. Per maggiori informazioni, vedi la pagina sui [Codec](./codecs). + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +Questo produce JSON che può essere usato in datapack, comandi e altri posti che accettano il formato JSON di testo invece che il formato letterale o traducibile. + +## Deserializzare Testo {#deserializing-text} + +Inoltre, per deserializzare un oggetto testo da JSON a un oggetto della classe `Text`, di nuovo, usa il codec. + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +## Formattare Testo {#formatting-text} + +Forse sei familiare con gli standard di formattazione di Minecraft: + +Puoi applicare queste formattazioni usando l'enum `Formatting` sulla classe `MutableText`: + +```java +MutableText result = Text.literal("Hello World!") + .formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE); +``` + + + + + + + + + + + + + + + + + + + + + + + + + +
ColoreNomeCodice in ChatCodice MOTDCodice Hex
Nero (black)§0\u00A70#000000
Blu Scuro (dark_blue)§1\u00A71#0000AA
Verde Scuro (dark_green)§2\u00A72#00AA00
Ciano Scuro (dark_aqua)§3\u00A73#00AAAA
Rosso Scuro (dark_red)§4\u00A74#AA0000
Viola Scuro (dark_purple)§5\u00A75#AA00AA
Oro (gold)§6\u00A76#FFAA00
Grigio (gray)§7\u00A77#AAAAAA
Grigio Scuro (dark_gray)§8\u00A78#555555
Blu (blue)§9\u00A79#5555FF
Verde (green)§a\u00A7a#55FF55
Ciano (aqua)§b\u00A7b#55FFFF
Rosso (red)§c\u00A7c#FF5555
Viola Chiaro (light_purple)§d\u00A7d#FF55FF
Giallo (yellow)§e\u00A7e#FFFF55
Bianco (white)§f\u00A7f#FFFFFF
Resetta§r
Grassetto§l
Barrato§m
Sottolineato§n
Corsivo§o
Offuscato§k
diff --git a/versions/1.21/translated/it_it/index.md b/versions/1.21/translated/it_it/index.md new file mode 100644 index 000000000..e10e121ac --- /dev/null +++ b/versions/1.21/translated/it_it/index.md @@ -0,0 +1,21 @@ +--- +title: Documentazione di Fabric +description: La documentazione ufficiale e curata di Fabric, una toolchain per il modding di Minecraft. +layout: home +hero: + name: Documentazione di Fabric + tagline: La documentazione ufficiale e curata di Fabric, una toolchain per il modding di Minecraft. +features: + - title: Guide per i Giocatori + icon: 📚 + details: Sei un giocatore che vuole usare mod basate su Fabric? Le nostre guide per giocatori ti aiuteranno. Queste guide ti aiuteranno a scaricare, installare e risolvere eventuali problemi delle mod di Fabric. + link: /it_it/players/ + linkText: Leggi di più + - title: Guide per Sviluppatori + icon: 🛠️ + details: Le nostre guide scritte dalla community trattano di tutto, dalla configurazione del tuo ambiente di sviluppo ad argomenti avanzati come rendering e reti. + link: /it_it/develop/ + linkText: Per Iniziare +--- + +Se vuoi contribuire alla Documentazione di Fabric, puoi trovare il codice sorgente su [GitHub](https://github.com/FabricMC/fabric-docs), e le corrispondenti [linee guida per la contribuzione](./contributing). diff --git a/versions/1.21/translated/it_it/players/faq.md b/versions/1.21/translated/it_it/players/faq.md new file mode 100644 index 000000000..0fba0ba2a --- /dev/null +++ b/versions/1.21/translated/it_it/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Domande Frequenti per Giocatori (FAQ) +description: Domande frequenti riguardanti Fabric per giocatori e admin di server. +--- + +# Domande Frequenti (FAQ) {#faq} + +Ci sono molte domande che vengono poste di frequente, quindi ne abbiamo compilato una lista qui. + +## Quali Versioni di Minecraft Supporta Fabric? {#what-minecraft-versions-does-fabric-support} + +Ufficialmente, Fabric supporta tutte le versioni di Minecraft a partire da snapshot `18w43b` e seguenti, e dalla release `1.14` e superiori. + +## Dove Posso Scaricare le Mod Fabric Pubblicate? {#where-can-i-download-published-fabric-mods} + +:::info +Dovresti sempre controllare che le mod provengano da una fonte affidabile. Dai un occhiata alla guida [Trovare Mod Affidabili](./finding-mods) per più informazioni. +::: + +La maggior parte degli autori pubblica le loro mod su [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) e [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4), anche se altri potrebbero aver deciso di caricarle sui loro siti personali o su altre piattaforme come le repository di GitHub. + +## Dove Posso Trovare Modpack Fabric Prefabbricati? {#where-can-i-find-premade-fabric-modpacks} + +Puoi trovare modpack Fabric prefabbricati su varie piattaforme, come: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/it_it/players/finding-mods.md b/versions/1.21/translated/it_it/players/finding-mods.md new file mode 100644 index 000000000..da324901e --- /dev/null +++ b/versions/1.21/translated/it_it/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Trovare Mod Affidabili +description: Una guida su come trovare mod Fabric attraverso fonti affidabili. +authors: + - IMB11 +--- + +# Trovare Mod Affidabili {#finding-mods} + +Anzitutto, la fiducia è soggettiva, e dovresti sempre affidarti al tuo giudizio quando scarichi mod. Tuttavia, ci sono alcune cose che puoi fare che ti aiutano a trovare mod affidabili. + +## 1. Usa una Fonte Nota per Essere Affidabile {#trustworthy-source} + +La maggior parte degli autori pubblica le loro mod su [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) e [CurseForge](https://www.curseforge.com/minecraft/search?page=1\&pageSize=20\&sortType=1\&class=mc-mods\&gameFlavorsIds=4). + +Questi siti controllano che le mod siano quello che dicono di essere, e che non contengano codice maligno. Puoi anche segnalare mod sospette su quei siti, ed essi agiranno in modo relativamente veloce. + +## 2. Controlla con gli Altri! {#with-others} + +Se stai scaricando una mod da una fonte che non è nota per essere affidabile, dovresti controllare con gli altri per vedere se loro l'hanno scaricata prima dalla posizione da cui la stai scaricando tu, e se hanno avuto problemi con essa. + +Se hai dubbi, sentiti libero di chiedere nel [Discord di Fabric](https://discord.gg/v6v4pMv) nel canale `#player-support`. + +## 3. Evita Siti Comuni Maligni! {#avoid-malware} + +:::info +I siti maligni potrebbero non essere ovvi per tutti. Se non sei sicuro, dovresti chiedere l'opinione di altri o evitare il sito completamente e affidarti solo a fonti fidate, come Modrinth e CurseForge. +::: + +Ci sono tanti siti che dicono di avere mod per Minecraft, ma che sono in realtà solo siti maligni. Dovresti evitare questi siti a tutti i costi. + +Puoi usare software antivirus e siti come [Windows Defender](https://www.microsoft.com/it-it/windows/comprehensive-security) o [VirusTotal](https://www.virustotal.com/) per controllare le mod scaricate. Tuttavia, non affidarti completamente su quei metodi, perché a volte potrebbero essere errati. + +Ancora, se hai dubbi, sentiti libero di chiedere l'opinione di altri nel [Discord di Fabric](https://discord.gg/v6v4pMv) nel canale `#player-support`. diff --git a/versions/1.21/translated/it_it/players/index.md b/versions/1.21/translated/it_it/players/index.md new file mode 100644 index 000000000..f05a37737 --- /dev/null +++ b/versions/1.21/translated/it_it/players/index.md @@ -0,0 +1,12 @@ +--- +title: Guide per Giocatori +description: Una collezione di guide per giocatori e admin di server riguardo all'installazione e all'uso di Fabric. +--- + +# Guide per Giocatori {#player-guides} + +Questa sezione della Documentazione di Fabric è dedicata ai giocatori e agli admin di server che vogliono imparare a installare e usare Fabric e risolverne i problemi. + +Dovresti fare riferimento alla barra laterale per una lista di tutte le guide disponibili. + +Se incontri dei problemi, per favore segnalali [su GitHub](https://github.com/FabricMC/fabric-docs) o chiedi aiuto sul [Discord di Fabric](https://discord.gg/v6v4pMv) nei canali `#player-support` o `#server-admin-support`. diff --git a/versions/1.21/translated/it_it/players/installing-fabric.md b/versions/1.21/translated/it_it/players/installing-fabric.md new file mode 100644 index 000000000..bea309a5d --- /dev/null +++ b/versions/1.21/translated/it_it/players/installing-fabric.md @@ -0,0 +1,59 @@ +--- +title: Installare Fabric +description: Una guida passo per passo su come installare Fabric. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Installare Fabric {#installing-fabric} + + + +Questa guida si applica soltanto al Launcher di Minecraft ufficiale. Per launcher di terze parti, dovresti consultare la loro documentazione. + +## 1. Scarica l'Installer di Fabric {#1-download-the-fabric-installer} + +Puoi scaricare l'installer di Fabric dal [Sito di Fabric](https://fabricmc.net/use/). + +Se usi Windows, scarica la versione `.exe` (`Scarica per Windows`), perché non necessita di Java per essere installata sul tuo sistema. Essa usa invece la versione di Java inclusa nel launcher ufficiale. + +Per macOS e Linux, dovresti scaricare la versione `.jar`. A volte, dovrai installare Java prima di questo passaggio. + +## 2. Esegui l'Installer di Fabric {#2-run-the-fabric-installer} + +:::warning +Chiudi Minecraft e il Launcher di Minecraft prima di avviare l'installer. +::: + +:::details Informazioni per utenti macOS + +Su macOS, potresti dover fare clic destro sul file `.jar` nella tua cartella download e cliccare `Apri` per avviarlo. + +![Menu contestuale macOS sull'Installer di Fabric](/assets/players/installing-fabric/macos-downloads.png) + +Quando ti viene chiesto "Sei sicuro di volerlo aprire?", clicca di nuovo `Apri`. +::: + +Una volta aperto l'installer, dovresti vedere una schermata come questa: + +![Fabric Installer con "Installa" evidenziato](/assets/players/installing-fabric/installer-screen.png) + + + +Per installare Fabric, basta scegliere la versione di gioco dal menu a tendina e cliccare `Installa`. + +:::warning IMPORTANTE +Assicurati che `Crea Profilo` sia selezionato. +::: + +## 3. Hai Finito! {#3-you-re-done} + +Una volta che l'installer ha finito, puoi aprire il Launcher di Minecraft e selezionare il profilo Fabric dal menu a tendina in basso a sinistra e premere Gioca! + +![Launcher di Minecraft con il profilo Fabric selezionato](/assets/players/installing-fabric/launcher-screen.png) + +Ora che hai installato Fabric, puoi aggiungere le mod al tuo gioco! Dai un occhiata alla guida [Trovare Mod Affidabili](./finding-mods) per più informazioni. + +Se incontri dei problemi seguendo questa guida, puoi chiedere aiuto nel [Discord di Fabric](https://discord.gg/v6v4pMv) nel canale `#player-support`. diff --git a/versions/1.21/translated/it_it/players/installing-java/linux.md b/versions/1.21/translated/it_it/players/installing-java/linux.md new file mode 100644 index 000000000..630933884 --- /dev/null +++ b/versions/1.21/translated/it_it/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Installare Java su Linux +description: Una guida passo per passo su come installare Java su Linux. +authors: + - IMB11 +--- + +# Installare Java su Linux {#installing-java-on-linux} + +Questa guida ti spiegherà come installare Java 21 su Linux. + +## 1. Controlla Se Java È Già Installato {#1-check-if-java-is-already-installed} + +Apri un terminale, scrivi `java -version` e premi Invio. + +![Terminale con scritto "java -version"](/assets/players/installing-java/linux-java-version.png) + +:::warning +Per usare Minecraft 1.21, ti servirà almeno Java 21 installato. Se questo comando mostra una versione inferiore a 21, allora dovrai aggiornare la versione di Java già esistente. +::: + +## 2. Scaricare e Installare Java 21 {#2-downloading-and-installing-java} + +Raccomandiamo l'uso di OpenJDK 21, che è disponibile per la maggior parte delle distribuzioni Linux. + +### Arch Linux {#arch-linux} + +:::info +Per maggiori informazioni su come installare Java su Arch Linux, vedi [la Wiki di Arch Linux](https://wiki.archlinux.org/title/Java). +::: + +Puoi installare la JRE più recente dalle repository ufficiali: + +```sh +sudo pacman -S jre-openjdk +``` + +Se stai eseguendo un server che non ha bisogno di un'interfaccia grafica, puoi installare la versione headless: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Se pensi di sviluppare delle mod, ti servirà invece il JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu {#debian-ubuntu} + +Puoi installare Java 21 usando `apt` con i comandi seguenti: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora {#fedora} + +Puoi installare Java 21 usando `dnf` con i comandi seguenti: + +```sh +sudo dnf install java-21-openjdk +``` + +Se non hai bisogno di un'interfaccia grafica, puoi installare la versione headless: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +Se pensi di sviluppare delle mod, ti servirà invece il JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Altre Distribuzioni Linux {#other-linux-distributions} + +Se la tua distribuzione non è fra quelle elencate sopra, puoi scaricare il JRE più recente da [Adoptium](https://adoptium.net/temurin/) + +Dovresti fare riferimento a una guida alternativa per la tua distribuzione se vuoi sviluppare delle mod. + +## 3. Verifica che Java 21 Sia Installato {#3-verify-that-java-is-installed} + +Quando l'installazione è stata completata, puoi verificare che Java 21 sia installato aprendo il terminale e scrivendo `java -version`. + +Se il comando funziona correttamente, vedrai qualcosa simile a quello mostrato prima, dove è mostrata la versione di Java: + +![Terminale con scritto "java -version"](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/it_it/players/installing-java/windows.md b/versions/1.21/translated/it_it/players/installing-java/windows.md new file mode 100644 index 000000000..a7083b7f7 --- /dev/null +++ b/versions/1.21/translated/it_it/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Installare Java su Windows +description: Una guida passo per passo su come installare Java su Windows. +authors: + - IMB11 +--- + +# Installare Java su Windows {#installing-java-on-windows} + +Questa guida ti spiegherà come installare Java 21 su Windows. + +Il Launcher di Minecraft ha la sua versione di Java installata, quindi questa sezione è rilevante solo se vuoi usare l'installer `.jar` di Fabric, oppure se vuoi usare il `.jar` del Server di Minecraft. + +## 1. Controlla Se Java È Già Installato {#1-check-if-java-is-already-installed} + +Per controllare se Java è già installato devi prima aprire il prompt dei comandi. + +Puoi farlo premendo Win + R e scrivendo `cmd.exe` nel riquadro che appare. + +![Dialogo Esegui su Windows che mostra "cmd.exe" scritto nella barra](/assets/players/installing-java/windows-run-dialog.png) + +Una volta aperto il prompt dei comandi, scrivi `java -version` e premi Invio. + +Se il comando funziona correttamente, vedrai qualcosa come questo. Se il comando ha fallito, procedi con il prossimo passaggio. + +![Il prompt dei comandi con scritto "java -version"](/assets/players/installing-java/windows-java-version.png) + +:::warning +Per usare Minecraft 1.21, ti servirà almeno Java 21 installato. Se questo comando mostra una versione inferiore a 21, allora dovrai aggiornare la versione di Java già esistente. +::: + +## 2. Scarica l'Installer per Java 21 {#2-download-the-java-installer} + +Per installare Java 21, dovrai scaricare l'installer da [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21). + +Dovrai scaricare la versione `Windows Installer (.msi)`: + +![La pagina di download di Adoptium con Windows Installer (.msi) evidenziato](/assets/players/installing-java/windows-download-java.png) + +Dovresti scegliere `x86` se il tuo sistema operativo è a 32-bit, oppure `x64` se tuo sistema operativo è a 64-bit. + +La maggior parte dei computer moderni ha un sistema operativo a 64-bit. Se non sei sicuro, prova a usare il download 64-bit. + +## 3. Esegui l'Installer! {#3-run-the-installer} + +Segui le istruzioni per installare Java 21. Quando arrivi a questa pagina, dovresti selezionare "L'intera funzionalità verrà installata sul disco rigido locale" per le seguenti funzionalità: + +- `Imposta JAVA_HOME come variabile d'ambiente` - Questo verrà aggiunto al tuo PATH. +- `JavaSoft (Oracle) registry keys` + +![Installer Java 21 con "Set JAVA\_HOME variable" e "JavaSoft (Oracle) registry keys" evidenziati](/assets/players/installing-java/windows-wizard-screenshot.png) + +Quando hai finito, puoi cliccare su `Avanti` e continuare con l'installazione. + +## 4. Verifica che Java 21 Sia Installato {#4-verify-that-java-is-installed} + +Quando l'installazione è stata completata, puoi verificare che Java 21 è installato aprendo il prompt dei comandi e scrivendo `java -version`. + +Se il comando funziona correttamente, vedrai qualcosa simile a quello mostrato prima, dove è mostrata la versione di Java: + +![Il prompt dei comandi con scritto "java -version"](/assets/players/installing-java/windows-java-version.png) + +--- + +Se incontri dei problemi, sentiti libero di chiedere aiuto nel server [Fabric Discord](https://discord.gg/v6v4pMv) nel canale `#player-support`. diff --git a/versions/1.21/translated/it_it/players/installing-mods.md b/versions/1.21/translated/it_it/players/installing-mods.md new file mode 100644 index 000000000..0982a9880 --- /dev/null +++ b/versions/1.21/translated/it_it/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Installare le Mod +description: Una guida passo per passo su come installare mod per Fabric. +authors: + - IMB11 +--- + +# Installare le Mod {#installing-mods} + +Questa guida ti aiuterà a installare mod per Fabric usando il Launcher di Minecraft ufficiale. + +Per launcher di terze parti, dovresti consultare la loro documentazione. + +## 1. Scarica la Mod {#1-download-the-mod} + +:::warning +Dovresti solo scaricare mod da fonti di cui ti fidi. Per maggiori informazioni su come trovare le mod, vedi la guida [Trovare Mod Affidabili](./finding-mods). +::: + +La maggior parte delle mod richiede anche l'API di Fabric, che può essere scaricata da [Modrinth](https://modrinth.com/mod/fabric-api) o da [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +Quando scarichi delle mod, assicurati che: + +- Funzionino nella versione di Minecraft su cui vuoi giocare. Una mod che funziona sulla versione 1.20, per esempio, potrebbe non funzionare sulla versione 1.20.2. +- Siano per Fabric e non per un altro loader di mod. +- Inoltre, che siano per la corretta edizione di Minecraft (Java Edition). + +## 2. Sposta le Mod nella Cartella `mods` {#2-move-the-mod-to-the-mods-folder} + +La cartella mods può essere trovata nelle posizioni seguenti per ciascun sistema operativo. + +Puoi solitamente incollare questi percorsi nella barra degli indirizzi del tuo gestore di file per navigare velocemente alla cartella. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Una volta che hai trovato la cartella `mods`, puoi muovere i file `.jar` della mod in essa. + +![Mod installate nella cartella mods](/assets/players/installing-mods.png) + +## 3. Hai Finito! {#3-you-re-done} + +Una volta che hai spostato le mod nella cartella `mods`, puoi aprire il Launcher di Minecraft e selezionare il profilo Fabric dal menu a tendina nell'angolo in basso a sinistra e premere gioca! + +![Launcher di Minecraft con il profilo Fabric selezionato](/assets/players/installing-fabric/launcher-screen.png) + +## Risoluzione dei Problemi {#troubleshooting} + +Se incontri qualsiasi problema nel seguire questa guida, puoi chiedere aiuto nel [Discord di Fabric](https://discord.gg/v6v4pMv) nel canale `#player-support`. + +Puoi anche tentare di risolvere il problema da solo leggendo le seguenti pagine di risoluzione dei problemi: + +- [Segnalazioni dei Crash](./troubleshooting/crash-reports) +- [Caricare i Log](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/it_it/players/troubleshooting/crash-reports.md b/versions/1.21/translated/it_it/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..b653179ed --- /dev/null +++ b/versions/1.21/translated/it_it/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: Segnalazioni dei Crash +description: Impara cosa fare con le segnalazioni di crash, e come leggerle. +authors: + - IMB11 +--- + +# Segnalazioni dei Crash {#crash-reports} + +:::tip +Se hai difficoltà nel trovare la causa del crash, puoi chiedere aiuto nel [Discord di Fabric](https://discord.gg/v6v4pMv) nei canali `#player-support` o `#server-admin-support`. +::: + +Le segnalazioni di crash, o degli arresti anomali, sono una parte molto importante della risoluzione di problemi con il tuo gioco o server. Contengono molte informazioni riguardanti il crash, e ti possono aiutare a trovare la causa del crash. + +## Trovare le Segnalazioni di Crash {#finding-crash-reports} + +Le segnalazioni di crash sono salvate nella cartella `crash-reports` nella tua cartella del gioco. Se stai usando un server, essi sono salvati nella cartella `crash-reports` nella cartella del server. + +Per launcher di terze parti, dovresti affidarti alla loro documentazione per sapere dove trovare le segnalazioni di crash. + +Le segnalazioni di crash possono essere trovate nelle seguenti posizioni: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Leggere le Segnalazioni di Crash {#reading-crash-reports} + +Le segnalazioni di crash sono molto lunghe, e possono causare confusione nella lettura. Tuttavia, contengono tante informazioni riguardanti il crash, e ti possono aiutare a trovare la causa del crash. + +Per questa guida, useremo [questa segnalazione di crash](/assets/players/crash-report-example.txt). + +:::details Segnalazioni dei Crash + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Sezioni della Segnalazione di Crash {#crash-report-sections} + +Le segnalazioni di crash consistono di varie sezioni, ciascuna separata con un'intestazione: + +- `---- Minecraft Crash Report ----`, il riassunto della segnalazione. Questa sezione contiene l'errore principale che ha causato il crash, l'orario al quale è avvenuto, e la stack trace pertinente. Questa è la sezione più importante della segnalazione del crash poiché lo stack trace potrebbe solitamente contenere riferimenti alla mod che ha causato il crash. +- `-- Last Reload --`, questa sezione non è molto utile a meno che il crash sia avvenuto durante un ricaricamento delle risorse (F3+T). Questa sezione conterrà probabilmente l'orario dell'ultimo ricaricamento, e lo stack trace pertinente di qualsiasi errore che si sia verificato durante il processo di ricaricamento. Questi errori sono solitamente causati dai pacchetti risorse, e possono essere ignorati tranne se stanno causando problemi con il gioco. +- `-- System Details --`, questa sezione contiene informazioni riguardo al tuo sistema, come il sistema operativo, la versione di Java, e la quantità di memoria allocata al gioco. Questa sezione è utile per determinare se stai usando la versione corretta di Java, e se hai allocato abbastanza memoria al gioco. + - In questa sezione, Fabric avrà incluso una linea personalizzata che dice `Fabric Mods:`, seguita da una lista di tutte le mod che hai installato. Questa sezione è utile per determinare se possibili conflitti potrebbero essersi verificati tra mod. + +### Comprendere la Segnalazione del Crash {#breaking-down-the-crash-report} + +Ora che sappiamo cos'è ciascuna sezione della segnalazione di crash, possiamo iniziare a suddividere la segnalazione di crash e trovare la causa del crash. + +Usando l'esempio del link sopra, possiamo analizzare la segnalazione di crash e trovare la causa del crash, incluse le mod che l'hanno causato. + +Lo stack trace nella sezione `---- Minecraft Crash Report ----` è il più importante in questo caso, poiché contiene l'errore principale che ha causato il crash. + +:::details Mostra Errore + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +Con la quantità di mod menzionata nello stack trace, può essere difficile puntare il dito, ma la prima cosa da fare è cercare la mod che ha causato il crash. + +In questo caso, la mod che ha causato il crash è `snownee`, poiché è la prima mod menzionata nello stack trace. + +Tuttavia, con la quantità di mod menzionata, potrebbe significare che ci sono problemi di compatibilità tra le mod, e che la mod che ha causato il crash potrebbe non essere la mod colpevole. In questo caso, è meglio segnalare il crash all'autore della mod, e lasciarglielo investigare. + +## Crash che Coinvolgono Mixin {#mixin-crashes} + +:::info +I mixin sono un modo che hanno le mod per modificare il gioco senza dover modificarne il codice sorgente. Sono usati da varie mod, e sono uno strumento molto potente per gli sviluppatori di mod. +::: + +Quando un mixin causa un crash, esso menzionerà solitamente il mixin nello stack trace, e la classe che il mixin sta modificando. + +I metodi mixin conterranno `modid$handlerName` nello stack trace, mentre `modid` è l'ID della mod, e `handlerName` è il nome del gestore del mixin. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +Puoi usare queste informazioni per trovare la mod che ha causato il crash, e segnalare il crash all'autore della mod. + +## Cosa Fare delle Segnalazioni di Crash {#what-to-do-with-crash-reports} + +La migliore cosa da fare con le segnalazioni di crash è caricarle a un paste site, e poi condividere il link con l'autore della mod, o tramite il suo issue tracker o attraverso qualche mezzo di comunicazione (Discord ecc...). + +Questo permetterà all'autore della mod d'investigare il crash, potenzialmente di riprodurlo, e di risolvere il problema che l'ha causato. + +Paste site comuni usati frequentemente per le segnalazioni di crash sono: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/it_it/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/it_it/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..aa928985f --- /dev/null +++ b/versions/1.21/translated/it_it/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Caricare i Log +description: Come caricare i log per la risoluzione dei problemi. +authors: + - IMB11 +--- + +# Caricare i Log {#uploading-logs} + +Quando stai tentando di risolvere problemi, spesso è necessario fornire i log per aiutare a identificare la causa del problema. + +## Perché Dovrei Caricare i Log? {#why-should-i-upload-logs} + +Caricare i log permette agli altri di aiutarti a risolvere i tuoi problemi molto più velocemente che non semplicemente incollare i log in una chat o in un post su un forum. Ti permette anche di condividere i tuoi log con altri senza doverli copiare e incollare. + +Alcuni siti forniscono anche colorazione della sintassi per i log, che li rende più facili da leggere, e potrebbero censurare informazioni riservate, come il tuo nome utente, o informazioni sul sistema. + +## Segnalazioni dei Crash {#crash-reports} + +Le segnalazioni dei crash sono generate automaticamente quando il gioco subisce un crash. Contengono soltanto informazioni sul crash e non i log reali del gioco. Esse sono posizionate nella cartella `crash-reports` nella directory del gioco. + +Per maggiori informazioni sulle segnalazioni dei crash, vedi [Segnalazioni dei Crash](./crash-reports). + +## Localizzare i Log {#locating-logs} + +Questa guida ricopre il Launcher di Minecraft ufficiale (anche comunemente noto come il "launcher vanilla") - per launcher di terze parti, dovresti consultare la loro documentazione. + +I log sono posizionati nella cartella `logs` della directory del gioco, la directory del gioco può essere trovata nelle seguenti posizioni a seconda del tuo sistema operativo: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +Il log più recente si chiama `latest.log`, e log precedenti usano lo schema di denominazione `aaaa-mm-gg_numero.log.gz`. + +## Caricare i Log Online {#uploading-logs-online} + +I log possono essere caricati su vari servizi, come: + +- [Pastebin](https://pastebin.com/) +- [Gist di GitHub](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/it_it/players/updating-fabric.md b/versions/1.21/translated/it_it/players/updating-fabric.md new file mode 100644 index 000000000..68ef235fe --- /dev/null +++ b/versions/1.21/translated/it_it/players/updating-fabric.md @@ -0,0 +1,41 @@ +--- +title: Aggiornare Fabric +description: Una guida passo per passo su come aggiornare Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Aggiornare Fabric {#updating-fabric} + +Questa guida ti aiuterà nell'aggiornare Fabric per quanto riguarda il Launcher di Minecraft. + +Per launcher di terze parti, dovresti consultare la loro documentazione. + +Aggiornare Fabric è un processo molto simile all'installazione di Fabric, per cui alcune parti di questa guida saranno uguali a quelle della guida [Installare Fabric](./installing-fabric). + +## Perché Dovrei Aggiornare il Loader di Fabric? {#why-should-i-update-fabric-loader} + +Mod più recenti potrebbero richiedere una versione più moderna del Loader di Fabric per funzionare, quindi è importante tenerlo aggiornato per assicurarti di poter usare le mod più recenti. + + + +Per aggiornare Fabric, basta assicurarsi che la versione del gioco e quella del Loader siano corrette per poi cliccare `Installa`. + +:::warning IMPORTANTE +Assicurati di deselezionare 'Crea Profilo' quando esegui l'installer, altrimenti creerà un nuovo profilo, che in questo caso non ci serve. +::: + +## 3. Apri il Profilo nel Launcher di Minecraft {#3-open-the-profile-in-the-minecraft-launcher} + +Appena l'installer ha finito, puoi aprire il Launcher di Minecraft e recarti nella scheda `Installazioni`. Dovresti andare al tuo profilo Fabric e aprire la schermata modifica. + +Sostituisci la versione con la nuova versione del Loader di Fabric che hai appena installato, e premi `Salva`. + +![Aggiornare la versione del Loader di Fabric nel Launcher di Minecraft](/assets/players/updating-fabric.png) + +## 4. Hai Finito! {#4-you-re-done} + +Appena avrai completato i passaggi potrai tornare alla scheda `Gioca`, selezionare il profilo Fabric dal menu a tendina nell'angolo in basso a sinistra e premere gioca! + +Se incontri qualsiasi problema nel seguire questa guida, puoi chiedere aiuto nel [Discord di Fabric](https://discord.gg/v6v4pMv) nel canale `#player-support`. diff --git a/versions/1.21/translated/it_it/sidebar_translations.json b/versions/1.21/translated/it_it/sidebar_translations.json new file mode 100644 index 000000000..f444c1b9c --- /dev/null +++ b/versions/1.21/translated/it_it/sidebar_translations.json @@ -0,0 +1,71 @@ +{ + "players.title": "Guide per Giocatori", + "players.faq": "Domande Frequenti (FAQ)", + "players.installingJava": "Installare Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Installare Fabric", + "players.findingMods": "Trovare Mod Affidabili", + "players.installingMods": "Installare le Mod", + "players.troubleshooting": "Risoluzione dei Problemi", + "players.troubleshooting.uploadingLogs": "Caricare i Log", + "players.troubleshooting.crashReports": "Segnalazioni dei Crash", + "players.updatingFabric": "Aggiornare Fabric", + "develop.title": "Guide per Sviluppatori", + "develop.gettingStarted": "Per Iniziare", + "develop.gettingStarted.introduction": "Introduzione a Fabric e al Modding", + "develop.gettingStarted.devEnvSetup": "Impostare un Ambiente di Sviluppo", + "develop.gettingStarted.creatingProject": "Creare un Progetto", + "develop.gettingStarted.projectStructure": "Struttura del Progetto", + "develop.gettingStarted.launchGame": "Avviare il Gioco", + "develop.gettingStarted.solvingProblems": "Problem-Solving Basilare", + "develop.items": "Oggetti", + "develop.items.first-item": "Creare il Tuo Primo Oggetto", + "develop.items.food": "Alimenti", + "develop.items.custom-armor": "Armature Personalizzate", + "develop.items.custom-tools": "Utensili Personalizzati", + "develop.items.custom-item-groups": "Gruppi di Oggetti Personalizzati", + "develop.items.custom-item-interactions": "Interazioni tra Oggetti Personalizzate", + "develop.items.custom-enchantment-effects": "Effetti d'Incantesimi Personalizzati", + "develop.items.potions": "Pozioni", + "develop.items.custom-data-components": "Componenti di Dati Personalizzate", + "develop.blocks": "Blocchi", + "develop.blocks.first-block": "Creare il Tuo Primo Blocco", + "develop.blocks.blockstates": "Stati di un Blocco", + "develop.blocks.block-entities": "Blocchi-Entità", + "develop.blocks.block-entity-renderer": "Renderer dei Blocchi-Entità", + "develop.entities": "Entità", + "develop.entities.effects": "Effetti di Stato", + "develop.entities.damage-types": "Tipi di Danno", + "develop.commands": "Comandi", + "develop.commands.basics": "Creare Comandi", + "develop.commands.arguments": "Parametri dei Comandi", + "develop.commands.suggestions": "Suggerimenti dei Comandi", + "develop.dataGeneration": "Generazione di Dati", + "develop.dataGeneration.setup": "Configurazione della Generazione di Dati", + "develop.dataGeneration.tags": "Generazione di Tag", + "develop.dataGeneration.translations": "Generazione di Traduzioni", + "develop.dataGeneration.advancements": "Generazione di Progressi", + "develop.dataGeneration.recipes": "Generazione di Ricette", + "develop.dataGeneration.lootTables": "Generazione di Loot Table", + "develop.rendering": "Rendering", + "develop.rendering.basicConcepts": "Concetti Base del Rendering", + "develop.rendering.drawContext": "Usare il Contesto di Disegno", + "develop.rendering.hud": "Rendering nel Hud", + "develop.rendering.gui": "Interfacce Grafiche e Schermate", + "develop.rendering.gui.customScreens": "Schermate Personalizzate", + "develop.rendering.gui.customWidgets": "Widget Personalizzati", + "develop.rendering.particles": "Particelle", + "develop.rendering.particles.creatingParticles": "Creare Particelle Personalizzate", + "develop.misc": "Pagine Varie", + "develop.misc.codecs": "Codec", + "develop.misc.events": "Eventi", + "develop.misc.text-and-translations": "Testo e Traduzioni", + "develop.misc.ideTipsAndTricks": "Trucchi Riguardanti l'IDE", + "develop.misc.automatic-testing": "Testing Automatizzato", + "develop.sounds": "Suoni", + "develop.sounds.using-sounds": "Riprodurre Suoni", + "develop.sounds.custom": "Creare Suoni Personalizzati", + "develop.sounds.dynamic-sounds": "Suoni Dinamici" +} diff --git a/versions/1.21/translated/it_it/website_translations.json b/versions/1.21/translated/it_it/website_translations.json new file mode 100644 index 000000000..4ed83f5fe --- /dev/null +++ b/versions/1.21/translated/it_it/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "Autori della pagina", + "authors.nogithub": "%s (non su GitHub)", + "banner": "La Documentazione di Fabric è un lavoro in corso. Segnala problemi su %s o su %s.", + "description": "Documentazione esaustiva di Fabric, la toolchain di modding per Minecraft.", + "download": "Scarica %s", + "footer.next": "Pagina successiva", + "footer.prev": "Pagina precedente", + "github_edit": "Modifica questa pagina su GitHub", + "lang_switcher": "Cambia lingua", + "last_updated": "Ultimo aggiornamento", + "mode_dark": "Passa al tema scuro", + "mode_light": "Passa al tema chiaro", + "mode_switcher": "Aspetto", + "nav.contribute": "Contribuisci", + "nav.contribute.api": "API di Fabric", + "nav.download": "Scarica", + "nav.home": "Home", + "outline": "In questa pagina", + "return_to_top": "Torna all'inizio", + "search.back": "Chiudi ricerca", + "search.button": "Cerca", + "search.display_details": "Mostra lista dettagliata", + "search.footer.close": "per chiudere", + "search.footer.close.key": "Esc", + "search.footer.down.key": "Freccia giù", + "search.footer.navigate": "per navigare", + "search.footer.up.key": "Freccia su", + "search.footer.select": "per selezionare", + "search.footer.select.key": "Invio", + "search.no_results": "Nessun risultato per", + "search.reset": "Cancella ricerca", + "sidebar_menu": "Menu", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Documentazione di Fabric", + "version.reminder": "Questa pagina si applica alla versione:", + "version.switcher": "Cambia Versione", + "404.code": "404", + "404.crowdin_link": "Traduci su Crowdin", + "404.crowdin_link.label": "Apri l'editor di Crowdin", + "404.english_link": "Leggi in Inglese", + "404.english_link.label": "Apri la versione in inglese", + "404.link": "Torna alla Home", + "404.link.label": "Apri la pagina home", + "404.quote": "Questa pagina ha provato a nuotare nella lava", + "404.title": "Pagina non trovata" +} diff --git a/versions/1.21/translated/ja_jp/contributing.md b/versions/1.21/translated/ja_jp/contributing.md new file mode 100644 index 000000000..404daee6d --- /dev/null +++ b/versions/1.21/translated/ja_jp/contributing.md @@ -0,0 +1,253 @@ +--- +title: 貢献ガイドライン +description: Fabricドキュメントへの貢献ガイドライン +--- + +# 貢献ガイドライン {#contributing} + +このWebサイトは、Markdownファイルから静的HTMLを生成するのに [VitePress](https://vitepress.dev/) を使っています。 VitePress がサポートする Markdown 拡張機能については、[こちら](https://vitepress.dev/guide/markdown#features)でよく理解しておく必要があります。 + +この Web サイトに貢献するには、次の 3 つの方法があります。 + +- [ドキュメントの翻訳](#translating-documentation) +- [コンテンツの寄稿](#contributing-content) +- [フレームワークの貢献](#contributing-framework) + +すべての貢献は、[スタイルガイドライン](#style-guidelines)に従ってください。 + +## ドキュメントの翻訳 {#translating-documentation} + +ドキュメントを自分の言語に翻訳したい場合は、[Fabric Crowdin ページ](https://crowdin.com/project/fabricmc)で行うことができます。 + + + +## <0>new-content コンテンツの寄稿 {#contributing-content} + +コンテンツの寄稿は、Fabric ドキュメントに貢献する主な方法です。 + +すべてのコンテンツ投稿は次の段階を経て行われ、各段階にはラベルが関連付けられます。 + +1. locally 変更を準備してPRをプッシュ +2. stage:expansion: 必要に応じて拡張するためのガイダンス +3. stage:verification: コンテンツの検証 +4. stage:cleanup: 文法、添削... +5. <0>stage:ready: マージの準備完了! + +すべてのコンテンツは、[スタイルガイドライン](#style-guidelines)に従ってください。 + +### 1. 変更を準備 {#1-prepare-your-changes} + +このWebサイトはオープンソースで、Githubのリポジトリで管理されているため、Githubでの手順に依存しています。 + +1. [GitHubのリポジトリをForkする](https://github.com/FabricMC/fabric-docs/fork) +2. あなたのForkで新しいブランチを作成する +3. そのブランチで変更を作る +4. 元のリポジトリにPull Requestを作る + +Github フローについて詳しくは[こちら](https://docs.github.com/en/get-started/using-github/github-flow)をご覧ください。 + +GitHub のWebインターフェースから編集するか、ローカルでWebサイトを構築してプレビューすることもできます。 + +#### あなたのForkをクローンする {#clone-your-fork} + +ローカルで開発する場合は、[Git](https://git-scm.com/)をインストールする必要があります。 + +そのあと、あなたのリポジトリをクローンします。 + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### 依存関係のインストール {#install-dependencies} + +もしローカルで変更をプレビューしたい場合、[Node.js 18+](https://nodejs.org/en/)をインストールする必要があります。 + +その後、次のコマンドを使用してすべての依存関係を必ずインストールしてください。 + +```sh +npm install +``` + +#### 開発サーバーの実行 {#run-the-development-server} + +`localhost:5173` でローカルに変更をプレビューできるようになり、変更を加えるとページが自動的にリロードされます。 + +```sh +npm run dev +``` + +これで、`http://localhost:5173` にアクセスして、ブラウザからWebサイトを開いて閲覧できるようになります。 + +#### ウェブサイトの構築 {#building-the-website} + +これによりすべての Markdown ファイルが静的 HTML ファイルにコンパイルされ、`.vitepress/dist` に配置されます。 + +```sh +npm run build +``` + +#### 構築した Web サイトのプレビュー {#previewing-the-built-website} + +これにより、`.vitepress/dist` にあるコンテンツを提供するポート `4173` でローカル サーバーが起動します。 + +```sh +npm run preview +``` + +#### Pull Requestを作る {#opening-a-pull-request} + +変更内容に満足したら、変更内容を `push` できます。 + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +次に、`git push` の出力にあるリンクに従って PR を開きます。 + +### 2. stage:expansion 必要に応じて拡張するためのガイダンス {#2-guidance-for-expansion-if-needed} + +ドキュメンテーションチームがPull Requestを拡張できると判断した場合、チームのメンバーがPull Requestに stage:expansion ラベルを追加し、拡張できると思われる内容を説明するコメントをします。 提案に同意する場合は、Pull Requestを拡張できます。 + +自分でPull Requestを拡張するつもりはないが、後日他のユーザーが拡張しても構わない場合は、[Issueページ](https://github.com/FabricMC/fabric-docs/issues) で新しいIssueを作成し、拡張が必要と思われる内容を説明してください。 ドキュメンテーションチームは、あなたのPull Requestに help-wanted ラベルを追加します。 + +### 3. stage:verification コンテンツの検証 {#3-content-verification} + +コンテンツが正確で、Fabricドキュメントのスタイルガイドに従っていることを確認するため、このステージが最も重要です。 + +このステージでは、次の質問に答える必要があります。 + +- すべての内容が正確ですか? +- すべての内容が最新ですか? +- 内容はOSの違いなど、あらゆる場合をカバーしているか? + +### 4. stage:cleanup クリーンアップ {#4-cleanup} + +このステージでは、次のことが行われます。 + +- [LanguageTool](https://languagetool.org/)を使って、文法の問題や誤字を修正します。 +- [`markdownlint`](https://github.com/DavidAnson/markdownlint)を使って、リンティングします。 +- [Checkstyle](https://checkstyle.sourceforge.io/)を使って、Javaのコードをフォーマットします。 +- その他の修正や改善 + +## framework コントリビュートの枠組み {#contributing-framework} + +フレームワークとは、Webサイトの構造のことを指します。フレームワークを変更するPull Requestには framework ラベルがつけられます。 + +フレームワークのPull Requestは、[Fabric Discord](https://discord.gg/v6v4pMv)またはissueでドキュメントチームに相談した後にのみ行う必要があります。 + +:::info +サイドバーとナビゲーションバーの設定の変更は、フレームワークのPull Requestとしてみなされません。 +::: + +## スタイルガイドライン {#style-guidelines} + +分からないことがあれば、[Fabric Discord](https://discord.gg/v6v4pMv)またはGitHub Discussionsで聞いてください。 + +### 原文をアメリカ英語で書く {#write-the-original-in-american-english} + +オリジナルドキュメントはすべて、アメリカの文法規則に従って英語で書かれています。 + +### Frontmatterにデータを追加 {#add-data-to-the-frontmatter} + +それぞれのページは`titile`と`description`をfrontmatterに含んでいる必要があります。 + +Markdownファイルのfrontmatterの`authors`にあなたのGitHubのユーザー名も忘れずに追加してください! そうすればあなたに適切なクレジットを付与することができます。 + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### 見出しにアンカーを追加する {#add-anchors-to-headings} + +それぞれの見出しには、その見出しへのリンクに使用されるアンカーが必要です。 + +```md +# This Is a Heading {#this-is-a-heading} +``` + +アンカーには、英小文字, 数字, ハイフン(-) のみを使用してください。 + +### コードを`/reference`のModに配置する {#place-code-within-the-reference-mod} + +コードを含むページを作成または変更する場合は、リファレンスMOD(リポジトリの `/reference` フォルダにあります)内の適切な場所にコードを配置してください。 そして、[VitePressが提供するコードスニペット機能](https://vitepress.dev/guide/markdown#import-code-snippets)を使ってコードを埋め込みます。 + +たとえば、`FabricDocsReference.java`ファイルの15行目から21行目をリファレンスモッドからハイライトするには + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +より大きな制御範囲が必要な場合は、[`markdown-it-vuepress-code-snippet-enhanced`のtransclude機能](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced)を使うことができます。 + +たとえば、これは上のファイルの `#entrypoint` タグでマークされた部分を埋め込むには + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### 新しいセクションごとにサイドバーを作る {#create-a-sidebar-for-each-new-section} + +新しいセクションを作成する場合は、`.vitepress/sidebars`フォルダに新しいサイドバーを作成し、`i18n.mts`ファイルに追加してください。 + +サポートが必要な場合は、[Fabric Discord](https://discord.gg/v6v4pMv) の `#docs` チャンネルで聞いてください。 + +### 関連するサイドバーに新しいページを追加する {#add-new-pages-to-the-relevant-sidebars} + +新しいページを作成する際は、`.vitepress/sidebars`フォルダ内の関連するサイドバーに追加してください。 + +繰り返しになりますが、サポートが必要な場合はFabric Discordの `#docs` チャンネルで聞いてください。 + +### 画像を`/assets`に配置する {#place-media-in-assets} + +画像は`/public/assets`内の適切な場所に配置してください。 + +### 相対リンクを使う! {#use-relative-links} + +これはバージョン管理が導入されているためで、リンクはあらかじめバージョンを追加するように処理されます。 絶対リンクを使う場合、バージョン番号はリンクに追加されません。 + +また、リンクにファイルの拡張子を追加しないでください。 + +たとえば、`/develop/index.md`から`/players/index.md`にリンクを貼るには、次のようにする必要があります。 + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/ja_jp/develop/getting-started/creating-a-project.md b/versions/1.21/translated/ja_jp/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..4566f399f --- /dev/null +++ b/versions/1.21/translated/ja_jp/develop/getting-started/creating-a-project.md @@ -0,0 +1,68 @@ +--- +title: プロジェクトの作成 +description: Fabric テンプレート Mod ジェネレータを使用した Mod 作成の段階的なガイド。 +authors: + - IMB11 +--- + +# プロジェクトの作成 {#creating-a-project} + +Fabric は、Mod プロジェクトを簡単に作成することを可能にする Fabric テンプレート Mod ジェネレータを提供しています。手動でプロジェクトを作成したい場合は、サンプルの Mod リポジトリを使用することができます。[手動で作成する](#manual-project-creation) セクションを参照してください。 + +## プロジェクトの生成 {#generating-a-project} + +[Fabric テンプレート Mod ジェネレータ](https://fabricmc.net/develop/template/) を使用すると新しいプロジェクトを生成することができます。パッケージ名、Mod 名、Mod が対応する Minecraft バージョンの入力が必要です。 + +![ジェネレータのプレビュー](/assets/develop/getting-started/template-generator.png) + +Kotlin を使用したい場合や、データ生成を行いたい場合は、`Advanced Options` セクションで適切なオプションを選択してください。 + +![Advanced Options セクション](/assets/develop/getting-started/template-generator-advanced.png) + +必要な項目の入力が完了したら、`Generate` ボタンを押してください。ジェネレータが新しいプロジェクトを zip ファイル形式で生成します。 + +zip ファイルを任意の場所で解凍して、解凍されたフォルダを IntelliJ IDEA で開いてください。 + +![プロジェクトを開く 画面](/assets/develop/getting-started/open-project.png) + +## プロジェクトのインポート {#importing-the-project} + +プロジェクトを IntelliJ IDEA で開くと、IDE は自動で Gradle 設定を読み込み、セットアップに必要なタスクを行います。 + +Gradle ビルドスクリプトに関する通知が表示された場合は、`Gradle プロジェクトのインポート` ボタンを押してください: + +![Gradle プロンプト](/assets/develop/getting-started/gradle-prompt.png) + +プロジェクトのインポートが完了すると、プロジェクトツールウィンドウにファイルが表示され、Mod の開発を始めることができるようになります。 + +## 手動によるプロジェクトの作成 {#manual-project-creation} + +:::warning +サンプルの Mod リポジトリをクローンするためには、[Git](https://git-scm.com/) のインストールが必要になります。 +::: + +Fabric テンプレート Mod ジェネレータを使用できない場合は、次のステップを踏むことで手動で新しいプロジェクトを作成できます。 + +まず、Git を使用してサンプル Mod リポジトリをクローンします: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +このコマンドは、リポジトリを `my-mod-project` という名前のフォルダにクローンします。 + +続いて、フォルダ内の `.git` フォルダを削除し、IntelliJ IDEA でプロジェクトを開いてください。 `.git` フォルダが表示されない場合は、ファイルマネージャで隠しファイルの表示を有効にする必要があります。 + +プロジェクトを IntelliJ IDEA で開くと、IDE は自動で Gradle 設定を読み込み、セットアップに必要なタスクを行います。 + +前述の通り、Gradle ビルドスクリプトに関する通知が表示された場合は、`Gradle プロジェクトのインポート` ボタンを押してください。 + +### テンプレートの編集 {#modifying-the-template} + +プロジェクトがインポートされたら、プロジェクトの詳細をあなたの Mod の詳細に合わせて編集してください: + +- `gradle.properties` ファイル内の `maven_group` と `archive_base_name` を編集します。 +- `fabric.mod.json` ファイル内の `id`、`name`、`description` プロパティを編集します。 +- Minecraft、マッピング、Fabric Loader、Loom のバージョンを、対応させたい値に編集します。これらは https://fabricmc.net/develop/ で照会できます。 + +言うまでもないですが、パッケージ名と Mod のメインクラスも適宜編集してください。 diff --git a/versions/1.21/translated/ja_jp/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/ja_jp/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..fb859f7b7 --- /dev/null +++ b/versions/1.21/translated/ja_jp/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Fabric と Modding への入門 +description: "Fabric と Minecraft: Java 版における Modding への入門" +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Fabric と Modding への入門 {#introduction-to-fabric-and-modding} + +## 前提条件 {#prerequisites} + +Fabric と Minecraft の Modding を始めるには、Java の基礎文法と、オブジェクト指向プログラミング(OOP)の理解が必要です。 + +これらの知識がない方は、Java と OOP に関する以下のチュートリアルをご覧いただけます。 + +- [W3: Java Tutorials](https://www.w3schools.com/java/) +- [Codecademy: Learn Java](https://www.codecademy.com/learn/learn-java) +- [W3: Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium: Introduction to OOP](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### 用語集 {#terminology} + +始める前に、Fabric における Modding で使われる用語について説明します: + +- **Mod**: 新しい機能の追加や既存の機能の変更といった、ゲームに加える変更。 +- **Mod ローダー**: Fabric Loader のような、Mod をゲームに読み込ませるツール。 +- **Mixin**: 実行時にゲームのプログラムを変更するツール。詳細は [Mixin Introduction](https://fabricmc.net/wiki/tutorial:mixin_introduction) を参照してください。 +- **Gradle**: Mod のビルドとコンパイルを自動化するツール。Fabric では Mod のビルドに使用している。 +- **マッピング(Mappings)**: 難読化されたプログラムと人間が読めるプログラムの間における対応。 +- **難読化(Obfuscation)**: プログラムを読みづらくする処理。Mojang が Minecraft のプログラムを守るために行う。 +- **再マッピング**: 難読化されたプログラムを人間が読めるプログラムに変更する処理。 + +## Fabric とは {#what-is-fabric} + +Fabric は Minecraft: Java 版向けの軽量な Modding ツールです。 + +Fabric はシンプルで扱いやすい Modding プラットフォームを目指して設計されています。 開発はコミュニティによって行われており、オープンソースです。つまり、誰でもプロジェクトに貢献することができます。 + +Fabric には 4 つの主要なコンポーネントがあります: + +- **Fabric Loader**: Minecraft やその他のゲームやアプリケーション向けに設計された、柔軟でプラットフォームに依存しない Mod ローダー。 +- **Fabric Loom**: Mod の開発とデバッグを簡単にする Gradle プラグイン。 +- **Fabric API**: Modding をする際に使用する API とツールのセット。 +- **Yarn**: オープンな Minecraft のマッピング。Creative Commons Zero ライセンスのもと、誰でも自由に使うことができる。 + +## Fabric が Minecraft の Modding に必要である理由 {#why-is-fabric-necessary-to-mod-minecraft} + +> Modding とは、挙動を変更したり、新しい機能を追加したりするためにゲームを改造することです。Minecraft の場合、新しいアイテム、ブロック、エンティティの追加から、ゲームの仕様の変更、新しいゲームモードの追加まで、あらゆることが含まれます。 + +Minecraft: Java 版は Mojang によって難読化されており、単独での Modding は困難です。 しかし、Fabric のような Modding ツールを使うことで、簡単に変更を加えることができます。 ツールの中には、Modding を支援するいくつかのマッピングシステムが存在します。 + +Loom はマッピングを用いて、難読化されたプログラムを人間が読める形式に再マッピングします。これにより、Mod 開発者が簡単にゲームのプログラムを理解し、変更を加えることができるようになります。 Yarn は人気があり、Modding に非常に優れたマッピングです。しかし、別のマッピングも存在します。 マッピングにはそれぞれ独自の強みや目的があります。 + +Loom は再マッピングされたプログラムにおける開発とコンパイルを容易にします。また、Fabric Loader はこれらの Mod をゲームに読み込ませることを可能にします。 + +## Fabric API が提供するものと、必要である理由 {#what-does-fabric-api-provide-and-why-is-it-needed} + +> Fabric API は Modding をする際に使用する API とツールのセットです。 + +Fabric API は Minecraft の既存の機能に対する様々な API を提供します。例えば、新しいフックやイベントを提供したり、Modding を簡単にするユーティリティやツール(推移的アクセスワイドナーや、内部レジストリへのアクセス機能など)を提供したりします。 + +Fabric API は強力な機能を提供しますが、ブロックの登録を含む一部の基本的なタスクはバニラの API を通じて行うことができます。 diff --git a/versions/1.21/translated/ja_jp/develop/getting-started/project-structure.md b/versions/1.21/translated/ja_jp/develop/getting-started/project-structure.md new file mode 100644 index 000000000..560702716 --- /dev/null +++ b/versions/1.21/translated/ja_jp/develop/getting-started/project-structure.md @@ -0,0 +1,59 @@ +--- +title: プロジェクトの構成 +description: Fabric Mod プロジェクトの構成の概要 +authors: + - IMB11 +--- + +# プロジェクトの構成 {#project-structure} + +このページでは、Fabric Mod プロジェクトの構成と、各ファイルやフォルダの目的について説明します。 + +## `fabric.mod.json` {#fabric-mod-json} + +`fabric.mod.json` ファイルは Mod の情報を Fabric Loader に伝えます。 ファイルには Mod の ID、バージョン、依存関係などの情報が書かれます。 + +`fabric.mod.json` 内の最も重要なフィールドは次の通りです: + +- `id`: Mod の ID。一意の値である必要がある。 +- `name`: Mod の名前。 +- `environment`: Mod が動く環境。`client`、`server`、`*`(両方)のいずれか。 +- `entrypoints`: Mod が提供するエントリポイント。`main` や `client` など。 +- `depends`: Mod が依存する Mod の ID のリスト。 +- `mixins`: Mod が提供する Mixin 構成ファイルのリスト。 + +以下に `fabric.mod.json` ファイルの例を示します。これは、このドキュメント上のサンプルプロジェクトで使われる `fabric.mod.json` ファイルです。 + +:::details サンプルプロジェクト `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## エントリポイント {#entrypoints} + +上述のとおり、`fabric.mod.json` ファイルは `entrypoints` というフィールドを持ちます。このフィールドは、Mod が提供するエントリポイントを示します。 + +テンプレート Mod ジェネレータはデフォルトで `main` と `client` のエントリポイントを作成します。`main` エントリポイントは共通するコードに使用され、`client` エントリポイントはクライアントでのみ実行されるコードに使用されます。 これらのエントリポイントは、ゲーム開始時にそれぞれ呼び出されます。 + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +上記のコードは、ゲーム開始時にコンソールにログを出力する、シンプルな `main` エントリポイントの例です。 + +## `src/main/resources` {#src-main-resources} + +`src/main/resources` フォルダは、 Mod が使用するリソースを格納するために使用されます。リソースは、テクスチャ、モデル、サウンドなどのことです。 + +また、`fabric.mod.json` ファイルや Mod が使用する Mixin 構成ファイルが配置される場所でもあります。 + +リソースは、リソースパックの構造に従って格納されます。例えば、ブロックのテクスチャは `assets/modid/textures/block/block.png` に格納されます。 + +## `src/client/resources` {#src-client-resources} + +`src/client/resources` フォルダは、クライアント固有のリソースを格納するために使用されます。 + +## `src/main/java` {#src-main-java} + +`src/main/java` フォルダは、クライアントとサーバの両方の環境で共通する Java コードを格納するために使用されます。 + +## `src/client/java` {#src-client-java} + +`src/client/java` フォルダは、クライアント固有の Java コードを格納するために使用されます。クライアント固有のコードとは、描画処理を行うコードや、クライアントサイドにのみ存在するロジックのコード(ブロックカラープロバイダなど)を指します。 diff --git a/versions/1.21/translated/ja_jp/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/ja_jp/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..3b1252f17 --- /dev/null +++ b/versions/1.21/translated/ja_jp/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: 開発環境のセットアップ +description: Fabric を使った Mod 開発環境をセットアップするための段階的なガイド。 +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# 開発環境のセットアップ {#setting-up-a-development-environment} + +Fabric を使って Mod を開発するためには、IntelliJ IDEA を使用した開発環境を設定する必要があります。 + +## JDK 21 のインストール {#installing-jdk-21} + +Minecraft 1.21 を対象にした Mod を開発するには、JDK 21 が必要です。 + +Java のインストールでお困りの場合、[プレイヤーガイド](../../players/index) 内の Java インストールガイドをご覧になれます。 + +## IntelliJ IDEA のインストール {#installing-intellij-idea} + +:::info +このドキュメント内の多くの記事は IntelliJ IDEA の使用を前提として書かれています。Eclipse や Visual Studio Code などの別の IDE もお使いいただけますが、その場合は公式のドキュメントを確認するようにしてください。 +::: + +まだ IntelliJ IDEA をインストールしていない場合は、[公式ウェブサイト](https://www.jetbrains.com/idea/download/) からダウンロードできます。お使いの OS のインストールガイドに従ってください。 + +Community 版の IntelliJ IDEA は無料かつオープンソースであり、Fabric を使った Modding に推奨されています。 + +Community 版のダウンロードリンクを見つけるにはページをスクロールする必要があるかもしれません。リンクは以下のようになっています: + +![IDEA Community Edition Download Prompt](/assets/develop/getting-started/idea-community.png) + +## IDEA プラグインのインストール {#installing-idea-plugins} + +このプラグインは必須ではありません。しかし、Fabric を使った Modding を非常に簡単にします。インストールを検討してください。 + +### Minecraft Development {#minecraft-development} + +Minecraft Development プラグインは Fabric を使った Modding を支援します。これは最もインストールすべきプラグインです。 + +インストールするには、IntelliJ IDEA を開き、`ファイル(macOS の場合は、IntelliJ IDEA) > 設定 > プラグイン > Marketplace タブ` を選択します。表示された検索バーで `Minecraft Development` を検索し、`インストール` ボタンをクリックしてください。 + +また、[プラグインページ](https://plugins.jetbrains.com/plugin/8327-minecraft-development) からダウンロードして、`ファイル > 設定 > プラグイン > ディスクからプラグインをインストール` からインストールすることもできます。 diff --git a/versions/1.21/translated/ja_jp/develop/index.md b/versions/1.21/translated/ja_jp/develop/index.md new file mode 100644 index 000000000..e959b99f2 --- /dev/null +++ b/versions/1.21/translated/ja_jp/develop/index.md @@ -0,0 +1,14 @@ +--- +title: デベロッパガイド +description: Fabricのコミュニティによって書かれたこのデベロッパガイドは、環境構築からレンダリングやネットワーキングなどの高度な内容までを扱っています。 +--- + +# デベロッパガイド {#developer-guides} + +コミュニティによって書かれたこのガイドは、環境構築から、ネットワーキングやレンダリングのような高度な内容まで幅広い内容を扱っています。 + +ガイドの一覧はサイドバーで見ることができます。 何か知りたい内容があるなら、このページの一番上にある検索バーを使うと良いですよ。 + +このドキュメントに対応した動作するModのコードは、[GitHubの `/reference` フォルダ](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21) にあります。 + +もしFabricのドキュメントに貢献したいなら、 [投稿ガイドライン](../contributing)を参照してください。ソースコードは [GitHub](https://github.com/FabricMC/fabric-docs)にあります。 diff --git a/versions/1.21/translated/ja_jp/index.md b/versions/1.21/translated/ja_jp/index.md new file mode 100644 index 000000000..31eab2dbc --- /dev/null +++ b/versions/1.21/translated/ja_jp/index.md @@ -0,0 +1,21 @@ +--- +title: Fabric ドキュメント +description: マインクラフトの前提ModであるFabricの、公式ドキュメント +layout: home +hero: + name: Fabric ドキュメント + tagline: マインクラフトの前提ModであるFabricの、公式ドキュメント +features: + - title: プレイヤーガイド + icon: 📚 + details: Fabric Modを探していますか? プレイヤーガイドにお任せください。 このガイドでは、ダウンロードから、インストール、そしてトラブルの解決までお助けします。 + link: /ja_jp/players/ + linkText: くわしく見る + - title: デベロッパガイド + icon: 🛠️ + details: Fabricのコミュニティによって書かれたこのデベロッパガイドは、環境構築からレンダリングやネットワーキングなどの高度な内容までを扱っています。 + link: /ja_jp/develop/ + linkText: 始めましょう +--- + +もしFabricのドキュメントに貢献したいなら、 [投稿ガイドライン](./contributing)を参照してください。ソースコードは [GitHub](https://github.com/FabricMC/fabric-docs)にあります。 diff --git a/versions/1.21/translated/ja_jp/sidebar_translations.json b/versions/1.21/translated/ja_jp/sidebar_translations.json new file mode 100644 index 000000000..32d3310c1 --- /dev/null +++ b/versions/1.21/translated/ja_jp/sidebar_translations.json @@ -0,0 +1,71 @@ +{ + "players.title": "プレイヤーガイド", + "players.faq": "よくある質問", + "players.installingJava": "Java のインストール", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Fabric のインストール", + "players.findingMods": "信頼できるMODを見つける", + "players.installingMods": "Modをインストール", + "players.troubleshooting": "トラブルシューティング", + "players.troubleshooting.uploadingLogs": "ログのアップロード", + "players.troubleshooting.crashReports": "クラッシュレポート", + "players.updatingFabric": "Fabricのアップデート", + "develop.title": "開発者ガイド", + "develop.gettingStarted": "はじめに", + "develop.gettingStarted.introduction": "Fabric とMOD開発への入門", + "develop.gettingStarted.devEnvSetup": "開発環境のセットアップ", + "develop.gettingStarted.creatingProject": "プロジェクトの作成", + "develop.gettingStarted.projectStructure": "プロジェクトの構成", + "develop.gettingStarted.launchGame": "ゲームの起動", + "develop.gettingStarted.solvingProblems": "基本的な問題解決", + "develop.items": "アイテム", + "develop.items.first-item": "最初のアイテムを作る", + "develop.items.food": "食べ物のアイテム", + "develop.items.custom-armor": "カスタム防具", + "develop.items.custom-tools": "カスタム道具", + "develop.items.custom-item-groups": "カスタムアイテムグループ", + "develop.items.custom-item-interactions": "カスタムアイテムの操作", + "develop.items.custom-enchantment-effects": "カスタムエンチャント効果", + "develop.items.potions": "ポーション", + "develop.items.custom-data-components": "カスタムデータコンポーネント", + "develop.blocks": "ブロック", + "develop.blocks.first-block": "最初のブロックを作る", + "develop.blocks.blockstates": "ブロックステート", + "develop.blocks.block-entities": "ブロックエンティティー", + "develop.blocks.block-entity-renderer": "ブロックエンティティレンダラー", + "develop.entities": "エンティティ", + "develop.entities.effects": "ステータス効果", + "develop.entities.damage-types": "ダメージタイプ", + "develop.commands": "コマンド", + "develop.commands.basics": "コマンドの作成", + "develop.commands.arguments": "コマンドの引数", + "develop.commands.suggestions": "コマンドの補完", + "develop.dataGeneration": "データ生成", + "develop.dataGeneration.setup": "データ生成のセットアップ", + "develop.dataGeneration.tags": "タグの生成", + "develop.dataGeneration.translations": "翻訳の生成", + "develop.dataGeneration.advancements": "進捗の生成", + "develop.dataGeneration.recipes": "レシピの生成", + "develop.dataGeneration.lootTables": "ルートテーブルの生成", + "develop.rendering": "レンダリング", + "develop.rendering.basicConcepts": "基本的なレンダリングの概念", + "develop.rendering.drawContext": "描画コンテキストの使用", + "develop.rendering.hud": "Hudでのレンダリング", + "develop.rendering.gui": "GUIとスクリーン", + "develop.rendering.gui.customScreens": "カスタムスクリーン", + "develop.rendering.gui.customWidgets": "カスタムウィジェット", + "develop.rendering.particles": "パーティクル", + "develop.rendering.particles.creatingParticles": "カスタムパーティクルの作成", + "develop.misc": "その他のページ", + "develop.misc.codecs": "コーデック", + "develop.misc.events": "イベント", + "develop.misc.text-and-translations": "テキストと翻訳", + "develop.misc.ideTipsAndTricks": "IDEのヒントとコツ", + "develop.misc.automatic-testing": "テストの自動化", + "develop.sounds": "サウンド", + "develop.sounds.using-sounds": "サウンドの再生", + "develop.sounds.custom": "カスタムサウンドの作成", + "develop.sounds.dynamic-sounds": "動的サウンド" +} diff --git a/versions/1.21/translated/ja_jp/website_translations.json b/versions/1.21/translated/ja_jp/website_translations.json new file mode 100644 index 000000000..7111e216b --- /dev/null +++ b/versions/1.21/translated/ja_jp/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "著者", + "authors.nogithub": "%s (GitHubにいない)", + "banner": "Fabric ドキュメントは未完成です。問題がある場合は %s や %s で報告してください。", + "description": "Minecraft の Modding ツール Fabric の総合的なドキュメント。", + "download": "ダウンロード %s", + "footer.next": "次のページ", + "footer.prev": "前のページ", + "github_edit": "GitHub上でこのページを編集する", + "lang_switcher": "言語の変更", + "last_updated": "最終更新", + "mode_dark": "ダークテーマに切り替える", + "mode_light": "ライトテーマに切り替える", + "mode_switcher": "外観", + "nav.contribute": "貢献", + "nav.contribute.api": "Fabric API", + "nav.download": "ダウンロード", + "nav.home": "ホーム", + "outline": "このページで", + "return_to_top": "一番上に戻る", + "search.back": "検索を閉じる", + "search.button": "検索", + "search.display_details": "詳細な結果を表示", + "search.footer.close": "閉じる", + "search.footer.close.key": "Escape", + "search.footer.down.key": "下矢印", + "search.footer.navigate": "選択", + "search.footer.up.key": "上矢印", + "search.footer.select": "開く", + "search.footer.select.key": "Enter", + "search.no_results": "ページが見つかりませんでした:", + "search.reset": "検索をリセット", + "sidebar_menu": "メニュー", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Fabric ドキュメンテーション", + "version.reminder": "このページで書かれているバージョン:", + "version.switcher": "バージョンを切り替える", + "404.code": "404", + "404.crowdin_link": "Crowdinで翻訳する", + "404.crowdin_link.label": "Crowdin Editorを開く", + "404.english_link": "英語で読む", + "404.english_link.label": "英語のバージョンを開く", + "404.link": "ホームに移動する", + "404.link.label": "ホームへ", + "404.quote": "このページは溶岩遊泳を試みた", + "404.title": "ページが見つかりません" +} diff --git a/versions/1.21/translated/ko_kr/contributing.md b/versions/1.21/translated/ko_kr/contributing.md new file mode 100644 index 000000000..38c25b336 --- /dev/null +++ b/versions/1.21/translated/ko_kr/contributing.md @@ -0,0 +1,253 @@ +--- +title: 기여 가이드라인 +description: Fabric 문서 기여 가이드라인 +--- + +# 기여 가이드라인 {#contributing} + +이 웹사이트는 [VitePress](https://vitepress.dev/)를 사용해 다양한 마크다운 파일에서 정적 HTML을 생성합니다. [여기](https://vitepress.dev/guide/markdown#features)에서 VitePress가 지원하는 마크다운 확장 기능에 익숙해져야 합니다. + +이 웹사이트에 기여하실 수 있는 세 가지의 방법이 있습니다: + +- [문서 번역](#translating-documentation) +- [기여 콘텐츠](#contributing-content) +- [기여 프레임워크](#contributing-framework) + +Fabric 문서 웹사이트의 모든 페이지는 스타일 가이드를 준수해야 합니다. + +## 문서 번역하기 + +문서를 한국어 또는 다른 언어로 번역하고 싶다면, [Fabric Crowdin](https://crowdin.com/project/fabricmc)에서 번역에 참여할 수 있습니다. + + + +## new-content 콘텐츠 기여 {#contributing-content} + +문서 콘텐츠에 기여하는 것은 Fabric 문서에 기여하는 가장 기본적인 방법입니다. + +모든 콘텐츠 기여는 다음 단계를 따르며 각 단계는 라벨과 연결됩니다: + +1. 로컬에서 변경 사항을 준비하고 PR을 푸시 +2. stage:expansion 필요한 경우의 확장 가이드라인 +3. stage:verification: 콘텐츠 인증 +4. stage:cleanup: 문법, 린팅... +5. stage:ready: 합체 준비 완료! + +모든 콘텐츠는 아래 스타일 가이드라인을 준수해야 합니다. + +### 1. 당신의 변경 사항을 준비하세요 {#1-prepare-your-changes} + +이 웹사이트는 오픈 소스이며, GitHub 리포지토리에서 개발되었으므로, 다음 GitHub의 흐름을 따릅니다: + +1. [GitHub 리포지토리 포크](https://github.com/FabricMC/fabric-docs/fork) +2. 포크에 새 브랜치 만들기 +3. 해당 브랜치에서 변경하기 +4. 원본 리포지토리에 끌어오기 요청 열기 + +GitHub 흐름에 대한 자세한 내용은 [여기](https://docs.github.com/en/get-started/using-github/github-flow)에서 확인할 수 있습니다. + +GitHub의 웹 UI에서 변경하거나 로컬에서 웹을 개발하고 미리 볼 수 있습니다. + +#### 포크 복사하기 {#clone-your-fork} + +로컬에서 개발하려면 [Git](https://git-scm.com/)을 설치해야 합니다. + +그런 다음, 리포지토리의 포크를 다음과 같이 복제하세요: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### 종속성 설치 {#install-dependencies} + +**만약 로컬에서 변경 사항을 미리 보려면, [Node.js 18+](https://nodejs.org/en/) 을 설치해야 합니다.** + +그런 다음 모든 종속성을 다음과 같이 설치하세요: + +```sh +npm install +``` + +#### 개발 서버 실행 {#run-the-development-server} + +개발 서버는 `localhost:5173`에서 로컬 변경 사항을 미리 볼 수 있게 합니다. 코드가 변경되면 변경 사항을 자동으로 적용합니다. + +```sh +npm run dev +``` + +이제 브라우저에서 `http://localhost:5173`을 방문해 웹사이트를 열고 탐색할 수 있습니다. + +#### 웹사이트 빌드 {#building-the-website} + +웹사이트를 빌드하면 모든 마크다운 파일이 정적 HTML로 컴파일되어 `.vitepress/dist` 에 저장됩니다. + +```sh +npm run build +``` + +#### 웹사이트 빌드 프리뷰 {#previewing-the-built-website} + +`.vitepress/dist`에 저장된 콘텐츠를 포트 `4173` 에서 볼 수 있도록 합니다: + +```sh +npm run preview +``` + +#### 끌어오기 요청 열기 {#opening-a-pull-request} + +만약 변경 사항에 만족하면, 변경 사항을 `푸시`할 수 있습니다: + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +그런 다음, `git push`의 출력에 있는 링크를 따라 PR을 여세요. + +### 2. stage:expansion 필요한 경우의 확장 가이드라인 {#2-guidance-for-expansion-if-needed} + +만약 문서화 팀에서 끌어오기 요청을 확장할 수 있다고 생각하면, 팀원 중 한 명이 끌어오기 요청에 stage:expansion 라벨과 함께 확장할 수 있다고 생각하는 내용을 설명하는 댓글을 추가할 것입니다. 제안에 동의하신다면, 문서 내용을 확장하시면 됩니다. + +끌어오기 요청에 따라 확장하길 원치 않지만, 이후 다른 사람이 확장하길 바랃나면, [Issues 페이지](https://github.com/FabricMC/fabric-docs/issues)에서 이슈를 생성하고 확장할 수 있다고 생각하는 내용을 설명해야 합니다. 추후 문서팀은 당신의 PR에 help-wanted 라벨을 추가할 것입니다. + +### 3. stage:verification 콘텐츠 인증 {#3-content-verification} + +이 단계는 콘텐츠가 정확하고 Fabric의 문서 스타일 가이드를 준수하는지의 여부를 확인하는 단계이므로 가장 중요합니다. + +이 단계에서는 다음 질문에 답해야 합니다: + +- 모든 콘텐츠가 올바른가요? +- 모든 콘텐츠가 최신인가요? +- 콘텐츠가 다양한 운영 체제 등의 모든 경우에 적용되나요? + +### 4. stage:cleanup 클린업 {#4-cleanup} + +이 단계에서는 다음과 같은 일이 발생합니다: + +- [[LanguageTool(https://languagetool.org/)을 사용하여 문법 문제 수정 +- [`markdownlint`](https://github.com/DavidAnson/markdownlint)를 사용해 모든 마크다운 파일 린트하기 +- [Checkstyle](https://checkstyle.sourceforge.io/)을 사용해 모든 Java 코드 서식 지정 +- 다른 기타 수정 또는 개선 사항 + +## framework 프레임워크에 기여하기 {#contributing-framework} + +프레임워크는 웹사이트의 내부 구조를 나타내며, 모든 끌어오기 요청은 framework 라벨이 붙습니다. + +프레임워크 끌어오기 요청은 [Fabric Discord](https://discord.gg/v6v4pMv) 또는 GitHub 이슈에서 문서 개발 팀과 모든 협의가 끝난 후에만 생성해야 합니다. + +:::info +사이드바 또는 네비게이션 바 구성 변경은 프레임워크 끌어오기 요청으로 간주하지 않습니다. +::: + +## 스타일 가이드라인 {#style-guidelines} + +가이드에 대해 궁금한것이 있다면, [Fabric Discord](https://discord.gg/v6v4pMv) GitHub 토론을 통해 질문할 수 있습니다. + +### 원본을 미국식 영어로 작성하기 {#write-the-original-in-american-english} + +모든 원본 문서는 미국 문법의 영어로 작성되었습니다. + +### Frontmatter에 데이터 추가하기 {#add-data-to-the-frontmatter} + +모든 페이지는 파일 최상단에 제목과 설명이 입력되어야 합니다. + +Markdown 파일의 frontmatter에 있는 `authors`에 GitHub 사용자 이름을 추가하는 것을 잊지 마세요! 이렇게 하면, 저희는 당신에게 적당한 크레딧을 제공할 수 있습니다. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### 제목에 앵커 추가하기 {#add-anchors-to-headings} + +각 제목은 해당 제목에 연결하는 데 쓰이는 앵커가 있어야 합니다: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +앵커에는 반드시 소문자, 숫자 및 대시를 사용해야 합니다. + +### `/reference` 모드 이내 코드 배치하기 {#place-code-within-the-reference-mod} + +만약 코드를 포함하는 페이지를 만들거나 수정하는 경우, 코드를 적절한 위치 내의 리퍼런스 모드 에 배치해야 합니다. (리포지토리의 `/reference` 폴더에 있습니다) 그런 다음, [VitePress의 코드 스니펫 기능](https://vitepress.dev/guide/markdown#import-code-snippets)을 이용하여 코드를 임베드합니다. + +예를 들어, 리퍼런스 모드에서 `FabricDocsReference.java` 파일의 15에서 21번째 줄을 하이라이트하려면: + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +만약 span을 더 복잡하게 제어해야 하는 경우, [`markdown-it-vuepress-code-snippet-enhanced` 의 트랜스클루전 기능](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced)을 이용할 수 있습니다. + +예를 들어, 이렇게 하면, 위 파일에서 `#entrypoint` 태그로 표시된 섹션이 임베드될 것입니다. + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### 각 섹션마다 새 사이드바 만들기 {#create-a-sidebar-for-each-new-section} + +새로운 섹션을 만들 때는, `.vitepress/sidebars` 폴더에 `config.mts` 파일을 생성해 새로운 사이드바를 생성해야 합니다. + +만약 도움이 필요하시다면, [Fabric Discord](https://discord.gg/v6v4pMv)의 `#docs` 채널에 질문해 주세요. + +### 관련 사이드 바에 새 페이지 추가하기 {#add-new-pages-to-the-relevant-sidebars} + +새로운 페이지를 생성할 때도, `.vitepress/sidebars` 폴더에 연결을 추가해야 합니다. + +역시나, 도움이 필요하시면 Fabric Discord의 `#docs` 채널에 질문하시면 됩니다. + +### `/assets`에 미디어 배치하기 {#place-media-in-assets} + +모든 이미지는 `/assets` 폴더의 적당한 위치에 저장되어야 합니다. + +### 상대적 링크 사용하기! {#use-relative-links} + +이렇게 해야 버전 관리 시스템이 마련되어 있어 링크를 처리해 미리 버전을 추가하기 때문입니다. 절대 링크를 사용하면, 버전 번호가 링크에 추가되지 않습니다. + +또한 링크에 파일 확장자를 추가해서는 안 됩니다. + +예를 들어서, `/players` 폴더의 `installing-fabric` 페이지를 언급하려는 경우, 절대 경로는 `/players/installing-fabric.md` 이지만, 다음과 같이 연결해야 합니다. + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/ko_kr/develop/blocks/blockstates.md b/versions/1.21/translated/ko_kr/develop/blocks/blockstates.md new file mode 100644 index 000000000..ff512a1b0 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/blocks/blockstates.md @@ -0,0 +1,127 @@ +--- +title: 블록 상태 +description: 블록 상태가 블록에 시각적 기능을 추가하는 좋은 방법인 이유에 대하여 알아보세요. +authors: + - IMB11 +--- + +# 블록 상태 {#block-states} + +블록 상태는 속성의 형태로 한 블록의 모든 정보를 포함하는 Minecraft 세계에서 단일 블록에 등록된 데이터의 조각입니다. 바닐라가 블록 상태에 저장하는 몇 가지 속성의 예시입니다: + +- Rotation: 주로 원목이나 기타 자연 블록에 사용됩니다. +- Activated: 레드스톤 장치 및 화로나 훈연기와 같은 블록에 사용됩니다. +- Age: 작물, 식물, 묘목, 켈프 등에 사용됩니다. + +세계의 용량을 줄이고, TPS 문제를 막아주기 때문에 — 또한 블록 엔티티 안에 NBT 데이터를 저장하는 것의 필요가 없습니다. — 아마도 이것들이 왜 유용한지 알 수 있습니다. + +블록 상태 정의는 `assets//blockstates` 폴더에서 찾을 수 있습니다. + +## 예시: 기둥 블록 {#pillar-block} + + + +Minecraft는 이미 빠르게 특정 종류의 블록을 만들 수 있도록 하는 몇 가지의 맞춤 클래스가 이미 있습니다. 이 예시는 "Condensed Oak Log" 블록을 생성하여 `axis` 속성을 사용하여 블록을 생성하는 과정을 보여 줍니다. + +바닐라 `PillarBlock` 클래스는 블록이 X, Y 혹은 Z축에 배치할 수 있도록 합니다. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +기둥 블록은 두 가지의 텍스처 — 윗면과 옆면 — 이 있습니다. `block/cube_column` 모델을 사용합니다. + +언제나 모든 블록 텍스처들의 경우, 텍스처 파일은 `assets//textures/block` 에서 찾을 수 있습니다. + +텍스처 + +기둥 블록이 두 개의 위치 — 수평과 수직 — 가 있기 때문에, 분리된 각각의 모델 파일을 만들어야 합니다. + +- `block/cube_column_horizontal` 모델을 확장하는 `condensed_oak_log_horizontal.json`. +- `block/cube_column` 모델을 확장하는 `condensed_oak_log.json`. + +`condensed_oak_log_horizontal.json` 파일의 예시: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +모든 블록 상태 파일 안의 수정자에 대한 더 자세한 보기는 [Minecraft 위키 - 모델 문단 (Block States) (영어)](https://minecraft.wiki/w/Tutorials/Models#Block_states)에 있습니다. +::: + +다음으로, 블록 상태 파일을 생성하여야 합니다. 블록 상태 파일은 마법이 일어나는 곳입니다. 기둥 블록은 세 개의 축이 있으므로, 다음 상황에서 특정 모델을 사용할 것입니다: + +- `axis=x` - 블록이 X축을 따라 설치되면, 양의 X축 방향을 향하도록 모델을 회전할 것입니다. +- `axis=y` - 블록이 Y축을 따라 설치되면, 기본 수직 모델을 사용할 것입니다. +- `axis=z` - 블록이 Z축을 따라 설치되면, 양의 Z축 방향을 향하도록 모델을 회전할 것입니다. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +언제나 블록에 대한 번역과 두 모델 중 하나의 부모격이 되는 아이템 모델을 만들어야 할 것입니다. + +![게임 안에서의 기둥 블록의 예시](/assets/develop/blocks/blockstates_1.png) + +## 사용자 정의 블록 상태 {#custom-block-states} + +사용자 지정 블록 상태는 블록이 고유한 속성을 가지고 있을 때 유용합니다. 때때로 바닐라 속성을 재사용하여 만든 블록을 발견할 수도 있습니다. + +이 예시는 `activated`라 불리는 고유한 불 (boolean) 속성을 생성할 것입니다. 플레이어가 블록에 오른쪽 클릭할 때, `activated=false`에서 `activated=true`로 변환하여서 이에 따라 텍스처를 변경합니다. + +### 속성 만들기 {#creating-the-property} + +먼저, 속성이 불이기 때문에 속성 자체를 만들어야 합니다. `BooleanProperty.of` 메서드를 사용할 것입니다. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +다음으로, `appendProperties` 메서드에 있는 블록 상태 관리자에 속성을 추가하여야 합니다. 빌더에 접근하기 위하여 메서드를 덮어써야 할 것입니다: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +또한 사용자 정의 블록의 생성자에서 `activated` 속성의 기본 상태를 설정하여야 합니다. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +`Block` 대신 사용자 지정 클래스를 이용하여 블록을 등록하는 것을 잊지 마세요! +::: + +### 속성 사용하기 {#using-the-property} + +이 예시는 플레이어가 블록과 상호작용을 할 때 불 `activated` 속성을 뒤집습니다. 이를 위하여 `onUse` 메서드를 재정의할 수 있습니다: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### 속성 시각화하기 {#visualizing-the-property} + +블록 상태 파일을 만들기 전, 블록 모델과 같이 블록이 활성화되었을 때와 비활성화되었을 때의 텍스처를 제공하여야 합니다. + +텍스처 + +블록의 두 모델 — 활성화된 상태와 비활성화된 상태 — 을 만들기 위하여 블록 모델의 지식을 이용하세요. 끝난 다음, 블록 상태 파일을 계속하여 만들 수 있습니다. + +새 속성을 만들었으면, 그 속성을 설명하기 위하여 블록에 대한 블록 상태 파일을 업데이트하여야 합니다. + +만약 블록에 여러 개의 속성이 있는 경우, 가능한 모든 조합을 고려하여야 합니다. 예시로, `activated`와 `axis`는 6개의 조합으로 이어집니다. (`activated`가 가능한 두 개의 값과, `axis`가 가능한 세 개의 값). + +블록이 오직 두 개의 가능한 변형이 있고, 오직 한 개의 속성 (`activated`)가 있으므로, 블록 상태 JSON 파일은 다음과 같을 것입니다. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +예시 블록이 바다 랜턴이기 때문에, 또한 `activated` 속성이 true (참)일 때 발광하도록 만들어야 합니다. 이는 블록을 등록할 때 생성자로 전달된 블록 설정을 통하여 완료될 수 있습니다. + +`luminance` 메서드를 통하여 블록이 발광할 때의 빛 단계를 조정할 수 있고, `activated` 속성에 기반한 빛 단계를 반환하기 위하여 `PrismarineLampBlock` 클래스에 정적 메서드를 만들 수 있으며, 메서드 참조로서 `luminance` 메서드에 대하여 전달할 수도 있습니다: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +모든 작업을 완료하면, 최종 결과는 다음과 같이 보일 것입니다: + + diff --git a/versions/1.21/translated/ko_kr/develop/blocks/first-block.md b/versions/1.21/translated/ko_kr/develop/blocks/first-block.md new file mode 100644 index 000000000..7027c3714 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/blocks/first-block.md @@ -0,0 +1,170 @@ +--- +title: 첫 번째 블록 만들기 +description: Minecraft에서의 첫 번째 블록을 만드는 법을 알아보세요. +authors: + - IMB11 + - xEobardThawne + - its-miroma +--- + +# 첫 번째 블록 만들기 {#creating-your-first-block} + +블록은 Minecraft에서의 건축 블록입니다 (말장난 아님). Minecraft의 다른 모든 것들처럼, 마찬가지로 레지스트리에 저장됩니다. + +## 블록 클래스 준비하기 {#preparing-your-blocks-class} + +만약 [첫 번째 블록 만들기](../items/first-item) 페이지를 성공했다면, 이 과정은 아주 친숙하게 느껴질 것입니다. 블록과 그 아이템을 등록하는 메서드를 만들어야 합니다. + +이 메서드를 `ModBlocks`이라 불리는 클래스에 넣어야 합니다. (아니면 마음대로 이름 지으세요). + +Mojang은 바닐라 블록과 매우 비슷한 무언가를 수행합니다. `Blocks` 클래스를 참조하여 어떻게 하였는지 참고해도 됩니다. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +아이템처럼, 블록 인스턴스가 포함된 모든 정적 필드가 초기화되도록 클래스가 불러와졌음을 확인하여야 합니다. + +이것을 정적 초기화를 트리거하기 위해 모드 이니셜라이저에서 호출될 수 있는 더미 `initialize` 메서드를 만듦으로써 할 수도 있습니다. + +:::info +만약 정적 초기화가 무엇인지 모르겠다면, 이는 클래스에서 정적 필드를 초기화하는 과정입니다. 이는 JVM에 의해 클래스가 로드될 때 끝나며, 어느 클래스의 인스턴스가 만들어지기 전에 끝납니다. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## 블록을 추가하고 등록하기 {#creating-and-registering-your-block} + +아이템처럼, 블록은 생성자에서 `Blocks.Settings` 클래스를 이용하여 소리 효과와 채굴 단계와 같은 블록의 속성을 지정합니다. + +여기선 모든 옵션을 다루지는 않습니다. 클래스를 직접 보면 자명한 다양한 옵션을 볼 수 있습니다. + +예시로, 흙의 속성을 가지고 있지만, 다른 재질의 간단한 블록을 만들어 볼 것입니다. + +:::tip +또한 이미 존재하는 블록의 설정을 복사하기 위하여 `AbstractBlock.Settings.copy(AbstractBlock block)을 사용할 수 있습니다. 이 상황에서, 흙의 설정을 복사하기 위해 `Blocks.DIRT\`를 사용할 수도 있지만 예시를 위해 빌더를 사용할 것입니다. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +자동으로 블록 아이템을 만들기 위하여, 이전 단계에서 만든 `register` 메서드의 `shouldRegisterItem` 매개변수를 `true`를 전달하면 됩니다. + +### 아이템 그룹에 블록 추가하기 {#adding-your-block-to-an-item-group} + +`BlockItem` 이 자동으로 만들어졌고 등록되었기 때문에, 아이템 그룹에 추가시키기 위해, `Block.asItem()` 메서드를 사용하여 `BlockItem` 인스턴스를 가져올 것입니다. + +예시로, [사용자 지정 아이템 그룹](../items/custom-item-groups) 페이지에서 만든 사용자 지정 그룹을 사용할 것입니다. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +이제 크리에이티브 인벤토리에 블록이 있고, 세계에 설치할 수 있음을 알 수 있습니다! + +![적합한 모델이나 텍스처가 없는 세계의 블록](/assets/develop/blocks/first_block_0.png). + +여기엔 몇가지 문제가 있습니다. 블록의 이름이 없으며, 텍스처도 없고 블록 모델이나 아이템 모델도 없습니다. + +## 블록 번역 추가하기 {#adding-block-translations} + +번역을 추가하기 위하여, 번역 파일 (`assets//lang/en_us.json`)에 번역 키를 만들어야 합니다. + +Minecraft는 이 번역을 크리에이티브 인벤토리나 명령어 피드백과 같은 블록의 이름이 표시되는 다른 곳에 사용할 것입니다. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +모드를 빌드하기 위하여 게임을 다시 시작하거나 F3 + T를 눌러 변경 사항을 적용할 수 있습니다. 그러면 크리에이티브 인벤토리나 통계 화면과 같은 다른 곳에 블록의 이름이 있는 것이 보일 것입니다. + +## 모델 및 텍스처 {#models-and-textures} + +모든 블록의 텍스처는 `assets//textures/block` 폴더에서 찾을 수 있습니다. 예시 텍스처인 "거친 흙" 블록은 무료로 사용할 수 있습니다. + + + +텍스처가 게임 안에서 보이게 하려면, "거친 흙" 블록의 다음 위치에서 찾을 수 있는 블록 및 아이템 모델을 만들어야 합니다: + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +이 아이템 모델은 꽤 단순합니다. 대부분의 블록 모델이 GUI에서 렌더되는 것을 지원하기 때문에그저 상위 모델로 블록 모델을 사용할 수 있습니다: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +하지만, 이 블록 모델은, 이 상황에서, `block/cube_all` 모델의 상위 모델이어야 합니다: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +게임으로 불러왔을 때, 여전히 텍스처가 없을 수도 있습니다. 왜냐하면 블록 상태 정의를 추가해야 하기 때문입니다. + +## 블록 상태 정의 만들기 {#creating-the-block-state-definition} + +블록 상태 정의는 현재 상태의 블록을 기반으로 어떤 모델을 렌더할지 게임에게 지시하는 데 쓰입니다. + +이 복잡한 상태 정의가 없는 예시 블록의 경우, 오직 한 개의 항목만이 정의에 필요합니다. + +파일은 `assets/mod_id/blockstates` 폴더에 위치해야 하며, 이름은 `ModBlocks` 클래스를 등록했을 때 사용한 블록 ID와 일치하여야 합니다. 예시로, 만약 블록 ID가 `condensed_dirt`라면, 파일 이름은 `condensed_dirt.json`이 되어야 합니다. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +블록 상태는 정말 복잡합니다. 그러므로, [블록 상태](./blockstates) 페이지에서 다루겠습니다. + +게임을 다시 시작하거나, F3 + T을 통해 다시 불러와 변경 사항을 적용하세요. 블록 텍스처가 인벤토리 안과 실제 세계에서 볼 수 있을 것입니다. + +![적합한 모델이나 텍스처가 있는 세계의 블록](/assets/develop/blocks/first_block_4.png) + +## 블록 떨굼 추가하기 {#adding-block-drops} + +서바이벌 모드에서 블록을 부쉈을 때, 블록이 떨어지지 않는 것을 봤을 수도 있습니다. 아마 이 기능을 원하였을 수도 있습니다. 하지만 블록을 부숴서 떨어지게 만들기 위하여 노획물 목록을 구현하여야 합니다. 노획물 목록은 `data//loot_table/blocks/` 폴더에 위치해야 합니다. + +:::info +노획물 목록에 대하여 더 자세히 알고 싶으면, [Minecraft 위키 - 노획물 목록](https://ko.minecraft.wiki/w/%EB%85%B8%ED%9A%8D%EB%AC%BC_%EB%AA%A9%EB%A1%9D) 페이지를 참고할 수 있습니다. +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +이 노획물 목록은 블록이 부서질 때나 폭발할 때 단일 블록 아이템의 떨굼을 제공합니다. + +## 부술 도구 추천하기 {#recommending-a-harvesting-tool} + +아마 특정한 도구만을 이용하여 블록을 부술 수 있도록 하고 싶을 수 있습니다. 예시로 삽을 이용해 블록을 더 빠르게 부술 수 있도록 하고 싶게 할 수 있습니다. + +모든 도구 태그는 `data/minecraft/tags/block/mineable/` 폴더에 있을 것입니다. 파일 이름은 사용한 도구에 따라 다르며, 다음을 따라 달라집니다: + +- `hoe.json` (괭이) +- `axe.json` (도끼) +- `pickaxe.json` (곡괭이) +- `shovel.json` (삽) + +이 파일의 내용은 꽤 단순합니다. 태그에 추가되어야 할 아이템의 목록입니다. + +이 예시는 "거친 흙" (Condensed Dirt) 블록을 `shovel` (삽) 태그에 추가시킵니다. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +만약 블록을 부수기 위하여 특정한 도구를 사용하여야 하게 하길 원한다면, 블록 설정에 `.requiresTool()`을 추가하고 적절한 채굴 태그를 추가하여야 합니다. + +## 채굴 단계 {#mining-levels} + +비슷하게, 채굴 단계 태그는 `data/minecraft/tags/block/` 폴더에서 찾을 수 있고, 다음 형식을 따릅니다: + +- `needs_stone_tool.json` - 최소 단계가 돌 도구 +- `needs_iron_tool.json` - 최소 단계가 철 도구 +- `needs_diamond_tool.json` - 최소 단계가 다이아몬드 도구 + +이 파일은 부술 도구 파일과 같은 형식을 가지고 있습니다. 태그에 추가되어야 할 아이템의 목록입니다. + +## 추가 사항 {#extra-notes} + +만약 많은 블록을 추가하려 한다면, 아마도 블록 및 아이템 모델을 만드는 과정, 블록 상태 정의, 노획물 목록 등을 자동화하기 위하여 [데이터 생성](https://fabricmc.net/wiki/tutorial:datagen_setup)을 사용하는 것을 고려하여 볼만 합니다. diff --git a/versions/1.21/translated/ko_kr/develop/commands/arguments.md b/versions/1.21/translated/ko_kr/develop/commands/arguments.md new file mode 100644 index 000000000..310c9a015 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/commands/arguments.md @@ -0,0 +1,64 @@ +--- +title: 명령어 인수 +description: 복잡한 인수를 가진 명령어를 만드는 방법을 알아보세요. +--- + +# 명령어 인수 {#command-arguments} + +인수는 대부분의 명령어에서 사용됩니다. 인수는 항상 필수적이진 않습니다. 다시 말해, 어떤 인수는 값을 입력하지 않더라도 명령어가 정상 작동한다는 의미입니다. 하나의 노드는 여러 개의 타입을 가질 수 있지만, 타입이 모호해지면 오류의 원인이 될 수 있으므로 그런 경우는 최대한 피해야 합니다. + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +이런 경우에는, `/command_with_arg` 명령어 다음에 정수를 입력해야 합니다. 예를 들어, 만약 `/command_with_arg 3`를 실행하면, 다음과 같은 피드백 메시지를 받을 것입니다: + +> Called /command_with_arg with value = 3 + +만약 `/command_with_arg` 를 아무런 인수 없이 실행하면, 명령어가 올바르게 작동하지 않을 것입니다. + +이제 선택적인 두 번째 인수를 추가해보겠습니다. + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +이렇게 하면 한 개 또는 두 개의 정수형을 입력할 수 있게 됩니다. 만약 한 개의 정수만 입력하면, 피드백 메세지에선 한 가지 값만 출력될 것입니다. 반대로 두 개의 정수을 모두 입력하면, 피드백 메세지에선 두 개의 값을 모두 출력할 것입니다. + +비슷한 처리를 두 번이나 정의할 필요는 없습니다. 대신, 비슷한 처리를 하는 두 가지 인수는 이렇게 만들 수 있습니다. + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 사용자 정의 인수 타입 {#custom-argument-types} + +만약 바닐라에 사용하려는 인수 타입이 없다면, 직접 인수 타입을 만들 수도 있습니다. 만드는 방법을 알아보자면, 먼저 `ArgumentType` 인터페이스를 상속하는 클래스를 만들어야 합니다. 이때, `T`는 인수의 타입을 의미합니다. + +이제 입력된 문자열을 원하는 타입으로 변환하기 위해 `parse` 메서드를 구현해야 합니다. + +예를 들어, `{x, y, z}` 형태로 입력된 문자열을 `BlockPos`로 변환해보겠습니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### 사용자 정의 인수 타입의 등록 {#registering-custom-argument-types} + +:::warning +명령어를 올바르게 작동하게 하려면 서버와 클라이언트 모두에 사용자 정의 인수 타입을 등록해야 합니다! 그렇지 않으면 정상적으로 작동하지 않을 것입니다. +::: + +모드 초기화 단계의 `onInitialize` 메서드 에서 `ArgumentTypeRegistry` 클래스를 통해 사용자 정의 인수 타입을 등록할 수 있습니다. + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### 사용자 정의 인수 타입의 사용 {#using-custom-argument-types} + +명령어 빌더의 `.argument` 메서드에 인스턴스를 입력하여 명령어에 사용자 정의 인수 타입을 사용할 수 있습니다. + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +명령어를 실행하여 인수 형태가 작동하는지 여부를 확인할 수 있습니다. + +![올바르지 않은 인수](/assets/develop/commands/custom-arguments_fail.png) + +![올바른 인수](/assets/develop/commands/custom-arguments_valid.png) + +![명령어 결과](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/ko_kr/develop/commands/basics.md b/versions/1.21/translated/ko_kr/develop/commands/basics.md new file mode 100644 index 000000000..334f3441a --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/commands/basics.md @@ -0,0 +1,174 @@ +--- +title: 명령어 만들기 +description: 복잡한 인수와 동작을 가진 명령어를 만들어 보세요. +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple +--- + +# 명령어 만들기 {#creating-commands} + +"명령어 만들기"에서는 모드 개발자가 명령어를 통한 기능을 추가하는 방법에 대해 설명합니다. 이 튜토리얼에서는 Brigadier의 일반적인 명령어 구조는 무엇이며, 어떻게 명령어를 등록하는지 알아볼 것입니다. + +::: info +Brigadier is a command parser and dispatcher written by Mojang for Minecraft. It is a tree-based command library where +you build a tree of commands and arguments. + +Brigadier는 오픈 소스로, 원본 소스 코드는 여기에서 확인할 수 있습니다: + +## `Command` 인터페이스 {#the-command-interface} + +`com.mojang.brigadier.Command`는 특정 코드를 실행하고 `CommandSyntaxException`을 던지는 기능형 인터페이스 이며, _명령어의 소스_ 의 타입을 결정하는 제네릭 타입 `S`를 가집니다. 인수처럼, 하위 명령어 노드도 필수적이진 않습니다. +명령어 소스는 명령어를 실행한 대상자를 의미합니다. Minecraft에서, 명령어 소스는 서버를 의미하는 `ServerCommandSource`, 명령 블록, 원격 연결 (RCON), 그리고 플레이어와 엔티티가 있습니다. + +`Command`의 `run(CommandContext)` 메서드는 `CommandContext`를 인수로 받아 정수를 반환합니다. 명령어 컨텍스트에선 명령어 소스 `S`와, 인수, 분석된 명령어 노드 또는 명령어의 입력을 받아올 수 있습니다. + +다른 기능형 인터페이스처럼, 이 인터페이스에는 대부분 람다식 또는 메서드 참조가 사용됩니다. + +```java +Command command = context -> { + return 0; +}; +``` + +치트를 켜지 않으면 대부분의 명령어를 탭 자동 완성에서 볼 수 없는 이유이기도 합니다. 일반적으로 음수 값은 명령어를 실행하는데 실패했고, 아무것도 실행되지 않았음을 의미합니다. `0`은 명령어가 성공적으로 처리되었음을 의미하고, 양수 값은 명령어가 성공적으로 작동했으며 어떠한 작업이 실행되었음을 의미합니다. Brigadier는 성공을 나타내는 상수 `Command#SINGLE_SUCCESS` 를 제공하고 있습니다. + +### `ServerCommandSource`의 역할 {#what-can-the-servercommandsource-do} + +예를 들어, 명령어가 전용 서버 환경에서만 등록되도록 해보겠습니다. `ServerCommandSource`는 명령어를 실행한 엔티티, 명령어가 실행된 세계 또는 서버 등 명령어가 실행될 때 추가적인 컨텍스트를 제공합니다. + +`CommandContext` 인스턴스에서 `getSource()` 메서드를 호출해 명령어 컨텍스트에서 명령어 소스에 접근할 수도 있습니다. + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## 기본 명령어의 등록 + +명령어는 Fabric API에서 제공하는 `CommandRegistrationCallback` 을 통해 등록됩니다. + +:::info +콜백을 등록하는 방법은 [이벤트](../events) 가이드를 참고하세요. +::: + +이벤트는 모드 초기화 단계에 등록되어야 합니다. + +콜백은 다음 세 가지 매개변수를 가집니다. + +- `CommandDispatcher dispatcher` - 명령어를 등록, 분석하고 실행하는 데 사용됩니다. `S`는 명령어 디스패처가 지원하는 명령어 소스의 타입입니다. +- `CommandRegistryAccess registryAccess` - 특정한 명령어 인수 메서드에 입력될 수 있는 레지스트리의 추상화를 제공합니다. +- `CommandManager.RegistrationEnvironment environment` - 명령어가 등록되는 서버의 유형을 식별합니다. + +이제 모드 초기화에서 간단한 명령어를 한번 등록해봅시다. + +@[code lang=java transcludeWith=:::test_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +`sendFeedback()` 메서드의 첫 번째 인수는 보내질 텍스트이며, 텍스트 오브젝트의 필요 없는 인스턴스화를 막기 위해 `Supplier` 로 제공됩니다. + +두 번째 인수는 다른 관리자에게 피드백을 전송할지 결정합니다. 일반적으로, 세계 시간이나 플레이어의 점수를 출력하는 등 세계에 영향을 주지 않는 명령어라면 `false` 로 설정됩니다. 반대로 시간이나 플레이어의 점수를 변경하는 등 명령어가 세계에 영향을 준다면 `true` 가 되게 됩니다. + +만약 명령어를 처리하는 데 실패한다면, `sendFeedback()`을 호출하는 대신에 바로 예외를 던질 수 있습니다. + +`CommandSyntaxException`은 일반적으로 명령어나 인수의 구문 오류를 나타낼 때 던져집니다. 원한다면 자신만의 예외도 구현할 수 있습니다. + +방금 등록한 명령어를 실행하려면, 대소문자를 구분하여 `/test_command`를 입력하면 됩니다. + +:::info +이 시점부터, `.execute()` 빌더에 전달된 람다식 이내에서 작성된 로직을 개별 메서드로 추출하겠습니다. 그런 다음 `.execute()`에 대한 메서드 참조를 전달할 수 있습니다. 이는 명확함을 위해 수행되었습니다. +::: + +### 등록 환경 {#registration-environment} + +원하는 경우 명령어가 특정한 상황에만 등록되도록 할 수도 있습니다. 예를 들어, 명령어가 전용 서버 환경에서만 등록되도록 해보겠습니다. + +@[code lang=java highlight={2} transcludeWith=:::dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### 명령어의 요구 사항 {#command-requirements} + +관리자만 실행 가능한 명령어를 만들고 싶다고 가정해봅시다. `require()` 메서드를 사용하기 딱 좋은 상황이군요. `require()` 메서드는 `ServerCommandSource`를 제공하고 `CommandSource`가 명령어를 실행할 수 있는지 판단하는 `Predicate`을 인수로 가집니다. + +@[code lang=java highlight={3} transcludeWith=:::required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +이렇게 하면 명령 블록을 포함해 명령어 소스가 적어도 레벨 2 관리자는 되어야 명령어를 실행할 수 있게 됩니다. 요구 사항을 충족하지 못한다면 명령어는 등록조차 되지 않게 됩니다. + +하지만, 명령어가 등록이 되지 않아 레벨 2 관리자가 아닌 플레이어에게는 탭 자동 완성에서 표시되지 않는다는 단점이 있습니다. 치트를 켜지 않으면 대부분의 명령어를 탭 자동 완성에서 볼 수 없는 이유이기도 합니다. + +### 하위 명령어 + +하위 명령어를 추가하려면, 먼저 상위 명령어의 리터럴 노드를 등록해야 합니다. 그런 다음, 상위 명령어의 리터럴 노드 다음에 하위 명령어의 리터럴 노드를 덧붙이면 됩니다. + +@[code lang=java highlight={3} transcludeWith=:::sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +인수처럼, 하위 명령어 노드도 필수적이진 않습니다. 아래와 같은 상황에선, `/command_two`와 `/command_two sub_command_two` 모두 올바른 명령어가 되게 됩니다. + +@[code lang=java highlight={2,8} transcludeWith=:::sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 클라이언트 명령어 {#client-commands} + +Fabric API는 `net.fabricmc.fabric.api.client.command.v2` 패키지에 클라이언트측 명령어를 등록할 때 사용되는 `ClientCommandManager` 클래스를 가지고 있습니다. 이러한 코드는 오로지 클라이언트측 코드에만 있어야 합니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## 명령어 리다이렉션 {#command-redirects} + +"별칭 (Aliases)"로도 알려진 명령어 리다이렉션은 명령어의 기능을 다른 명령어로 리다이렉트(전송)하는 방법입니다. 명령어의 이름을 변경하고 싶지만, 기존 이름도 지원하고 싶을 때 유용하게 사용될 수 있습니다. + +:::warning +Brigadier는 [인수를 사용해 명령 노드만 리다이렉트 시킬 것입니다](https://github.com/Mojang/brigadier/issues/46). 만약 인수 없이 명령 노드를 리다이렉션하려면 예제에 설명된 것과 동일한 로직에 대한 참조와 함께 '.executes()\` 빌더를 제공하세요. +::: + +@[code lang=java transcludeWith=:::redirect_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_redirected_by](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 자주 묻는 질문 {#faq} + +### 왜 내 코드가 컴파일되지 않나요? {#why-does-my-code-not-compile} + +- `CommandSyntaxException` 예외를 던지거나 처리해 보세요. `CommandSyntaxException`은 `RuntimeException`이 아닙니다. 만약 던진다면, 메소드 시그니처에서 `CommandSyntaxException`을 발생시키는 메서드에 있어야 합니다. 그렇지 않으면, 처리되어야 합니다. + Brigadier가 확인된 예외를 처리하고 게임에서 적절한 오류 메세지를 전송할 것입니다. + +- 제네릭 타입이 올바른지 확인해 보세요. 가끔 제네릭 타입에 문제가 있을 수도 있습니다. (대부분의 경우처럼) 명령어를 서버에 등록하려 한다면, `LiteralArgumentBuilder.literal` 대신에 `CommandManager.literal`, 또는 `RequiredArgumentBuilder.argument` 대신에 `CommandManager.argument`를 사용 중인지 확인하세요. + +- `sendFeedback()` 메서드를 확인해 보세요. 두 번째 인수에 불리언을 추가하는 것을 잊었을지도 모릅니다. 그리고 Minecraft 1.20부터 첫 번째 인수가 `Text`가 아니라 `Supplier` 임을 기억하세요. + +- 명령어는 무조건 정수를 반환해야 합니다. 명령어를 등록할 때, `execute()` 메서드는 `Command` 객체를 (대부분의 경우 람다식으로) 받게 됩니다. 람다식은 무조건 정수를 반환해야 합니다. + +### 런타임에서 명령어를 등록할 수 있나요?
+ +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +그 다음에는, `CommandManager.sendCommandTree(ServerPlayerEntity)`를 통해 모든 플레이어에게 다시 명령어 트리를 전송해야 합니다. + +클라이언트는 로컬로 완료 오류를 보여주기 위해 로그인 단계 중에 (또는 관리자 패킷이 전송되었을 때) 서버로부터 명령어 트리를 받아 캐시하기 때문에 필수적인 작업입니다. +::: + +### 런타임에서 명령어를 등록 해제할 수 있나요? {#can-i-unregister-commands-at-runtime} + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +간단하게 하려면, Brigadier를 리플렉션해서 노드를 제거해야 합니다. 그 다음에는, `CommandManager.sendCommandTree(ServerPlayerEntity)`를 통해 모든 플레이어에게 다시 명령어 트리를 전송해야 합니다. + +업데이트된 명령어 트리를 전송하지 않으면, 서버가 명령어 처리에 실패해도 클라이언트는 아직 명령어가 존재한다고 표시할 것입니다. +::: diff --git a/versions/1.21/translated/ko_kr/develop/commands/suggestions.md b/versions/1.21/translated/ko_kr/develop/commands/suggestions.md new file mode 100644 index 000000000..97f3c3b7d --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/commands/suggestions.md @@ -0,0 +1,49 @@ +--- +title: 명령어 제안 +description: 어떻게 명령어 인수를 플레이어에게 제안하는지 알아보세요. +authors: + - IMB11 +--- + +# 명령어 제안 {#command-suggestions} + +Minecraft에는 `/give` 명령어처럼 많은 경우에서 사용되는 강력한 명령어 제안 체계가 잡혀 있습니다. 이 체계는 플레이어에게 명령어 인수 값을 제안하고, 유저가 제안된 값을 선택할 수 있게 해줍니다. 이는 명령어를 더 유저 친화적이며 사용하기 편리하게 만드는 데에 가장 좋은 방법입니다. + +## 제안 공급자 {#suggestion-providers} + +`SuggestionProvider`는 클라이언트에 전송될 제안 리스트를 만드는 데 사용됩니다. 이는 `CommandContext`와 `SuggestionBuilder`를 인수로 받고 `Suggestions`를 반환하는 기능형 인터페이스 입니다. `SuggestionProvider`는 `CompletableFuture`를 반환해 인수가 항상 바로 사용 가능한 것은 아닙니다. + +## 제안 공급자 사용하기 {#using-suggestion-providers} + +제안 공급자를 사용하려면, 인수 빌더의 `suggests` 메서드를 호출해야 합니다. 이 메서드는 `SuggestionProvider`를 인수로 받고 제안 공급자가 덧붙여진 새로운 인수 빌더를 반환합니다. + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 내장된 제안 공급자 {#built-in-suggestion-providers} + +시스템에 내장되어 있는 몇 가지 제안 공급자도 있습니다. + +| 제안 공급자 | 설명 | +| ----------------------------------------- | -------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | 생성 가능한 모든 엔티티를 제안합니다. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | 재생 가능한 모든 소리를 제안합니다. | +| `LootCommand.SUGGESTION_PROVIDER` | 가능한 모든 전리품 테이블을 제안합니다. | +| `SuggestionProviders.ALL_BIOMES` | 가능한 모든 생물 군계를 제안합니다. | + +## 직접 제안 공급자 만들기 {#creating-a-custom-suggestion-provider} + +내장된 제안 공급자에 필요로 하는 것이 없다면, 직접 자신만의 제안 공급자를 만들 수도 있습니다. 이렇게 하려면, 먼저 `SuggestionProvider` 인터페이스를 구현(Implement)하는 클래스를 만들고, `getSuggestion` 메서드를 덮어써야(Override) 합니다. + +예를 들어, 서버의 모든 플레이어 이름을 제안하는 제안 공급자를 만들어 보겠습니다. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +이 제안 공급자를 사용하려면, 그냥 간단하게 인수 빌더의 `.suggests` 메서드에 만든 인스턴스를 전달하기만 하면 됩니다. + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +물론, 제안 공급자는 (이미 제공된 인수처럼) 명령어 컨텍스트를 읽어 명령어의 상태에 따라 제안을 변경할 수 있기 때문에, 제안 공급자가 더 복잡해질 수 있습니다. + +플레이어의 인벤토리의 아이템을 제안하거나, 플레이어 근처에 있는 엔티티를 제안할 수도 있습니다. diff --git a/versions/1.21/translated/ko_kr/develop/entities/damage-types.md b/versions/1.21/translated/ko_kr/develop/entities/damage-types.md new file mode 100644 index 000000000..d9ab68559 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/entities/damage-types.md @@ -0,0 +1,96 @@ +--- +title: 피해 유형 +description: 사용자 정의 피해 유형을 추가하는 방법을 알아보세요. +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# 피해 유형 {#damage-types} + +피해 유형은 엔티티가 입을 수 있는 피해(대미지)의 종류를 의미합니다. Minecraft 1.19.4 부터, 새로운 피해 유형의 추가는 데이터 기반이 되어, JSON 파일을 통해 생성됩니다. + +## 피해 유형 추가하기 {#creating-a-damage-type} + +_Tater_ 라는 이름의 사용자 정의 피해 유형을 추가해 봅시다. 이는 피해 유형의 JSON 파일을 생성하며 시작됩니다. 이 파일은 모드 리소스의 `data` 디렉토리의 `damage_type` 폴더에 저장됩니다. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +파일은 다음과 같은 구조를 가집니다. + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +이 사용자 정의 피해 유형을 플레이어가 살아있는 엔티티가 아닌 것에서 피해를 입었을 때 [허기 피로](https://minecraft.wiki/w/Hunger#Exhaustion_level_increase)를 0.1만큼 올리도록 만들어 봅시다. 참고로, 피해 크기는 세계의 난이도에 비례합니다. + +::: info + +JSON 파일 구조에 대한 자세한 내용은 [Minecraft 위키 (영문)](https://minecraft.wiki/w/Damage_type#JSON_format) 를 참고하십시오. + +::: + +### 코드를 통해 피해 유형에 접근하기 {#accessing-damage-types-through-code} + +코드를 통해 추가한 사용자 정의 피해 유형에 접근하고 싶다면, `DamageSource` 인스턴스를 생성하기 위해 `RegistryKey`에 접근해야 합니다. + +`RegistryKey` 는 다음 코드로 불러올 수 있습니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### 피해 유형 사용하기 {#using-damage-types} + +피해 유형 사용의 예시를 만들어 보기 위해, 먼저 사용자 정의 블록 _Tater Block_을 추가해보겠습니다. _Tater Block_은 살아있는 엔티티가 밟으면 _Tater_ 피해를 입힙니다. + +피해를 주기 위해 먼저 `onSteppedOn` 메서드를 덮어(Override) 쓰겠습니다. + +사용자 정의 피해 유형의 `DamageSource`를 생성하며 시작합니다. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +그리고, `entity.damage()` 메서드에 `DamageSource`와 피해 크기를 입력하여 호출합니다. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +블록의 코드 전문은 다음과 같습니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +이제 살아있는 엔티티가 블록 위에 서면, 사용자 정의 피해 유형으로 크기 5 (2.5 하트) 의 피해를 입게 됩니다. + +### 사용자 정의 사망 메시지 {#custom-death-message} + +`en_us.json` 파일의 `death.attack.` 키를 수정해 사용자 정의 피해 유형의 사망 메시지를 수정할 수 있습니다. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +이제 사용자 정의 피해 유형으로 사망하면, 다음 사망 메시지를 보게 될 것입니다. + +![플레이어 인벤토리에서 보여지는 효과](/assets/develop/tater-damage-death.png) + +### 피해 유형 태그 {#damage-type-tags} + +일부 피해 유형은 갑옷, 상태 효과 등을 무시할 수 있습니다. 태그는 이러한 피해 유형의 속성을 제어하는 데 사용됩니다. + +피해 유형 태그는 `data/minecraft/tags/damage_type` 에 저장됩니다. + +::: info + +내장된 피해 유형 태그와 설명은 [Minecraft 위키 (영문)](https://minecraft.wiki/w/Tag#Damage_types) 를 참고하세요. + +::: + +Tater 피해 유형을 `bypasses_armor` 피해 유형 태그에 추가해 봅시다. + +이러한 태그에 사용자 정의 피해 유형을 추가하려면, 먼저 `minecraft` 네임스페이스로 JSON 파일을 생성해야 합니다. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +파일은 다음과 같은 구조를 가집니다. + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +`replace` 키를 `false` 로 설정하여 기존 태그의 값을 제거하지 않도록 주의하세요. diff --git a/versions/1.21/translated/ko_kr/develop/entities/effects.md b/versions/1.21/translated/ko_kr/develop/entities/effects.md new file mode 100644 index 000000000..dfa891ade --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/entities/effects.md @@ -0,0 +1,65 @@ +--- +title: 상태 효과 +description: 사용자 정의 상태 효과를 만드는 방법을 알아보세요. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil +authors-nogithub: + - siglong + - tao0lu +--- + +# 상태 효과 + +이펙트, 효과로도 알려진 상태 효과는 엔티티에게 영향을 줄 수 있는 조건을 의미합니다. 이는 자연적으로 좋거나, 나쁘거나, 중립적일 수 있습니다. 기본 게임은 이러한 효과를 음식, 물약 등 다양한 방법으로 적용합니다. + +`/effect` 명령어를 통해 엔티티에게 효과를 부여할 수도 있습니다. + +## 사용자 정의 상태 효과 {#custom-status-effects} + +이 튜토리얼에서는, 매 틱마다 플레이어에게 경험 포인트를 주는 새로운 사용자 정의 효과 _Tater_ 를 만들어 보겠습니다. + +### `StatusEffect` 확장 {#extend-statuseffect} + +모든 효과의 기본이 되는 `StatusEffect` 클래스의 사용자 정의 확장 클래스를 만들어 봅시다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### 사용자 정의 효과 등록하기 {#registering-your-custom-effect} + +블록, 아이템 등록처럼, `Registry.register`를 통해 `STATUS_EFFECT` 레지스트리에 사용자 정의 효과를 등록할 수 있습니다. 이는 모드 초기화 단계에서 완료되어야 합니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### 텍스쳐 {#texture} + +상태 효과의 아이콘은 18x18의 PNG 입니다. 사용자 정의 아이콘을 다음 폴더에 넣어 적용할 수 있습니다: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + + + +### 번역 {#translations} + +다른 현지화처럼, 간단히 언어 파일에 `"effect..": "값"` 포맷의 엔트리 ID를 추가하기만 하면 됩니다. + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### 테스트 {#testing} + +`/effect give @s fabric-docs-reference:tater` 명령어를 사용해 직접 Tater 효과를 부여해 보세요. +`/effect clear`로 효과를 제거할 수 있습니다. + +:::info +::: info +사용자 정의 효과를 부여하는 물약을 만드는 방법은 [물약](../items/potions) 가이드를 참조하세요. +::: diff --git a/versions/1.21/translated/ko_kr/develop/getting-started/creating-a-project.md b/versions/1.21/translated/ko_kr/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..a59b26fc5 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/getting-started/creating-a-project.md @@ -0,0 +1,71 @@ +--- +title: 프로젝트 만들기 +description: Fabric 템플릿 모드 생성기로 새 모드를 생성하는 방법에 대한 단계별 가이드입니다. +authors: + - IMB11 + - Cactooz +--- + +# 프로젝트 만들기 {#creating-a-project} + +페브릭에는 템플릿 생성기를 사용하여 새 모드를 생성하는 쉬운 방법이 있습니다. 원하는 경우 예제 모드 저장소를 사용하여 수동으로 새 프로젝트를 생성할 수 있습니다. [수동으로 프로젝트 생성](#manual-project -creation). + +## 프로젝트 생성하기 {#generating-a-project} + +[Fabric 템플릿 모드 생성기](https://fabricmc.net/develop/template/)로 새 프로젝트를 생성할 수 있습니다. 모드 이름, 패키지 이름, 그리고 개발하려면 Minecraft 버전 등의 필수 항목을 입력해야 합니다. + +패키지의 이름은 소문자여야 하며, 점으로 분류되고, 다른 프로그래머의 패키지와의 충돌을 피하기 위해 고유해야 합니다. 주로, `com.example.modid`같은 형식의 역순 인터넷 도메인으로 지정됩니다. + +![생성기 미리보기](/assets/develop/getting-started/template-generator.png) + +만약 Kotlin을 사용하고 싶으면, Yarn 맵핑 보다는 Mojang의 공식 맵핑을 사용하거나, 데이터 생성기를 추가하고 싶은 경우, `고급 옵션`에서 적절한 옵션을 선택할 수 있습니다. + +![고급 옵션 섹션](/assets/develop/getting-started/template-generator-advanced.png) + +필수 필드를 입력한 후 '생성' 버튼을 클릭하면 zip 파일 형식으로 새 프로젝트를 다운받을 수 있습니다. + +압축파일을 원하는 위치에 푼다음 IntelliJ에서 열어줍니다. + +![프로젝트 열기 스크린샷](/assets/develop/getting-started/open-project.png) + +## 프로젝트 가져오기 {#importing-the-project} + +IntelliJ IDEA에서 프로젝트를 열면, IDE가 자동으로 Gradle의 구성 요소를 불러온 다음 필요한 작업을 수행할 것입니다. + +Gradle 빌드 알림을 받으면 `Import Gradle Project` 버튼을 눌러야 합니다. + +![Gradle 확인 스크린샷](/assets/develop/getting-started/gradle-prompt.png) + +여기까지 하셨다면 프로젝트 탐색기에 프로젝트 파일이 뜨고 이제 모드 개발을 시작할 수 있습니다. + +## 직접 프로젝트 생성 {#manual-project-creation} + +:::warning +리포지토리를 복사하려면 [Git](https://git-scm.com/)이 설치되어 있어야 합니다. +::: + +Fabric 템플릿 모드 생성기를 사용할 수 없는 경우 다음 단계에 따라 프로젝트를 수동으로 생성할 수 있습니다. + +먼저 Git을 이용해 리포지토리를 복사해 줍니다. + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/my-mod-project +``` + +명령어를 실행하면 my-mod-project라는 새 폴더에 복사됩니다. + +새로 생성된 폴더에서 `.git` 폴더를 삭제후 Intellij에서 열어줍니다. 만약 파일 탐색에서 `.git` 폴더가 안보인다면 파일 탐색기 설정에서 숨긴 항목 표시를 켜줍니다. + +IntelliJ에서 프로젝트를 열면 에디터가 자동으로 필요한 작업을 실행합니다. + +앞에서 말한 것처럼 Gradle 빌드 알림을 받으면 `Import Gradle Project` 버튼을 눌러줍니다. + +### 템플릿 수정하기 {#modifying-the-template} + +프로젝트를 가져온 후에는 모드 세부정보를 수정해야 합니다. + +- 프로젝트의 `gradle.properties` 파일을 수정해 `maven_group` 및 `archive_base_name` 속성을 모드와 일치하도록 변경하세요. +- `fabric.mod.json` 파일을 수정하여 `id`, `name` 및 `description` 속성을 모드와 일치하도록 변경하세요. +- 대상으로 삼으려는 버전과 일치하게 을(를) 통해 쿼리할 수 있는 Minecraft의 버전과 맵핑, 로더와 Loom 버전을 업데이트 해주세요. + +모드와 패키지 이름이 일치하도록 패키지 이름과 모드의 메인 클래스 이름을 변경할 수 있습니다. diff --git a/versions/1.21/translated/ko_kr/develop/index.md b/versions/1.21/translated/ko_kr/develop/index.md new file mode 100644 index 000000000..78b99bd0c --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/index.md @@ -0,0 +1,12 @@ +--- +title: 개발자 가이드 +description: "커뮤니티에서 작성한 엄선된 개발자 가이드는 개발 환경 설정부터 렌더링 및 네트워킹과 같은 고급 주제까지 광범위한 주제를 다루고 있습니다. " +--- + +# 개발자 가이드 + +커뮤니티에서 작성한 엄선된 개발자 가이드는 개발 환경 설정부터 렌더링 및 네트워킹과 같은 고급 주제까지 광범위한 주제를 다루고 있습니다. + +사이드바에서 전체 개발자 가이드 문서를 둘러보십시오. 무언가 찾고 있다면, 우측 상단의 검색 바를 통해 원하는 페이지를 찾을 수 있습니다. + +Fabric 문서에 기여하고 싶다면, [GitHub](https://github.com/FabricMC/fabric-docs)에서 원본 코드를 볼 수 있으며, 기여시에는 [기여 가이드라인](../contributing)을 준수하시기 바랍니다. diff --git a/versions/1.21/translated/ko_kr/develop/items/food.md b/versions/1.21/translated/ko_kr/develop/items/food.md new file mode 100644 index 000000000..dcaff6789 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/items/food.md @@ -0,0 +1,52 @@ +--- +title: 음식 아이템 +description: 아이템을 먹을 수 있고, 설정할 수 있게 하기 위해 아이템에 FoodComponent를 추가하는 방법을 알아보세요. +authors: + - IMB11 +--- + +# 음식 아이템 {#food-items} + +음식은 Minecraft에서 생존하는 데 주요한 면입니다. 그래서 먹을 수 있는 아이템을 만들 때, 다른 먹을 수 있는 아이템과의 용도를 고려해야 합니다. + +만약, 모드를 사용해 사기적인 아이템을 만들 것이 아니라면, 다음을 고려해야 합니다: + +- 먹을 아이템이 얼마나 많은 배고픔 수치를 추가하거나 뺄 것인가 +- 어떤 물약 효과를 부여할 것인가 +- 게임 초반에 얻을 수 있는가 아니면 후반에 얻을 수 있는가 + +## 음식 요소 추가하기 {#adding-the-food-component} + +음식 요소를 추가하기 위해, `Item.Settings` 인스턴스에 전달할 수 있습니다: + +```java +new Item.Settings().food(new FoodComponent.Builder().build()) +``` + +지금은, 이 아이템을 그저 먹을 수만 있게 합니다. + +`FoodComponent.Builder` 클래스는 플레이어가 음식을 먹을 때 무슨 일이 일어나는지 조정할 수 있게 해주는 많은 메서드를 가지고 있습니다. + +| 메서드 | 설명 | +| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `nutrition` | 아이템이 채울 배고픔의 양을 정합니다. | +| `saturationModifier` | 아이템이 추가할 포만감의 양을 정합니다. | +| `alwaysEdible` | 배고픔의 양에 상관없이 항상 먹을 수 있게 합니다. | +| `snack` | 아이템을 간식으로서 정하게 합니다. | +| `statusEffect` | 아이템을 먹을 때 상태 효과를 추가합니다. 일반적으로 상태 효과 인스턴스와 확률이 이 메서드에 전달됩니다. 여기서, 확률은 백분율 (`1f = 100%`) 입니다. | + +원하는 대로 빌더를 수정한 후, `FoodComponent`를 가지기 위해 `build()` 메서드를 호출할 수 있습니다. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +[Creating Your First Item](./first-item) 페이지의 예시와 비슷하게 위의 구성 요소를 사용하겠습니다: + +@[code transcludeWith=:::poisonous_apple](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +이렇게 하면 아이템이 다음과 같이 됩니다: + +- 배고픔의 양에 상관없이 항상 먹을 수 있습니다. +- "간식"입니다. +- 항상 먹을 때마다 독 II를 6초 부여합니다. + + diff --git a/versions/1.21/translated/ko_kr/develop/items/potions.md b/versions/1.21/translated/ko_kr/develop/items/potions.md new file mode 100644 index 000000000..80d691cb7 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/items/potions.md @@ -0,0 +1,49 @@ +--- +title: 물약 +description: 여러 상태 효과를 부여하는 사용자 정의 물약을 만드는 방법을 알아보세요. +authors: + - dicedpixels + - PandoricaVi + - Drakonkinst + - JaaiDead +--- + +# 물약 {#potions} + +물약은 엔티티에게 효과를 주는 소모품입니다. 플레이어는 양조대에서 물약을 제조하거나 여러 게임 메커니즘을 통해 아이템을 얻을 수 있습니다. + +## 사용자 정의 물약 {#custom-potions} + +아이템과 블록들처럼, 물약도 등록이 필요합니다. + +### 물약 만들기 {#creating-the-potion} + +`Potion` 인스턴스를 저장할 필드를 만들며 시작해 봅시다. 이를 보관하기 위해 `ModInitializer` 구현 클래스를 직접 사용하겠습니다. + +@[code lang=java transclude={18-27}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +`StatusEffectInstance` 인스턴스에는 세 가지 매개 변수를 입력해야 합니다. + +- `RegistryEntry type` - 효과. 여기에선 사용자 정의 효과를 사용해볼 것입니다. 대신, 바닐라의 `StatusEffects` 클래스를 통해 바닐라 효과에 접근할 수도 있습니다. +- `int duration` - 효과의 지속 시간(틱). +- `int amplifier` - 효과의 세기. 예를 들어, 성급함 II는 1을 세기로 가지게 됩니다. + +:::info +사용자 정의 물약 효과를 만드려면, [상태 효과](../entities/effects) 가이드를 참조하세요. +::: + +### 물약 등록하기 {#registering-the-potion} + +이니셜라이저에서 `BrewingRecipeRegistry.registerPotionRecipe` 메서드를 사용해 물약 효과를 등록하기 위해 `FabricBrewingRecipeRegistryBuilder.BUILD` 이벤트를 사용할 것입니다. + +@[code lang=java transclude={29-42}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +`registerPotionRecipe`는 세 가지 매개변수를 가집니다. + +- `RegistryEntry input` - 시작 물약의 레지스트리 항목. 일반적으로 물병 또는 어색한 물약이 사용됩니다. +- `Item item` - 물약의 기본 재료가 될 아이템. +- `RegistryEntry output` - 결과 물약의 레지스트리 항목. + +등록을 완료했다면, 이제 감자를 통해 Tater 물약을 만들 수 있습니다. + +![플레이어 인벤토리에서 보여지는 효과](/assets/develop/tater-potion.png) diff --git a/versions/1.21/translated/ko_kr/develop/rendering/basic-concepts.md b/versions/1.21/translated/ko_kr/develop/rendering/basic-concepts.md new file mode 100644 index 000000000..ab7d3de56 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/rendering/basic-concepts.md @@ -0,0 +1,162 @@ +--- +title: 기본 렌더링 개념 +description: Minecraft의 렌더링 엔진에 사용되는 기본적인 렌더링의 개념을 알아보세요. +authors: + - IMB11 + - "0x3C50" +--- + +# 기본 렌더링 개념 {#basic-rendering-concepts} + +::: warning +Although Minecraft is built using OpenGL, as of version 1.17+ you cannot use legacy OpenGL methods to render your own things. Instead, you must use the new `BufferBuilder` system, which formats rendering data and uploads it to OpenGL to draw. + +간단히 요약하자면, Minecraft의 렌더링 시스템을 사용하거나, `GL.glDrawElements()`를 활용하는 자체 렌더링 시스템을 구축하여야 합니다. +::: + +이 튜토리얼에서는 새로운 렌더링 시스템을 만들며 렌더링의 기본 사항과 주요 용어, 개념에 대해 알아볼 것입니다. + +Minecraft에서 렌더링은 여러 `DrawContext` 메서드를 통하여 추상화 되어있어, 이 튜토리얼에 언급된 대로 하지 않아도 되지만, 그래도 렌더링의 기본 개념을 이해할 필요는 있습니다. + +## `Tessellator` {#the-tessellator} + +`Tessellator`는 Minecraft에서 렌더링에 사용하는 기본(Main) 클래스입니다. 이는 싱글톤이므로, 게임에 오직 하나의 인스턴스만 존재할 수 있습니다. `Tessellator.getInstance()`를 사용하여 인스턴스를 불러올 수 있습니다. + +## `BufferBuilder` + +`BufferBuilder`는 OpenGL에 렌더링 데이터의 형식을 지정하고 업로드하는 클래스입니다. 이는 화면에 게임을 그리기 위하여 OpenGL에 업로드되는 Buffer를 생성합니다. + +`Tessellator`는 렌더링 데이터의 형식을 지정하고 업로드를 하는 데 쓰이는 `BufferBuilder`를 생성하기 위하여 사용됩니다. + +### `BufferBuilder` 초기화 하기 + +`BufferBuilder`에 무엇이든 쓰기 전에, 먼저 초기화해야 합니다. 이는 `VertexFormat` 및 그리기 모드를 사용하고 `BufferBuilder`를 반환하는 `Tessellator#begin(...)` 메서드를 사용하여 할 수 있습니다. + +#### 꼭짓점 포맷 {#vertex-formats} + +`VertexFormat`은 데이터 버퍼에 포함할 요소를 정의하고 어떻게 물체가 OpenGL에서 처리되어야 하는지에 대한 개요를 만듭니다. + +`VertexFormat`에는 다음과 같은 요소가 있습니다. + +| 요소 | 포맷 | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | +| `BLIT_SCREEN` | `{ position (3 floats: x, y and z), uv (2 floats), color (4 ubytes) }` | +| `POSITION_COLOR_TEXTURE_LIGHT_NORMAL` | `{ position, color, texture uv, texture light (2 shorts), texture normal (3 sbytes) }` | +| `POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL` | `{ position, color, texture uv, overlay (2 shorts), texture light, normal (3 sbytes) }` | +| `POSITION_TEXTURE_COLOR_LIGHT` | `{ position, texture uv, color, texture light }` | +| `POSITION` | `{ position }` | +| `POSITION_COLOR` | `{ position, color }` | +| `LINES` | `{ position, color, normal }` | +| `POSITION_COLOR_LIGHT` | `{ position, color, light }` | +| `POSITION_TEXTURE` | `{ position, uv }` | +| `POSITION_COLOR_TEXTURE` | `{ position, color, uv }` | +| `POSITION_TEXTURE_COLOR` | `{ position, uv, color }` | +| `POSITION_COLOR_TEXTURE_LIGHT` | `{ position, color, uv, light }` | +| `POSITION_TEXTURE_LIGHT_COLOR` | `{ position, uv, light, color }` | +| `POSITION_TEXTURE_COLOR_NORMAL` | `{ position, uv, color, normal }` | + +#### 그리기 모드 + +그리기 모드는 데이터가 그려지는 방법을 결정합니다. 다음과 같은 그리기 모드를 사용할 수 있습니다: + +| 그리기 모드 | 설명 | +| --------------------------- | -------------------------------------------------------------------------------------------------------------- | +| `DrawMode.LINES` | 각 요소는 2개의 꼭짓점으로 구성되며 단일 선으로 표시됩니다. | +| `DrawMode.LINE_STRIP` | 첫 번째 선만 2개의 꼭짓점을 가집니다. 이후 꼭짓점은 기존에 있던 꼭짓점과 연결되어, 연속적인 줄을 만듭니다. | +| `DrawMode.DEBUG_LINES` | `DrawMode.LINES`와 비슷하지만, 항상 선이 화면에서 1px 너비로 표시됩니다. | +| `DrawMode.DEBUG_LINE_STRIP` | `DrawMode.LINE_STRIP`과 같지만, 항상 선이 화면에 1px 너비로 표시됩니다. | +| `DrawMode.TRIANGLES` | 각 요소가 3개의 꼭짓점으로 만들어져, 삼각형이 구성합니다. | +| `DrawMode.TRIANGLE_STRIP` | 첫 삼각형만 세 개의 꼭짓점을 가집니다. 이후 추가된 꼭짓점은 기존에 있던 두 꼭짓점으로 새 삼각형을 구성하게 됩니다. | +| `DrawMode.TRIANGLE_FAN` | 첫 삼각형만 세 개의 꼭짓점을 가집니다. 이후 추가된 꼭지점은 기존에 있던 첫 번째 꼭지점과 마지막 꼭지점으로 새 삼각형을 구성하게 됩니다. | +| `DrawMode.QUADS` | 각 요소가 4개의 꼭짓점으로 만들어져, 사각형을 구성합니다. | + +### `BufferBuilder` 쓰기 + +`BufferBuilder`가 초기화 되면, 이제 데이터를 쓸 수 있습니다. + +`BufferBuilder`로 버퍼를 만들거나, 꼭짓점끼리 서로 연결할 수 있습니다. 꼭짓점을 추가하려면, `buffer.vertex(matrix, float, float, float)` 메서드를 사용합니다. `matrix` 매개변수는 변환 행렬로, 아래에서 더 자세하게 설명할 예정입니다. 세 float 매개변수는 꼭짓점의 (x, y, z) 좌표를 의미합니다. + +사용하면 꼭짓점에 추가적인 정보를 추가할 수 있게 꼭짓점 빌더가 반환됩니다. 정보를 추가할 때 추가한 `VertexFormat` 순서를 따르는 것이 중요합니다. 그렇지 않으면 OpenGL이 데이터를 제대로 해석하지 못할 수 있습니다. 꼭짓점 빌딩을 끝마친 후, 끝나기 전까지 버퍼에 데이터를 추가하거나 계속해서 꼭짓점을 더 추가하세요. + +컬링의 개념을 이해하는 것도 가치 있는 일입니다. 컬링은 플레이어의 시야에서 보이지 않는 3차원 면을 제거하는 기법입니다. 만약 면의 꼭지점이 잘못된 순서로 배열되어 있으면, 컬링으로 인해 면이 정상적으로 렌더링되지 않을 수 있습니다. + +#### 변환 행렬이 무엇인가요? {#what-is-a-transformation-matrix} + +변환 행렬은 벡터를 변환하기 위하여 사용되는 4x4 행렬입니다. Minecraft에서는, 변환 행렬은 꼭지점 생성에서 입력된 좌표를 변환하는 게 끝입니다. 변환을 통해 꼭지점의 크기를 키우거나, 움직이거나, 회전할 수 있습니다. + +때로는 위치 행렬 또는 모델 행렬이라고도 합니다. + +일반적으로 `DrawContext`의 `MatrixStack` 클래스를 통하여 가져올 수 있습니다. + +```java +drawContext.getMatrices().peek().getPositionMatrix(); +``` + +#### 실전 예시: 삼각형 스트립 렌더링하기 + +현실적인 예시로 `BufferBuilder`를 쓰는 방법을 설명하는 것이 더 쉽습니다. `DrawMode.TRIANGLE_STRIP` 그리기 모드와 `POSITION_COLOR` 꼭지점 포맷으로 무언가를 렌더링하고 싶다고 가정해봅시다. + +순서대로 HUD에 꼭짓점을 그려봅시다. + +```txt +(20, 20) +(5, 40) +(35, 40) +(20, 60) +``` + +`TRIANGLE_STRIP` 그리기 모드를 사용했으므로, 꼭짓점을 그리면 다음과 같은 과정을 거쳐 사랑스러운 다이아몬드가 렌더링될 것입니다. + +![두 개의 삼각형을 형성하기 위하여 화면에 꼭짓점의 위치를 표시하는 네 단계](/assets/develop/rendering/concepts-practical-example-draw-process.png) + +이 튜토리얼에서는 HUD에 그리고 있으므로, `HudRenderCallback` 이벤트를 사용하겠습니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +이렇게 하면 HUD에 두 삼각형이 그려지게 됩니다. + +![최종 결과](/assets/develop/rendering/concepts-practical-example-final-result.png) + +:::tip +색을 지정하거나 꼭짓점의 위치를 옮겨 어떤 변화가 일어나는지 알아보세요! 다른 그리기 모드와 꼭짓점 포맷을 사용해 볼 수도 있습니다. +::: + +## `MatrixStack` + +어떻게 `BufferBuilder`를 쓰는지 알았다면, 이제 어떻게 모델을 움직이고, 좀 더 멋진 분들은 어떻게 애니메이션을 적용할지 궁금할 수도 있습니다. 이제 `MatrixStack` 클래스가 나설 때입니다. + +`MatrixStack` 클래스에는 다음 메서드가 포함되어 있습니다. + +- `push()` - 새 행렬을 스택으로 (밀어) 넣습니다. +- `pop()` - 스택의 최상단 행렬을 소거합니다. +- `peek()` - 스택의 최상단 행렬을 반환합니다. +- `translate(x, y, z)` - 최상단 스택을 이동합니다. +- `scale(x, y, z)` - 최상단 스택의 크기를 조절합니다. + +다음 섹션에서 알아볼 쿼터니언을 통해 최상단 행렬을 곱할 수도 있습니다. + +위 예시에서는, `MatrixStack`과 `tickDelta` (프레임이 변경될 때 소요된 시간) 를 통해 다이아몬드의 크기를 조절할 수 있습니다. + +::: warning +You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. + +행렬을 변환하기 전에 행렬 스택을 넣었는지 확인하세요! +::: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +![다이아몬드의 크기가 변화하는 모습을 보여주는 영상](/assets/develop/rendering/concepts-matrix-stack.webp) + +## 쿼터니언 (움직이는 것) {#quaternions-rotating-things} + +쿼터니언은 3차원에서 회전을 표현하는 방법입니다. 이는 `MatrixStack`의 최상단 행렬을 `multiply(Quaternion, x, y, z)` 메소드를 통해 회전할 때 사용됩니다. + +Minecraft가 `RotationAxis` 도구 클래스에 여러 쿼터니언 인스턴스를 먼저 생성해 두었기 때문에 쿼터니언 클래스를 바로 사용할 필요는 없습니다. + +그럼 다이아몬드의 Z축을 회전해 봅시다. `MatrixStack`과 `multiply(Quaternion, x, y, z)` 메소드를 통해 회전할 수 있습니다. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +결과는 다음과 같습니다. + +![다이아몬드의 Z축이 변화하는 모습을 보여주는 영상](/assets/develop/rendering/concepts-quaternions.webp) diff --git a/versions/1.21/translated/ko_kr/develop/rendering/gui/custom-screens.md b/versions/1.21/translated/ko_kr/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..8deb19751 --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/rendering/gui/custom-screens.md @@ -0,0 +1,64 @@ +--- +title: 사용자 정의 화면 +description: 모드의 사용자 정의 화면을 만드는 방법을 알아보세요. +authors: + - IMB11 +--- + +# 사용자 정의 화면 + +:::info +본 튜토리얼은 서버에서 처리되는 화면이 아닌 클라이언트에서 표시되는 일반 화면 에 대한 튜토리얼입니다. +::: + +화면은 일반적으로 타이틀 화면, 일시 정지 화면 등과 같이 플레이어가 상호 작용하는 GUI를 의미합니다. + +이러한 화면은 사용자 정의 정보, 사용자 정의 설정 메뉴 등을 표시하기 위해 직접 만들 수 있습니다. + +## 화면 만들기 + +화면을 만드려면, 먼저 `Screen` 클래스를 확장하는(Extend) 클래스를 만들고, `init` 메소드를 덮어 써야(Override) 합니다. + +사용자 정의 화면을 제작할 때 다음 사항에 유의해야 합니다. + +- 생성자 메소드에서 화면이 초기화되지 않기 때문에 위젯또한 생성되지 않습니다. +- `init` 메소드는 화면이 초기화되었을 때 호출되므로, 위젯을 만들기에 가장 좋은 위치입니다. + - 모든 그려질 수 있는 위젯이 입력되는 `addDrawableChild` 메소드를 통해 위젯을 추가합니다. +- `render` 메소드는 매 프레임마다 호출되므로, 메소드를 통해 그려지는 컨텍스트, 마우스 포인터의 위치에 접근할 수 있습니다. + +예를 들어, 라벨이 위에 있는 버튼이 있는 간단한 화면을 만들어 보겠습니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![사용자 정의 화면 1](/assets/develop/rendering/gui/custom-1-example.png) + +## 화면 열기 + +화면은 `MinecraftClient`의 `setScreen` 메소드를 통해 열 수 있습니다. + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## 화면 닫기 + +만약 화면을 닫고 싶다면, `setScreen` 메소드를 통해 간단하게 화면을 `null` 로 설정하면 됩니다. + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +만약 디테일하게 이전 화면으로 되돌아가는 기능을 추가하고 싶다면, 현재 화면을 `CustomScreen` 생성자에 입력하여 필드에 저장하고, `close` 메소드가 호출되었을 때 해당 필드를 사용하여 이전 화면으로 되돌아가면 됩니다. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +이제, 사용자 정의 화면이 열릴 때, 현재 화면을 두 번째 매개변수에 입력하면, `CustomScreen#close`가 호출되었을 때 이전 화면으로 되돌아갈 것입니다. + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/translated/ko_kr/develop/rendering/gui/custom-widgets.md b/versions/1.21/translated/ko_kr/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..63301debd --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,39 @@ +--- +title: 사용자 정의 위젯 +description: 화면에 사용될 사용자 정의 위젯을 만드는 방법을 알아보세요. +authors: + - IMB11 +--- + +# 사용자 정의 위젯 + +위젯은 일반적으로 화면에 추가되는 렌더링 컴포넌트의 컨테이너로, 키 입력, 마우스 클릭 등의 여러 이벤트를 통해 플레이어와 상호작용할 수 있습니다. + +## 위젯 만들기 {#creating-a-widget} + +`ClickableWidget`을 확장(Extend)하는 등 위젯 클래스를 만드는 방법은 여러 가지가 있습니다. `ClickableWidget` 클래스는 `Drawable`, `Element`, `Narratable`, `Selectable` 인터페이스를 확장해 높이, 너비, 위치, 이벤트 처리 등 여러 유용한 도구를 제공합니다. + +- `Drawable` - 렌더링 - `addDrawableChild` 메소드를 통해 화면에 위젯을 등록하려면 필수적인 인터페이스입니다. +- `Element` - 이벤트 - 마우스 클릭, 키 입력 등과 같은 이벤트를 처리하려면 필수적입니다. +- `Narratable` - 접근성 - 스크린 리더 등 여러 접근성 도구가 사용자 정의 위젯에 접근하려면 필수적입니다. +- `Selectable` - 탭 선택 - 위젯이 키를 통해 선택 가능하게 하려면 필수적입니다. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## 화면에 위젯 추가하기 + +다른 위젯와 같이, 위젯을 화면에 추가하려면 `Screen` 클래스에서 제공되는 `addDrawableChild` 메소드를 사용해야 합니다. 이러한 작업은 `init` 메소드에서 수행되어야 합니다. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![화면에 표시되는 사용자 정의 위젯](/assets/develop/rendering/gui/custom-widget-example.png) + +## 위젯 이벤트 + +`onMouseClicked`, `onMouseReleased`, `onKeyPressed` 등의 메소드를 덮어 쓰기(Override) 하여 마우스 클릭, 키 입력 등과 같은 이벤트를 처리할 수 있습니다. + +예를 들어, `ClickableWidget` 클래스에서 제공되는 `isHovered()` 메소드를 통해 마우스가 호버되면 위젯 색이 변경되도록 해보겠습니다. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![호버 이벤트 예시](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/translated/ko_kr/develop/rendering/particles/creating-particles.md b/versions/1.21/translated/ko_kr/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..1ff112a8e --- /dev/null +++ b/versions/1.21/translated/ko_kr/develop/rendering/particles/creating-particles.md @@ -0,0 +1,72 @@ +--- +title: 사용자 정의 입자 만들기 +description: Fabric API를 통해 사용자 정의 입자를 만드는 방법을 알아보세요. +authors: + - Superkat32 +--- + +# 사용자 정의 입자 만들기 + +입자는 강력한 도구입니다. 아름다운 장면에 분위기를 더할 수도 있고, 보스와의 전투에 긴장감을 더할 수도 있습니다. 그럼 직접 한번 만들어 봅시다! + +## 사용자 정의 입자 등록하기 + +이 튜토리얼에서는 엔드 막대기 입자처럼 움직이는 새로운 스파클 입자를 추가해 볼 예정입니다. + +먼저, 모드 초기화 클래스에 모드 ID로 `ParticleType` 을 등록해 봅시다. + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +소문자로 "sparkle_particle"은 이후 입자의 텍스쳐를 위한 JSON 파일의 이름이 되게 됩니다. 곧 JSON 파일을 어떻게 생성하는지 알아볼 것입니다. + +## 클라이언트측에서 등록하기 + +`ModInitializer` 엔트리포인트에 입자를 등록했다면, `ClientModInitializer`의 엔트리포인트에도 입자를 등록해야 합니다. + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +위 예시는 입자를 클라이언트측에 등록하는 방법입니다. 이제 엔드 막대기 입자 팩토리를 통해 입자에 움직임을 줘보겠습니다. 이렇게 하면 입자가 엔드 막대기 입자와 똑같이 움직이게 됩니다. + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- IntelliJ 단축 키: Ctrl+Alt+B +- VSCode 단축 키: Ctrl+F12 + ::: + +## JSON 파일을 만들고 텍스쳐 추가하기 + +먼저, 모드 소스의 `resources/assets//` 폴더에 두 가지 새로운 폴더를 생성해야 합니다. + +| 폴더 경로 | 설명 | +| -------------------- | --------------------------------------------------------------- | +| `/textures/particle` | `/textures/particle` 폴더는 입자의 모든 텍스쳐를 담습니다. | +| `/particles` | `particles` 폴더는 입자의 정보에 대한 모든 JSON 파일을 담고 있습니다. | + +예를 들어, `textures/particle` 폴더에는 "sparkle_particle_texture.png" 라는 이름의 텍스쳐 이미지를 넣겠습니다. + +그리고, `particles` 폴더에는 ParticleType에 등록한 것과 같은 이름의 소문자를 이름으로 가지는 JSON 파일을 생성합니다. 이 예제에서는, `sparkle_particle.json` 으로 생성하겠습니다. 이 파일은 Minecraft가 입자에 어떠한 텍스쳐를 사용해야 하는지 정의하기 때문에 매우 중요합니다. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +:::tip +입자에 애니메이션을 적용하고 싶다면 `textures` 배열 노드에 더 많은 텍스쳐를 추가하면 됩니다. 입자는 배열의 순서대로 반복될 것입니다. +::: + +## 새 입자 테스트하기 + +위의 모든 작업을 완료했다면, 이제 Minecraft에서 입자를 테스트해볼 차례입니다. + +다음의 명령어를 입력하여 입자가 정상적으로 작동하는지 확인할 수 있습니다. + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![입자 쇼케이스](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +:::info +이 명령어를 사용하면 입자가 플레이어 안에 생성될 것입니다. 입자를 보려면 뒤로 몇 걸음 걸어야할 수도 있습니다. +::: + +대신, 같은 명령어로 명령 블록을 통해 입자를 생성할 수도 있습니다. diff --git a/versions/1.21/translated/ko_kr/index.md b/versions/1.21/translated/ko_kr/index.md new file mode 100644 index 000000000..429290408 --- /dev/null +++ b/versions/1.21/translated/ko_kr/index.md @@ -0,0 +1,21 @@ +--- +title: Fabric 문서 +description: Minecraft용 모딩 툴체인 Fabric의 엄선된 공식 문서입니다. +layout: home +hero: + name: Fabric 문서 + tagline: Minecraft용 모딩 툴체인 Fabric의 엄선된 공식 문서입니다. +features: + - title: 플레이어 가이드 + icon: 📚 + details: Fabric 기반 모드를 사용하려는 플레이어인가요? 플레이어 가이드에서 자세히 알아보세요. 이 가이드는 Fabric 모드 다운로드, 설치 및 문제 해결을 도와줍니다. + link: /ko_kr/players/ + linkText: 자세히 보기 + - title: 개발자 가이드 + icon: 🛠️ + details: 커뮤니티에서 작성한 개발자 가이드는 개발 환경 설정부터 렌더링 및 네트워킹과 같은 고급 주제까지 모든 것을 다루고 있습니다. + link: /ko_kr/develop/ + linkText: 시작하기 +--- + +Fabric 문서에 기여하고 싶다면, [GitHub](https://github.com/FabricMC/fabric-docs)에서 소스 코드를 볼 수 있으며, 기여시에는 [기여 가이드라인](./contributing)을 준수하시기 바랍니다. diff --git a/versions/1.21/translated/ko_kr/players/faq.md b/versions/1.21/translated/ko_kr/players/faq.md new file mode 100644 index 000000000..ea4fab2ff --- /dev/null +++ b/versions/1.21/translated/ko_kr/players/faq.md @@ -0,0 +1,29 @@ +--- +title: 자주 묻는 질문 +description: Fabric 관련 서버 관리자와 플레이어가 자주 묻는 질문입니다. +--- + +# 자주 묻는 질문 + +자주 언급되는 질문이 여럿 있으므로, 아래에 간단히 정리했습니다. + +## Fabric이 지원하는 Minecraft 버전은 무엇인가요? 일반적인 질문 + +공식적으로, Fabric은 스냅숏 `18w43b` (`1.14` 이상) 의 모든 버전을 지원합니다. + +## 어디서 Fabric 모드를 다운로드 할 수 있나요? {#where-can-i-download-published-fabric-mods} + +:::info +항상 모드를 다운로드한 사이트가 안전한지 확인하세요. [안전한 모드 찾기](./finding-mods) 에서 더 많은 정보를 확인할 수 있습니다. +::: + +대부분의 모드 개발자는 [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) 또는 [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4) 에 모드를 업로드 하지만, 몇몇 사람들은 개인 웹사이트나 GitHub 레포지토리 등 같은 다른 플랫폼에 모드를 업로드하는 경우도 있습니다. + +## 먼저 생성된 Fabric 모드팩은 어디에서 찾을 수 있나요? {#where-can-i-find-premade-fabric-modpacks} + +Fabric 모드팩은 다음과 같이 여러 플랫폼에서 찾을 수 있습니다. + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/ko_kr/players/finding-mods.md b/versions/1.21/translated/ko_kr/players/finding-mods.md new file mode 100644 index 000000000..1b3fdfda1 --- /dev/null +++ b/versions/1.21/translated/ko_kr/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: 안전한 모드 찾기 +description: 안전한 사이트에서 Fabric 모드를 찾는 방법을 알아보세요. +authors: + - IMB11 +--- + +# 안전한 모드 찾기 {#finding-mods} + +먼저, 신뢰는 주관적이므로, 항상 모드를 다운로드 하기 전 직접 판단해야 합니다. 그럼에도, 안전한 모드를 찾는 데 도움이 될 수 있는 여러 가지 방법이 있습니다. + +## 1. 안전하다고 알려진 소스를 사용하기 {#trustworthy-source} + +대부분의 모드 개발자는 [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) 또는 [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4) 에 모드를 업로드 합니다. + +이러한 서비스는 모드와 설명이 같은지, 모드에 악성 코드가 포함되어 있지 않은지 확인합니다. 공유되고 있는 악성 모드를 신고할 수도 있습니다. 빠르게 행동을 취할 것입니다. + +## 2. 다른 것들과 함께 확인하기! {#with-others} + +신뢰할 수 없는 출처에서 모드를 다운로드하는 경우, 다른 사람들이 다운로드하려는 곳에서 이전에 모드를 다운로드한 적이 있는지, 문제가 있었는지 확인해야 합니다. + +만약 의심이 드신다면, '#player-support' 채널의 [Fabric Discord](https://discord.gg/v6v4pMv)에서 문의해 주세요. + +## 3. 일반적인 악성 코드 사이트를 조심하세요! {#avoid-malware} + +:::info +악성 코드 사이트는 모두에게 분명하지 않을 수도 있습니다. 확실하지 않으시다면, 다른 사람들에게 의견을 물어보거나, 그러한 사이트를 완전히 피하고, Modrinth나 Curseforge와 같은 신뢰있는 소스에만 의존하세요. +::: + +Minecraft의 모드를 제공한다고 주장하지만, 실제론 그냥 악성 코드 사이트거든요. 이러한 사이트는 가급적 피하는 것이 좋습니다. + +[Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security)와 같은 안티바이러스 소프트웨어를 사용하거나 [VirusTotal](https://www.virustotal.com/)에서 다운로드한 모드를 확인할 수 있습니다. 하지만, 이 방법을 전적으로 의지하지 마세요. 가끔 틀릴 때도 있거든요. + +다시 한 번 더, 만약 의심이 드신다면, '#player-support' 채널의 [Fabric Discord](https://discord.gg/v6v4pMv)에서 문의해 주세요. diff --git a/versions/1.21/translated/ko_kr/players/index.md b/versions/1.21/translated/ko_kr/players/index.md new file mode 100644 index 000000000..eec684e5f --- /dev/null +++ b/versions/1.21/translated/ko_kr/players/index.md @@ -0,0 +1,12 @@ +--- +title: 플레이어 가이드 +description: 플레이어와 서버 관리자를 위한 Fabric 설치 및 사용 가이드 모음입니다. +--- + +# 플레이어 가이드 {#player-guides} + +이 문단의 가이드는, Fabric 설치, 사용, 문제 해결 방법을 배우고자 하는 플레이어와 서버 관리자를 위한 것입니다. + +사용 가능한 모든 가이드 목록은 사이드바를 참조해 주세요. + +문제가 생기셨다면, [GitHub](https://github.com/FabricMC/fabric-docs)에 신고하거나 [Fabric Discord](https://discord.gg/v6v4pMv)에서 `#player-support` 또는 `#server-admin-support` 채널에 도움을 요청하실 수 있습니다. diff --git a/versions/1.21/translated/ko_kr/players/installing-fabric.md b/versions/1.21/translated/ko_kr/players/installing-fabric.md new file mode 100644 index 000000000..0f1de8180 --- /dev/null +++ b/versions/1.21/translated/ko_kr/players/installing-fabric.md @@ -0,0 +1,59 @@ +--- +title: Fabric 설치 +description: Fabric을 설치하는 방법에 대한 단계별 가이드입니다. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Fabric 설치하기 {#installing-fabric} + + + +이 가이드는 오직 공식 Minecraft 런처용 Fabric 설치 방법을 안내합니다. 서드 파티 런처의 경우, 해당 런처의 설명서를 참조하여 주세요. + +## 1. Fabric 실행기 다운로드하기 {#1-download-the-fabric-installer} + +[Fabric 웹사이트](https://fabricmc.net/use/)에서 Fabric 실행기를 설치할 수 있습니다. + +Windows라면, Java가 다운로드 되어야 할 필요가 없게 하도록 `exe` 버전 (`Windows 용 다운로드`)를 다운로드하세요. 대신 공식 런처와 함께 제공되는 Java를 사용합니다. + +macOS나 Linux의 경우라면, `.jar`버전을 다운로드 받으셔야 합니다. 가끔, 이 단계 전에 Java를 다운로드하셔야 할 때도 있습니다. + +## 2. Fabric 실행기 실행하기 {#2-run-the-fabric-installer} + +:::warning +실행하기 전, 먼저 Minecraft와 Minecraft 런처를 닫으세요. +::: + +:::details macOS 사용자들을 위한 정보 + +macOS의 경우 다운로드 디렉터리에서 '.jar' 파일을 마우스 오른쪽 버튼으로 클릭하고 '열기'를 클릭하여 실행해야 할 수 있습니다. + +![Fabric 실행기의 MacOS 컨텍스트 메뉴](/assets/players/installing-fabric/macos-downloads.png) + +"여시겠습니까"?라고 물으면, `열기`를 한 번 더 클릭하세요. +::: + +설치기를 열면, 다음과 같은 화면이 보일 것입니다: + +!["Install"을 강조 표시한 Fabric 설치기](/assets/players/installing-fabric/installer-screen.png) + + + +Fabric을 설치하기 위하여 드롭다운에서 게임 버전을 선택하고 `install`을 클릭하세요. + +:::warning 중요 +'Create Profile'이 켜져 있는지 확인하세요. +::: + +## 3. 이제 끝났습니다! {#3-you-re-done} + +설치가 완료되면 Minecraft 런처를 열고 왼쪽 하단의 드롭다운에서 Fabric 프로필을 선택한 후 플레이를 누르면 됩니다! + +![Fabric 프로필을 선택한 Minecraft 런처](/assets/플레이어/설치-패브릭/런처 화면.png) + +이제 Fabric을 설치했으니 게임에 모드를 추가할 수 있습니다! [안전한 모드 찾기](./finding-mods) 에서 더 많은 정보를 확인할 수 있습니다. + +이 가이드를 따르는 동안 문제가 발생하면 `#player-support` 채널의 [Fabric Discord](https://discord.gg/v6v4pMv)에서 도움을 요청할 수 있습니다. diff --git a/versions/1.21/translated/ko_kr/players/troubleshooting/crash-reports.md b/versions/1.21/translated/ko_kr/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..e67a076f8 --- /dev/null +++ b/versions/1.21/translated/ko_kr/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: 충돌 보고서 +description: 충돌 보고서가 어떤 역할을 가지고, 어떻게 읽는지 알아보세요. +authors: + - IMB11 +--- + +# 충돌 보고서 {#crash-reports} + +:::tip +충돌의 원인을 찾는 데 어려움이 있으시다면, [Fabric Discord (영어)](https://discord.gg/v6v4pMv) 의 `#player-support` 또는 `#server-admin-support` 채널에 도움을 요청할 수 있습니다. +::: + +충돌 보고서는 게임 또는 서버의 문제를 해결하기 위해 굉장히 중요한 부분 중 하나입니다. 이러한 충돌 보고서는 충돌에 관련된 많은 정보를 포함하고 있으며, 충돌의 원인을 찾는 데 도움이 됩니다. + +## 충돌 보고서 찾기 {#finding-crash-reports} + +충돌 보고서는 게임 디렉토리의 `crash-reports` 폴더에 저장됩니다. 서버의 경우, 서버 디렉토리의 `crash-reports` 폴더에 저장됩니다. + +서드 파티 런처의 경우, 충돌 보고서를 찾으려면 해당 런처의 문서를 참고해야 할 수 있습니다. + +충돌 보고서는 다음과 같은 위치에서 찾을 수 있습니다. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## 충돌 보고서 읽기 {#reading-crash-reports} + +충돌 보고서는 매우 길고, 읽기 매우 어려울 수 있습니다. 하지만, 충돌에 관련된 많은 정보를 포함하고 있고, 충돌의 원인을 찾는데 유용합니다. + +이 가이드에선, [이 충돌 보고서를 예시로](/assets/players/crash-report-example.txt) 보고서를 읽어볼 것입니다. + +:::details 충돌 보고서 + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### 충돌 보고서의 목차 {#crash-report-sections} + +충돌 보고서는 여러 목차로 이루어져 있으며, 각 목차는 다음 제목을 가집니다. + +- `---- Minecraft Crash Report ----`, 보고서 요약본. 이는 충돌을 일으킨 주요 오류, 발생한 시간, 그리고 관련 스택트레이스로 이루어집니다. 대부분의 경우에서 스택트레이스에 충돌을 일으킨 모드의 리퍼런스가 포함되므로 보고서의 가장 중요한 부분이라고 할 수 있습니다. +- `-- Last Reload --`, 충돌이 리소스 다시 로드 (F3+T) 도중 발생하지 않았다면 대부분 불필요합니다. 다시 로드가 진행된 시간, 다시 로드 중 발생한 오류의 관련 스택 트레이스 등을 포함합니다. 이러한 오류는 대부분 리소스 팩에서 발생하며, 게임에 문제를 일으키지 않는 한 신경 쓸 필요는 없습니다. +- 운영체제, Java 버전, 게임에 할당된 메모리의 양 등이 기록됩니다. 게임에 적당한 양의 메모리가 할당되었는지, 올바른 Java 버전을 사용했는지 등을 확인할 때 유용합니다. + - Fabric의 경우, 여기에 설치된 모드가 기록되는 `Fabric Mods:` 가 추가됩니다. 모드 간 충돌을 파악할 때 유용합니다. + +### 충돌 보고서로 할 수 있는 것 {#breaking-down-the-crash-report} + +이제 충돌 보고서의 목차를 알았으니, 충돌 보고서를 분해해서 충돌의 원인이 무엇인지 파악할 수 있게 되었습니다. + +아래에 링크된 예시를 통해, 충돌 보고서를 분석하고 충돌을 일으킨 원인과 모드를 찾아봅시다. + +이 예시에서는 `---- Minecraft Crash Report ----` 안 목차의 스택트레이스에서 충돌을 일으킨 주요 오류가 기록되어 있어 가장 중요한 부분이라고 할 수 있습니다. + +:::details 오류 표시 + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +스택트레이스에 언급된 모드의 개수에 따라, 정확히 지목하기 어려울 수 있지만, 가장 먼저 해야 할 일은 충돌을 일으킨 모드를 찾는 것입니다. + +이 예시에서는, `snownee`가 스택트레이스에서 처음으로 언급되었기 때문에 충돌을 일으킨 모드입니다. + +하지만, 여러 모드가 언급되었다면, 모드 간의 호환성 문제일 수도 있으며, 충돌을 일으킨 모드에는 문제가 없을 가능성도 있습니다. 이러한 경우에는, 모드 개발자에게 충돌을 신고하고, 충돌을 조사할 수 있도록 하는 것이 최선책입니다. + +## Mixin 충돌 {#mixin-crashes} + +:::info +Mixin은 모드가 게임의 소스 코드를 수정하지 않고도 게임을 수정할 수 있도록 하는 방법 중 하나입니다. 이는 많은 모드에서 사용되고, 개발자에게 매우 강력한 도구입니다. +::: + +Mixin이 충돌하면, 스택트레이스에는 충돌한 Mixin과 그 Mixin이 수정하려고 한 클래스가 기록됩니다. + +메소드 Mixin은 스택트레이스에 `modid$handlerName`로 기록되는데, `modid`는 모드의 ID, `handlerName`은 Mixin 처리기의 이름입니다. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +이 정보를 통해 충돌을 일으킨 모드를 찾고, 모드 개발자에게 충돌을 신고할 수 있게 됩니다. + +## 충돌 보고서로 뭘 하나요 {#what-to-do-with-crash-reports} + +충돌 보고서로 할 수 있는 최고의 행동은 보고서를 Paste에 업로드하고, 이슈 트래커 또는 커뮤니티 (Discord 등)에 게시하여 모드 개발자에게 공유하는 것입니다. + +이는 모드 개발자가 충돌을 재현하는 등 분석하고, 충돌을 해결할 수 있게 합니다. + +일반적으로 충돌 보고서에 사용되는 기록 사이트는 다음과 같습니다. + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/ko_kr/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/ko_kr/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..5f30ab455 --- /dev/null +++ b/versions/1.21/translated/ko_kr/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: 로그 업로드 +description: 문제를 해결하기 위해 로그를 업로드하는 방법을 알아보세요. +authors: + - IMB11 +--- + +# 로그 업로드 {#uploading-logs} + +문제를 해결할 때, 원인을 파악하기 위해 개발자에게 로그를 전송해야 하는 경우가 자주 있습니다. + +## 왜 로그를 업로드해야 하나요? {#why-should-i-upload-logs} + +로그를 단순히 복사하고 붙여넣는 것보다 업로드할 때 문제를 해결하는 데 보다 수월해집니다. 또한 다른 곳으로 로그를 간단하게 전송할 수 있게 됩니다. + +때때로 일부 서비스에서는 로그에 구문 강조를 지원하여, 더 쉽게 읽을 수 있게 하고, 사용자 아이디나 시스템 정보 등 민감한 정보를 걸러주기도 합니다. + +## 충돌 보고서 {#crash-reports} + +충돌 리포트는 게임이 충돌하면 자동으로 생성되며, 게임의 전체 로그 대신 충돌 관련 정보만 포함하고 있습니다. 로그는 게임 디렉토리의 `logs` 폴더에 저장됩니다. 충돌 리포트는 게임 디렉토리의 `crash-reports` 폴더에 저장됩니다. + +충돌 리포트에 대한 자세한 정보는 [충돌 리포트](./crash-reports) 페이지를 참고하세요. + +## 로그 찾기 {#locating-logs} + +본 가이드는 공식 Minecraft 런처 (일반적으로 "바닐라 런처" 라고 불림) 를 위한 것이며, 서드파티 런처는 해당 런처의 문서를 확인해야 합니다. + +각 운영체제에서 로그 폴더의 위치는 다음과 같습니다. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +최신 로그는 `latest.log` 에 저장되며, 이전 로그는 `연도-월-일_순서.log.gz` 의 이름 패턴으로 저장됩니다. + +## 로그를 온라인으로 업로드 {#uploading-logs-online} + +로그는 다음처럼 여러 서비스로 업로드 될 수 있습니다. + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/ko_kr/sidebar_translations.json b/versions/1.21/translated/ko_kr/sidebar_translations.json new file mode 100644 index 000000000..99db59bd1 --- /dev/null +++ b/versions/1.21/translated/ko_kr/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "플레이어 가이드", + "players.faq": "자주 묻는 질문", + "players.installingJava": "Java 설치", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Fabric 설치", + "players.findingMods": "신뢰 가능한 모드 찾기", + "players.installingMods": "모드 설치", + "players.troubleshooting": "스스로 해결", + "players.troubleshooting.uploadingLogs": "로그 업로드", + "players.troubleshooting.crashReports": "충돌 보고서", + "players.updatingFabric": "Fabric 업데이트", + "develop.title": "개발자 가이드", + "develop.gettingStarted": "시작하기", + "develop.gettingStarted.introduction": "패브릭과 모딩 소개", + "develop.gettingStarted.devEnvSetup": "개발 환경 설정하기", + "develop.gettingStarted.creatingProject": "프로젝트 생성하기", + "develop.gettingStarted.projectStructure": "프로젝트 구조", + "develop.gettingStarted.launchGame": "게임 실행하기", + "develop.gettingStarted.solvingProblems": "기초 문제 해결", + "develop.items": "아이템", + "develop.items.first-item": "첫번째 아이템 만들기", + "develop.items.food": "음식 아이템", + "develop.items.custom-armor": "사용자 정의 갑옷", + "develop.items.custom-tools": "사용자 정의 도구", + "develop.items.custom-item-groups": "사용자 정의 그룹", + "develop.items.custom-item-interactions": "사용자 정의 아이템 상호작용", + "develop.items.potions": "물약", + "develop.items.custom-data-components": "사용자 정의 데이터 구성 요소", + "develop.blocks": "블록", + "develop.blocks.first-block": "첫번째 블록 만들기", + "develop.blocks.blockstates": "블록 상태", + "develop.entities": "엔티티", + "develop.entities.effects": "상태 효과", + "develop.entities.damage-types": "피해 유형", + "develop.commands": "명령어", + "develop.commands.basics": "명령어 만들기", + "develop.commands.arguments": "인수", + "develop.commands.suggestions": "제안", + "develop.rendering": "렌더링", + "develop.rendering.basicConcepts": "기본 렌더링 개념", + "develop.rendering.drawContext": "그리기 컨텍스트 사용", + "develop.rendering.hud": "HUD 렌더링", + "develop.rendering.gui": "GUI와 화면", + "develop.rendering.gui.customScreens": "사용자 정의 화면", + "develop.rendering.gui.customWidgets": "사용자 정의 위젯", + "develop.rendering.particles": "입자", + "develop.rendering.particles.creatingParticles": "사용자 정의 입자 만들기", + "develop.misc": "기타", + "develop.misc.codecs": "코덱", + "develop.misc.events": "이벤트", + "develop.misc.text-and-translations": "텍스트와 번역", + "develop.misc.ideTipsAndTricks": "IDE 팁과 트릭들", + "develop.misc.automatic-testing": "테스트 자동화", + "develop.sounds": "소리", + "develop.sounds.using-sounds": "소리 이벤트 재생", + "develop.sounds.custom": "사용자 정의 소리 생성" +} diff --git a/versions/1.21/translated/ko_kr/website_translations.json b/versions/1.21/translated/ko_kr/website_translations.json new file mode 100644 index 000000000..4679808aa --- /dev/null +++ b/versions/1.21/translated/ko_kr/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "페이지 작성자", + "authors.nogithub": "%s (GitHub에 없음)", + "banner": "Fabric 문서화가 진행 중입니다. %s 또는 %s에 이슈를 보고하세요.", + "description": "Minecraft를 위한 모딩 툴체인, Fabric을 위한 포괄적인 문서입니다.", + "download": "%s 다운로드", + "footer.next": "다음 페이지", + "footer.prev": "이전 페이지", + "github_edit": "GitHub에서 이 페이지 편집", + "lang_switcher": "언어 변경", + "last_updated": "마지막 업데이트", + "mode_dark": "다크 모드로 전환", + "mode_light": "라이트 모드로 전환", + "mode_switcher": "외관", + "nav.contribute": "기여하기", + "nav.contribute.api": "Fabric API", + "nav.download": "다운로드", + "nav.home": "메인", + "outline": "이 페이지에서", + "return_to_top": "맨 위로 돌아가기", + "search.back": "검색 닫기", + "search.button": "검색", + "search.display_details": "상세 목록 표시", + "search.footer.close": "으로 닫기", + "search.footer.close.key": "Esc 키", + "search.footer.down.key": "아래 방향키", + "search.footer.navigate": "(으)로 탐색", + "search.footer.up.key": "위 방향키", + "search.footer.select": "으로 선택", + "search.footer.select.key": "엔터 키", + "search.no_results": "다음에 대한 검색 결과가 존재하지 않습니다.", + "search.reset": "검색 초기화", + "sidebar_menu": "메뉴", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Fabric 문서", + "version.reminder": "이 페이지는 다음 버전에 맞게 작성되었습니다:", + "version.switcher": "버전 선택", + "404.code": "404", + "404.crowdin_link": "Crowdin에서 번역하기", + "404.crowdin_link.label": "Crowdin 편집기 열기", + "404.english_link": "영어로 읽기", + "404.english_link.label": "영어 버전 열기", + "404.link": "메인 페이지", + "404.link.label": "메인 페이지로 돌아가기", + "404.quote": "이 페이지가 용암에 빠졌습니다", + "404.title": "페이지를 찾을 수 없습니다" +} diff --git a/versions/1.21/translated/ms_my/players/index.md b/versions/1.21/translated/ms_my/players/index.md new file mode 100644 index 000000000..eeddd1322 --- /dev/null +++ b/versions/1.21/translated/ms_my/players/index.md @@ -0,0 +1,12 @@ +--- +title: Panduan Pemain +description: Koleksi panduan untuk pemain dan juga pentadbir pelayan dalam memasang dan menggunakan Fabric. +--- + +# Panduan Pemain + +Bahagian Dokumentasi Fabric ini dikhususkan kepada pemain dan pentadbir pelayan yang ingin mengetahui cara memasang, menggunakan dan menyelesaikan masalah berkenaan Fabric. + +Anda harus merujuk kepada bar sisi untuk senarai semua panduan yang tersedia. + +Jika anda menghadapi sebarang isu, sila laporkannya [di GitHub](https://github.com/FabricMC/fabric-docs) atau minta bantuan di [pelayan Discord Fabric](https://discord.gg/v6v4pMv) dalam saluran `#player-support` atau `#server-admin-support`. diff --git a/versions/1.21/translated/ms_my/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/ms_my/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..f8f38834d --- /dev/null +++ b/versions/1.21/translated/ms_my/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Memuat Naik Log +description: Cara memuat naik log untuk menyelesaikan masalah. +authors: + - IMB11 +--- + +# Memuat Naik Log + +Apabila menyelesaikan masalah, anda selalunya perlu menyediakan log untuk membantu mengenal pasti punca isu tersebut. + +## Mengapa saya perlu memuat naik log? + +Memuat naik log membolehkan orang lain membantu anda dalam menyelesaikan masalah anda dengan lebih cepat daripada hanya menampal log ke dalam ruang perbualan atau siaran forum. Ia juga membolehkan anda berkongsi log anda dengan orang lain tanpa perlu menyalin dan menampalnya. + +Sesetengah tapak penampalan juga menyediakan penyerlahan sintaks untuk log, yang menjadikannya lebih mudah dibaca dan mungkin menapis maklumat sensitif, seperti nama pengguna anda atau maklumat sistem. + +## Laporan Ranap Permainan + +Laporan ranap permainan dijana secara automatik apabila permainan ranap. Ia hanya mengandungi maklumat ranap dan bukan log sebenar permainan. Ia terletak di dalam folder `crash-reports` dalam direktori permainan. + +Untuk mendapatkan maklumat lanjut tentang laporan ranap permainan, lihat [Laporan Ranap Permainan](./crash-reports). + +## Mencari Lokasi Log + +Panduan ini merangkumi Pelancar Minecraft rasmi (biasanya dirujuk sebagai "pelancar vanila") - untuk pelancar pihak ketiga, anda harus merujuk dokumentasi mereka. + +Log-log terletak di dalam folder `log` dalam direktori permainan, direktori permainan boleh didapati di lokasi berikut bergantung pada sistem pengoperasian anda: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +Log terkini dipanggil `latest.log`, dan log sebelumnya menggunakan corak penamaan `yyyy-mm-dd_number.log.gz`. + +## Memuat Naik Log + +Log boleh dimuat naik ke pelbagai perkhidmatan, seperti: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/nl_nl/develop/blocks/blockstates.md b/versions/1.21/translated/nl_nl/develop/blocks/blockstates.md new file mode 100644 index 000000000..5ef78c6d7 --- /dev/null +++ b/versions/1.21/translated/nl_nl/develop/blocks/blockstates.md @@ -0,0 +1,127 @@ +--- +title: Blok Staten +description: Leer waarom blok staten een goede manier zijn om visuele functies toe te voegen aan je blokken. +authors: + - IMB11 +--- + +# Blok Staten {#block-states} + +Een block staat is een stukje data gekoppeld aan een enkel blok in de Minecraft wereld, wat informatie bevat over het blok in de vorm van eigenschappen - hier een paar voorbeelden van eigenschappen die vanilla opslaat: + +- Rotatie: Het meest gebruikt voor boomstammen en andere natuur gerelateerde blokken. +- Geactiveerd: Erg sterk gebruikt in vele Redstone apparaten, en blokken zoals de Oven of de Roker. +- Leeftijd: Gebruikt voor gewassen, planten, kiemplanten, etc. + +Je kunt je dus wel inbeelden waarom ze zo handig zijn - ze vermijden de noodzaak om gegevens in een blok entiteit op te slaan - wat de wereld grootte verkleint en TPS-problemen voorkomt! + +Blok staat definities kunnen gevonden worden in de `assets//blockstates` folder. + +## Voorbeeld: Pilaar Blok {#pillar-block} + + + +Minecraft heeft al een paar zelfgemaakte classen die je gemakkelijk bepaalde types blok laat maken - dit voorbeeld gaat over het maken van een blok met de `axis` (as) eigenschap door een "Gecondenseerde Eiken Boomstam" blok te maken. + +Met de vanilla class `PillarBlock` kan het blok in de X-, Y- of Z-as worden geplaatst. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Pilaren hebben twee texturen, de bovenkant en de zijkant - ze maken gebruik van het `block/cube_collumn` model. + +Zoals gewoonlijk, met alle blok texturen, kunnen de textuurbestanden worden gevonden in `assets//textures/block` + + + +Omdat de pilaar twee posities heeft, horizontaal en verticaal, zullen we twee verschillende modelbestanden moeten maken: + +- `condensed_oak_log_horizontal.json` wat het `block/cube_column_horizontal` model uitbreidt. +- `condensed_oak_log.json` wat het `block/cube_column` model uitbreidt. + +Hier een voorbeeld van het bestand `condensed_oak_log_horizontal.json`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +Voor een meer diepgaande blik op alle modificaties die beschikbaar zijn in de blockstate-bestanden, ga naar de pagina [Minecraft Wiki - Models (Block States)](https://minecraft.wiki/w/Tutorials/Models#Block_states). +::: + +Vervolgens zullen we een blok staat bestand moeten maken. Het blok staat bestand is waar de magie gebeurt: pilaren hebben drie assen, dus we zullen specifieke modellen gebruiken voor de volgende situaties: + +- `axis=x` - Wanneer het blok langs de X-as wordt geplaatst, roteren we het model in de positieve X-richting. +- `axis=y` - Wanneer het blok langs de Y-as wordt geplaatst, gebruiken we het normale verticale model. +- `axis=z` - Wanneer het blok langs de Z-as wordt geplaatst, roteren we het model in de positieve X-richting. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +Zoals altijd moet je een vertaling voor uw blok maken, en een voorwerp model dat de "parent" is van een van de twee modellen. + +![Example of Pillar block in-game](/assets/develop/blocks/blockstates_1.png) + +## Aangepaste blok staten {#custom-block-states} + +Aangepaste blok staten zijn geweldig als je blok unieke eigenschappen heeft - soms zul je ook zien dat je blok vanilla eigenschappen kan hergebruiken. + +Dit voorbeeld creëert een unieke boolean eigenschap met de naam `activated` - wanneer een speler met de rechtermuisknop op het blok klikt, gaat het blok van `activated=false` naar `activated=true` - waardoor de textuur net zo wordt gewijzigd. + +### Het maken van De Eigenschap {#creating-the-property} + +Ten eerste moet je de eigenschap zelf maken - sinds dit een boolean is, zullen we de `BooleanProperty.of` methode gebruiken. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Vervolgens moeten we de eigenschap toevoegen aan de blok staat manager in de methode `appendProperties`. Je zult de methode moeten overschrijven om toegang te krijgen tot de builder: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Je moet ook een standaardstaat instellen voor de eigenschap `activated` in de constructor van jouw aangepaste blok. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +Vergeet niet om je blok te registreren met de zelfgemaakte class in plaats val `Block`! +::: + +### Het Gebruik van De Eigenschap {#using-the-property} + +In dit voorbeeld wordt de boolean eigenschap `activated` omgedraaid wanneer de speler interactie heeft met het blok. We kunnen hiervoor de `onUse` methode overschrijven: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### Het Visualiseren van De Eigenschap {#visualizing-the-property} + +Voordat je het blok staat bestand maakt, moet je texturen opgeven voor zowel de geactiveerde als de gedeactiveerde staten van het blok, evenals voor het blokmodel. + + + +Gebruik je kennis van blokmodellen om twee modellen voor het blok te maken: één voor de geactiveerde staat en één voor de gedeactiveerde staat. Zodra je dat gedaan hebt, kun je het blok staat bestand gaan maken. + +Omdat je een nieuwe eigenschap hebt gemaakt, moet je het blok staat bestand voor het blok bijwerken om rekening te houden met die eigenschap. + +Als je meerdere eigenschappen hebt voor een blok, moet je met alle mogelijke combinaties rekening houden. `activated` en `axis` zouden bijvoorbeeld leiden tot 6 combinaties (twee mogelijke waarden voor `activated` en drie mogelijke waarden voor `axis`). + +Omdat dit blok maar twee mogelijke varianten heeft, omdat er maar een eigenschap is (`activated`), zal de blok staat JSON er ongeveer zo uitzien: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +Omdat het voorbeeldblok een lamp is, zullen we er ook voor moeten zorgen dat het licht uitstraalt als de eigenschap `activated` waar is. Dit kan worden gedaan via de blokinstellingen die aan de constructor worden doorgegeven bij het registreren van het blok. + +U kunt de `luminance`-methode gebruiken om het lichtniveau in te stellen dat door het blok wordt uitgezonden. We kunnen een statische methode maken in de `PrismarineLampBlock` class om het lichtniveau terug te geven op basis van de `activated`-eigenschap, en dit doorgeven als een methodereferentie naar de `luminance`-methode: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +Zodra je klaar bent met alles, zal het resultaat er ongeveer zo uitzien: + + diff --git a/versions/1.21/translated/nl_nl/develop/blocks/first-block.md b/versions/1.21/translated/nl_nl/develop/blocks/first-block.md new file mode 100644 index 000000000..718a08617 --- /dev/null +++ b/versions/1.21/translated/nl_nl/develop/blocks/first-block.md @@ -0,0 +1,170 @@ +--- +title: Maak Je Eerste Blok +description: Leer hoe je je eerste zelfgemaakte blok kunt maken in Minecraft. +authors: + - IMB11 + - xEobardThawne + - its-miroma +--- + +# Maak Je Eerste Blok {#creating-your-first-block} + +Blokken vormen de basis van Minecraft – letterlijk en figuurlijk. Net als alles in de game, worden ze netjes opgeborgen in registers. + +## Je Blokken-klasse Voorbereiden {#preparing-your-blocks-class} + +Als je de [Maak Je Eerste Voorwerp](../items/first-item) pagina hebt afgerond, zal dit proces erg vertrouwd aanvoelen - je zult een methode moeten maken die je blokken registreert, en het blokvoorwerp. + +Je kunt deze methode het beste in een soort klasse genaamd `ModBlokken` (of wat je het ook wilt noemen) zetten. + +Mojang doet iets soortgelijks als dit met vanilla blokken; je kunt de klasse `Blocks` raadplegen om te zien hoe zij het doen. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Net als bij items moet je ervoor zorgen dat de klasse wordt geladen, zodat alle statische velden die je blokinstanties bevatten, worden geïnitialiseerd. + +Je kunt dit doen door een dummy `initialize`-methode te maken, die in je mod-initialisator kan worden aangeroepen om de statische initialisatie te activeren. + +:::info +Voor het geval dat je niet weet wat statische initialisatie is: dit is het proces van het initialiseren van statische velden in een klasse. Dit wordt gedaan wanneer de klasse door de JVM wordt geladen, en gebeurt voordat er exemplaren van de klasse worden gemaakt. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## Het Maken En Registreren Van Je Blok {#creating-and-registering-your-block} + +Net als voorwerpen hebben blokken een klasse `Blocks.Settings` in hun constructor, die eigenschappen over het blok specificeert, zoals de geluidseffecten en het mining-niveau. + +We zullen hier niet alle opties behandelen; je kunt de klasse zelf bekijken om de verschillende opties te zien, die voor zich spreken. + +Ter voorbeeld zullen we een simpel blok maken dat de eigenschappen heeft van aarde, maar het is een ander materiaal. + +:::tip +Je kunt ook `AbstractBlock.Settings.copy(AbstractBlock block)` gebruiken om de instellingen van een bestaand blok te kopiëren. In dit geval hadden we `Blocks.DIRT` kunnen gebruiken om de instellingen van aarde te kopiëren, maar voor het voorbeeld gebruiken we de bouwer. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Om het blokvoorwerp automatisch te maken, kunnen we `true` doorgeven aan de parameter `shouldRegisterItem` van de `register`-methode die we in de vorige stap hebben gemaakt. + +### Je Blokvoorwerp Toevoegen aan een Voorwerpgroep {#adding-your-block-to-an-item-group} + +Omdat 'BlockItem' automatisch wordt aangemaakt en geregistreerd, moet je, om het aan een voorwerpgroep toe te voegen, de methode 'Block.asItem()' gebruiken om de instantie 'BlockItem' op te halen. + +Voor dit voorbeeld gebruiken we een aangepaste artikelgroep die is gemaakt op de pagina [Aangepaste Voorwerpgroepen](../items/custom-item-groups). + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Je zou nu moeten merken dat jouw blok in de creatieve inventaris staat en in de wereld kan worden geplaatst! + +![Block in world without suitable model or texture](/assets/develop/blocks/first_block_0.png). + +Er zijn wel een paar problemen: het blokvoorwerp heeft geen naam en het blok heeft geen textuur, blokmodel of voorwerpmodel. + +## Blokvertalingen toevoegen {#adding-block-translations} + +Om een ​​vertaling toe te voegen, moet je een vertaalsleutel aanmaken in je vertaalbestand - `assets//lang/nl_nl.json` (`us_en.json` voor Engels). + +Minecraft zal deze vertaling gebruiken in de creatieve inventaris en op andere plaatsen waar de bloknaam wordt weergegeven, zoals bij commandofeedback. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +Je kunt het spel opnieuw starten of je mod bouwen en op F3 + T drukken om de wijzigingen toe te passen - en je zou moeten zien dat het blok een naam heeft in de creatieve inventaris en op andere plaatsen zoals het statistiekenscherm. + +## Modellen en Texturen {#models-and-textures} + +Alle bloktexturen zijn te vinden in de map `assets//textures/block` - een voorbeeldtextuur voor het blok "Condensed Dirt" is gratis te gebruiken. + + + +Om de textuur in het spel te laten verschijnen, moet je een blok- en voorwerpmodel maken dat je kunt vinden op de respectievelijke locaties voor het blok "Condensed Dirt": + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +Het voorwerpmodel is vrij eenvoudig, het kan gewoon het blokmodel als ouder gebruiken - aangezien de meeste blokmodellen ondersteuning bieden voor weergave in een GUI: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +Het blokmodel moet in ons geval echter als ouder het `block/cube_all`-model hebben: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +Wanneer je het spel laadt, merk je misschien dat de textuur nog steeds ontbreekt. Dit komt omdat je een blockstaat-definitie moet toevoegen. + +## Het Maken van De Blokstaat-definitie {#creating-the-block-state-definition} + +De blokstaat-definitie wordt gebruikt om het spel te instrueren op basis van de huidige status van het blok. + +Voor het voorbeeldblok, dat geen complexe blokstaat heeft, is slechts één invoer in de definitie nodig. + +Dit bestand moet zich in de map `assets/mod_id/blockstates` bevinden en de naam ervan moet overeenkomen met het blok-ID dat is gebruikt bij het registreren van uw blok in de klasse `ModBlokken`. Als het blok-ID bijvoorbeeld `condensed_dirt` is, moet het bestand `condensed_dirt.json` heten. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +Blockstaten zijn erg complex en daarom worden ze op een volgende pagina behandeld: [Blockstaten](./blockstates) + +Als je het spel opnieuw start, of herlaadt via F3 + T om wijzigingen toe te passen, zou je de bloktextuur in de inventaris en fysiek in de wereld moeten kunnen zien: + +![Block in world with suitable texture and model](/assets/develop/blocks/first_block_4.png) + +## Blokdrops toevoegen {#adding-block-drops} + +Wanneer je het blok breekt in overleefmodus, zie je misschien dat het blok niet valt. Misschien wil je deze functionaliteit, maar om je blok als een voorwerp te laten vallen, moet je de buittabel implementeren. Het buittabelbestand moet in de map `data/<0>/loot_table/blocks/` worden geplaatst. + +:::info +Voor een beter begrip van buittabellen kun je de pagina [Minecraft Wiki - Buittabellen](https://nl.minecraft.wiki/w/Buittabel) raadplegen. +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +Deze buittabel biedt een eenmalige voorwerpval van het blokvoorwerp wanneer het blok wordt gebroken en wanneer het wordt opgeblazen door een explosie. + +## Een Oogstinstrument Voorstellen {#recommending-a-harvesting-tool} + +Mogelijk wil je ook dat je blok alleen met een specifiek gereedschap kan worden geoogst. Misschien wilt je je blok bijvoorbeeld sneller laten oogsten met een schep. + +Alle gereedschapstags moeten in de map `data/minecraft/tags/block/mineable/` worden geplaatst - waarbij de naam van het bestand afhangt van het type tool dat wordt gebruikt, een van de volgende: + +- `hoe.json` (schoffel) +- `axe.json` (bijl) +- `pickaxe.json` (houweel) +- `shovel.json` (schep) + +De inhoud van het bestand is vrij eenvoudig: het is een lijst met items die aan de tag moeten worden toegevoegd. + +In dit voorbeeld wordt het blok "Condensed Dirt" toegevoegd aan de tag `shovel`. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +Als je wilt dat er een tool nodig is om het blok te breken, kun je `.requiresTool()` toevoegen aan je blokinstellingen, en ook de juiste mining-tag toevoegen. + +## Miningniveaus {#mining-levels} + +Op dezelfde manier kan de tag voor miningniveau worden gevonden in de map `data/minecraft/tags/block/` en respecteert het volgende formaat: + +- `needs_stone_tool.json` - Een minimumniveau aan stenen gereedschap +- `needs_iron_tool.json` - Een minimumniveau aan ijzeren gereedschap +- `needs_diamond_tool.json` - Een minimumniveau aan diamanten gereedschap. + +Het bestand heeft hetzelfde formaat als het oogstinstrumentbestand: een lijst met items die aan de tag moeten worden toegevoegd. + +## Extra Notities {#extra-notes} + +Als je meerdere blokken aan je mod toevoegt, kunt je overwegen om [Data Generatie](https://fabricmc.net/wiki/tutorial:datagen_setup) te gebruiken om het proces van het maken van blok- en voorwerpmodellen, blokstaatdefinities en buittafels te automatiseren. diff --git a/versions/1.21/translated/nl_nl/develop/items/first-item.md b/versions/1.21/translated/nl_nl/develop/items/first-item.md new file mode 100644 index 000000000..7da683c75 --- /dev/null +++ b/versions/1.21/translated/nl_nl/develop/items/first-item.md @@ -0,0 +1,151 @@ +--- +title: Maak Je Eerste Voorwerp +description: Leer hoe je een simpel voorwerp registreert en hoe je textureert, modelleert en een benoemt. +authors: + - IMB11 + - dicedpixels +--- + +# Maak Je Eerste Voorwerp {#creating-your-first-item} + +Op deze pagina maak je kennis met enkele belangrijke concepten met betrekking tot voorwerpen, en hoe je ze kunt registreren, texturen, modelleren en benoemen. + +Als je het nog niet wist: alles in Minecraft wordt opgeslagen in registers, en voorwerpen vormen daarop geen uitzondering. + +## Je Voorwerpen-klasse Voorbereiden {#preparing-your-items-class} + +Om de registratie van items te vereenvoudigen, kunt u een methode maken die een exemplaar van een item en een string-ID accepteert. + +Met deze methode wordt een item gemaakt met de opgegeven identificatie en wordt dit geregistreerd bij het voorwerpregister van het spel. + +Je kunt deze methode het beste in een soort klasse genaamd `ModVoorwerpen` (of wat je het ook wilt noemen) zetten. + +Mojang doet dit ook voor hun voorwerpen! Neem maar eens een kijkje naar de `Items` klasse voor inspiratie. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Het Registreren van een Voorwerp {#registering-an-item} + +Je kunt nu een voorwerp registreren met de methode. + +De voorwerpconstructor neemt een exemplaar van de `Items.Settings` klasse als een parameter. Met deze klasse kun je de eigenschappen van het voorwerp configureren via verschillende bouwermethodes. + +::: tip +If you want to change your item's stack size, you can use the `maxCount` method in the `Items.Settings`/`FabricItemSettings` class. + +Dit werkt niet als je het item als beschadigbaar hebt gemarkeerd, omdat de stapelgrootte voor beschadigbare items altijd 1 is om duplicatie-exploits te voorkomen. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Als je echter in het spel gaat, kun je zien dat ons item niet bestaat! Dit komt omdat u de klasse niet statisch initialiseert. + +Om dit te doen, kunt u een openbare statische initialisatiemethode aan uw klasse toevoegen en deze vanuit uw klasse `ModInitializer` aanroepen. Momenteel heeft deze methode niets nodig. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java) + +Het aanroepen van een methode voor een klasse initialiseert deze statisch als deze nog niet eerder is geladen - dit betekent dat alle `static` velden worden geëvalueerd. Dit is waar de dummy `initialize` voor is. + +## Het Voorwerp Toevoegen aan een Voorwerpgroep {#adding-the-item-to-an-item-group} + +:::info +Als je het item wilt toevoegen aan een aangepaste `ItemGroup`, ga dan naar de pagina [Aangepaste Voorwerpgroepen](./custom-item-groups) voor meer informatie. +::: + +We zullen dit item bijvoorbeeld toevoegen aan de ingrediënten `ItemGroup`, u zult de voorwerpgroepgebeurtenissen van Fabric API moeten gebruiken - met name `ItemGroupEvents.modifyEntriesEvent` + +Dit kan gedaan worden in de `initialize`-methode van uw voorwerpen klasse. + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Als je het spel inlaadt, kun je zien dat ons item is geregistreerd en zich in de voorwerpgroep Ingrediënten bevindt: + +![Item in the ingredients group](/assets/develop/items/first_item_0.png) + +Echter mist het het volgende: + +- Voorwerpmodel +- Textuur +- Vertaling (Naam) + +## Het Voorwerp Benoemen {#naming-the-item} + +Momenteel heeft het voorwerp geen vertaling, dus je zult er een moeten toevoegen. De vertaalsleutel is al door Minecraft verstrekt: `item.mod_id.suspicious_substance`. + +Maak een nieuw JSON-bestand in: `src/main/resources/assets//lang/nl_nl.json` (`en_us.json` voor Engels) en plaats de vertaalsleutel en de waarde ervan: + +```json +{ + "item.mod_id.suspicious_substance": "Suspicious Substance" +} +``` + +Je kunt het spel opnieuw starten of je mod bouwen en op F3 + T drukken om de wijzigingen toe te passen. + +## Een Textuur en Model Toevoegen {#adding-a-texture-and-model} + +Om je voorwerp een ​​textuur en model te geven, maak je eenvoudig een textuurafbeelding van 16x16 pixels voor uw item en slaat u deze op in de map `assets//textures/item`. Geef het textuurbestand dezelfde naam als de ID van het voorwerp, maar met de extensie `.png`. + +Je kunt deze voorbeeldtextuur bijvoorbeeld gebruiken voor `suspicious_substance.png` + + + +Bij het herstarten/herladen van het spel zou je moeten zien dat het voorwerp nog steeds geen textuur heeft, dat komt omdat je een model moet toevoegen dat deze textuur gebruikt. + +Je gaat een eenvoudig `item/generated`-model maken, dat een invoertextuur bevat en niets anders. + +Maak de model-JSON in de map `assets//models/item`, met dezelfde naam als het item; `suspicious_substance.json` + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) + +### Het Model-JSON Afbreken {#breaking-down-the-model-json} + +- `parent`: Dit is het ouder model wat dit model van zal erven. In dit geval is het het `item/generated`-model. +- `textures`: Dit is waar je de texturen voor het model definieert. De `layer0`-sleutel is de textuur wat het voorwerpmodel zal gebruiken. + +De meeste voorwerpen zullen `item/generated` als ouder hebben, omdat het een eenvoudig model is wat alleen maar de textuur weergeeft. + +Er zijn alternatieven, zoals `item/handheld`, wat gebruikt wordt voor voorwerpen die vastgehouden worden in de spelers handen, zoals gereedschappen. + +Je voorwerp moet er nu zo uitzien in het spel: + +![Item with correct model](/assets/develop/items/first_item_2.png) + +## Het Voorwerp Composteerbaar of een Brandstof Maken {#making-the-item-compostable-or-a-fuel} + +Fabric API biedt verschillende registers die kunnen worden gebruikt om extra eigenschappen aan je voorwerp toe te voegen. + +Als je je voorwerp bijvoorbeeld composteerbaar wilt maken, kun je het `CompostableItemRegistry` gebruiken: + +@[code transcludeWith=:::_10](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Als je van je voorwerp een ​​brandstof wilt maken, kun je ook de klasse `FuelRegistry` gebruiken: + +@[code transcludeWith=:::_11](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Een Basisrecept Toevoegen {#adding-a-basic-crafting-recipe} + + + +Als u een recept voor uw item wilt toevoegen, moet u een JSON-receptbestand in de map `data//recipe` plaatsen. + +Voor meer informatie over het receptformaat kunt u deze bronnen raadplegen: + +- [Recept JSON Generator](https://crafting.thedestruc7i0n.ca/) +- [Minecraft Wiki - Recipe JSON](https://minecraft.wiki/w/Recipe#JSON_Format) + +## Aangepaste Tooltips {#custom-tooltips} + +Als je wilt dat je voorwerp een ​​aangepaste tooltip heeft, moet je een klasse maken die `Item` uitbreidt en de methode `appendTooltip` overschrijft. + +:::info +In dit voorbeeld wordt de klasse `LightningStick` gebruikt die is gemaakt op de pagina [Aangepaste Voorwerpinteracties](./custom-item-interactions). +::: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Elke aanroep van `add()` zal één regel aan de tooltip toevoegen. + +![Tooltip Showcase](/assets/develop/items/first_item_3.png) diff --git a/versions/1.21/translated/nl_nl/players/updating-fabric.md b/versions/1.21/translated/nl_nl/players/updating-fabric.md new file mode 100644 index 000000000..46b2d87a1 --- /dev/null +++ b/versions/1.21/translated/nl_nl/players/updating-fabric.md @@ -0,0 +1,43 @@ +--- +title: Fabric updaten +description: Een stap voor stap instructie voor het updaten van fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Fabric Updaten{#updating-fabric} + +Deze gids begeleidt u bij het updaten van Fabric voor de Minecraft Launcher. + +Voor externe launchers dient u hun documentatie te raadplegen. + +Het updaten van Fabric lijkt sterk op het installeren van Fabric, dus delen van deze handleiding zullen hetzelfde zijn als de handleiding [Installing Fabric](./installing-fabric). + +## Waarom Zou Ik Fabric Updaten? {#why-should-i-update-fabric-loader} + +Nieuwere mods hebben misschien een nieuwere versie van de Fabric Loader nodig om te werken, het is dus belangerijk om het up to date te houden om ervoor te zorgen dat je de nieuwste mods kan gebruiken. + + + + + +Om Fabric te updaten, moet je ervoor zorgen dat de spel versie en Fabric Loader versie correct is, en dat op `Install` te klikken. + +:::warning BELANGRIJK +Zorg ervoor dat je 'Create Profile' niet aanvinkt wanneer je de Installer gebruikt, anders maakt het een nieuw profiel aan, dat wij in dit geval niet nodig hebben. +::: + +## 3. Open het Profiel in de Minecraft Launcher {#3-open-the-profile-in-the-minecraft-launcher} + +Wanneer de installer klaar is, kan je de Minecraft launcher openen en naar de `installaties` tab gaan. Je moet naar je Fabrc Profile gaan en dat het edit scherm openen. + +Vervan de oude versie met de nieuwste versie van de Fabric Loader die je net heb geinstalleerd en klik op `Save`. + +![Fabric updaten in de Minecraft Launcher](/assets/players/updating-fabric.png) + +## 4. Je bent klaar! {#4-you-re-done} + +Wanneer je de stappen hebt voltooid, kan je terug gaan naar het `Spelen` tab, selecteer het Fabric profiel van het menu in de onderste linker hoek en klik op speel! + +Als je problemen tegenkomt terwijl je deze gids volgt, dan kan je voor hulp vragen in de [Fabric Discord](https://discord.gg/v6v4pMv) in het `#player-support` kanaal. diff --git a/versions/1.21/translated/nl_nl/sidebar_translations.json b/versions/1.21/translated/nl_nl/sidebar_translations.json new file mode 100644 index 000000000..df7933e72 --- /dev/null +++ b/versions/1.21/translated/nl_nl/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "Gebruikershandleidingen", + "players.faq": "Veelgestelde Vragen", + "players.installingJava": "Java installeren", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Fabric Installeren", + "players.findingMods": "Betrouwbare Mods Vinden", + "players.installingMods": "Mods Installeren", + "players.troubleshooting": "Problemen oplossen", + "players.troubleshooting.uploadingLogs": "Je Logs Uploaden", + "players.troubleshooting.crashReports": "Crashrapporten", + "players.updatingFabric": "Fabric Updaten", + "develop.title": "Ontwikkelaarshandleidingen", + "develop.gettingStarted": "Om Te Beginnen", + "develop.gettingStarted.introduction": "Introductie Tot Fabric En Modden", + "develop.gettingStarted.devEnvSetup": "Je Ontwikkelingsomgeving Opzetten", + "develop.gettingStarted.creatingProject": "Een Project Aanmaken", + "develop.gettingStarted.projectStructure": "Projectstructuur", + "develop.gettingStarted.launchGame": "Je Game Starten", + "develop.gettingStarted.solvingProblems": "Fundamentele Probleemoplossing", + "develop.items": "Voorwerpen", + "develop.items.first-item": "Maak Je Eerste Blok", + "develop.items.food": "Voedselitems", + "develop.items.custom-armor": "Aangepast Pantser", + "develop.items.custom-tools": "Aangepast Gereedschap", + "develop.items.custom-item-groups": "Aangepaste Voorwerpgroepen", + "develop.items.custom-item-interactions": "Aangepaste Voorwerpinteracties", + "develop.items.potions": "Drankjes", + "develop.items.custom-data-components": "Aangepaste Data-componenten", + "develop.blocks": "Blokken", + "develop.blocks.first-block": "Maak Je Eerste Blok", + "develop.blocks.blockstates": "Blokstaten", + "develop.entities": "Entiteiten", + "develop.entities.effects": "Statuseffecten", + "develop.entities.damage-types": "Schadesoorten", + "develop.commands": "Commando's", + "develop.commands.basics": "Commando's Maken", + "develop.commands.arguments": "Argumenten", + "develop.commands.suggestions": "Suggesties", + "develop.rendering": "Weergave", + "develop.rendering.basicConcepts": "Basis Weergaveconcepten", + "develop.rendering.drawContext": "De Tekencontext Gebruiken", + "develop.rendering.hud": "Weergave In De Hud", + "develop.rendering.gui": "GUIs en Schermen", + "develop.rendering.gui.customScreens": "Zelfgemaakte Schermen", + "develop.rendering.gui.customWidgets": "Zelfgemaakte Widgets", + "develop.rendering.particles": "Deeltjes", + "develop.rendering.particles.creatingParticles": "Deeltjes Zelf Maken", + "develop.misc": "Andere Pagina's", + "develop.misc.codecs": "Codecs", + "develop.misc.events": "Gebeurtenissen", + "develop.misc.text-and-translations": "Tekst en Translatie", + "develop.misc.ideTipsAndTricks": "IDE Tips en Tricks", + "develop.misc.automatic-testing": "Geautomatiseerd Testen", + "develop.sounds": "Geluiden", + "develop.sounds.using-sounds": "Geluiden Afspelen", + "develop.sounds.custom": "Geluiden Zelf Maken" +} diff --git a/versions/1.21/translated/pl_pl/contributing.md b/versions/1.21/translated/pl_pl/contributing.md new file mode 100644 index 000000000..641ef6940 --- /dev/null +++ b/versions/1.21/translated/pl_pl/contributing.md @@ -0,0 +1,253 @@ +--- +title: Wytyczne współtworzenia +description: Wytyczne dotyczące współtworzenia i wnoszenia wkładu do dokumentacji Fabric. +--- + +# Wytyczne współtworzenia {#contributing} + +Ta strona używa [VitePress](https://vitepress.dev/) do generowania statycznego HTML-a z różnych plików Markdown. Warto zapoznać się z rozszerzeniami Markdown, które obsługuje VitePress, [tutaj](https://vitepress.dev/guide/markdown.html#features). + +Istnieją trzy sposoby, w jakie możesz pomóc współtworzyć tę stronę: + +- [Tłumaczenie dokumentacji](#translating-documentation) +- [Współtworzenie treści](#contributing-content) +- [Współtworzenie frameworka](#contributing-framework) + +Wszystkie współtworzone treści i wniesiony wkład muszą być zgodne z naszymi [wytycznymi dotyczącymi stylu](#style-guidelines). + +## Tłumaczenie dokumentacji {#translating-documentation} + +Jeśli chcesz przetłumaczyć dokumentację na swój język, możesz to zrobić dołączając do projektu [Fabric na platformie Crowdin](https://crowdin.com/project/fabricmc). + + + +## new-content Współtworzenie treści {#contributing-content} + +Tworzenie nowych treści jest głównym sposobem na przyczynienie się do rozwoju dokumentacji Fabric. + +Wszystkie nowe współtworzone treści przechodzą przez następujące etapy, z których każdy jest powiązany z etykietą: + +1. lokalnie Przygotuj swoje zmiany i utwórz PR +2. stage:expansion: Pomoc w rozbudowie treści (w razie potrzeby) +3. stage:verification: Weryfikowanie treści +4. stage:cleanup: Sprawdzanie gramatyki, błędów itp. +5. stage:ready: Gotowe do wdrożenia! + +Wszystkie treści muszą być zgodne z naszymi [wytycznymi dotyczącymi stylu](#style-guidelines). + +### 1. Przygotuj swoje zmiany {#1-prepare-your-changes} + +Ta strona jest open-source i rozwijana jest w repozytorium na GitHubie, co oznacza, że polegamy na GitHubowym schemacie pracy: + +1. [Sforkuj repozytorium GitHub](https://github.com/FabricMC/fabric-docs/fork) +2. Stwórz nową gałąź w swoim forku +3. Wprowadź zmiany na tej gałęzi +4. Utwórz Pull Request w oryginalnym repozytorium + +Więcej informacji o GitHubowym schemacie pracy znajdziesz [tutaj](https://docs.github.com/en/get-started/using-github/github-flow). + +Zmiany możesz wprowadzać bezpośrednio z interfejsu internetowego na GitHubie lub lokalnie edytować i podglądać zmiany na stronie. + +#### Klonowanie swojego forka {#clone-your-fork} + +Jeśli chcesz wprowadzać zmiany lokalnie, będzie ci potrzebny [Git](https://git-scm.com/). + +Po jego zainstalowaniu sklonuj swoje sforkowane repozytorium za pomocą: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### Instalowanie zależności {#install-dependencies} + +Jeśli chcesz lokalnie podglądać swoje zmiany na stronie, będzie ci potrzebny [Node.js 18+](https://nodejs.org/en/). + +Po jego zainstalowaniu zainstaluj wszystkie wymagane zależności za pomocą: + +```sh +npm install +``` + +#### Uruchamianie serwera deweloperskiego {#run-the-development-server} + +Serwer ten pozwala na podglądanie w czasie rzeczywistym wprowadzonych zmian lokalnie pod adresem `localhost:5173`, automatycznie przeładowując stronę po wprowadzeniu zmian. Uruchamia się go za pomocą: + +```sh +npm run dev +``` + +Teraz możesz otworzyć i przeglądać stronę z przeglądarki, odwiedzając `http://localhost:5173`. + +#### Budowanie strony {#building-the-website} + +Spowoduje to skompilowanie wszystkich plików Markdown do statycznych plików HTML i umieszczenie ich w `.vitepress/dist`. + +```sh +npm run build +``` + +#### Podglądanie zbudowanej strony {#previewing-the-built-website} + +Spowoduje to uruchomienie lokalnego serwera na porcie `4173` wyświetlającego zawartość znajdującą się w `.vitepress/dist`. + +```sh +npm run preview +``` + +#### Tworzenie Pull Requesta {#opening-a-pull-request} + +Po wprowadzeniu odpowiednich zmian możesz je s`push`ować za pomocą: + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +Następnie, aby utworzyć PR, otwórz link wyświetlony w wyniku polecenia `git push`. + +### 2. stage:expansion Pomoc w rozbudowie treści {#2-guidance-for-expansion-if-needed} + +Jeśli nasz zespół od dokumentacji uzna, że twój PR można rozbudować, członek zespołu doda do niego etykietę stage:expansion wraz z komentarzem wyjaśniającym, co mogłoby zostać rozbudowane. Jeśli się zgadasz z podanymi sugestiami, możesz rozbudować swój PR. + +Jeśli nie chcesz rozbudowywać swojego PR, ale chcesz, aby zrobił to ktoś inny w późniejszym terminie, musisz utworzyć zgłoszenie w [zakładce „Issues”](https://github.com/FabricMC/fabric-docs/issues) i wyjaśnić, co mogłoby zostać rozbudowane. Nasz zespół od dokumentacji doda następnie do twojego PR etykietę help-wanted. + +### 3. stage:verification Weryfikowanie treści {#3-content-verification} + +Jest to najważniejszy etap, ponieważ zapewnia, że treść jest poprawna i zgodna z wytycznymi dokumentacji Fabric dotyczącymi stylu. + +Na tym etapie należy odpowiedzieć na następujące pytania: + +- Czy wszystkie treści są poprawne? +- Czy wszystkie treści są aktualne? +- Czy treść obejmuje wszystkie przypadki, takie jak różne systemy operacyjne? + +### 4. stage:cleanup Porządkowanie {#4-cleanup} + +Na tym etapie wykonuje się następujące czynności: + +- Poprawianie wszelkich błędów gramatycznych za pomocą [LanguageTool](https://languagetool.org/) +- Analizowanie (linting) pod kątem potencjalnych błędów wszystkich plików Markdown za pomocą [`markdownlint`](https://github.com/DavidAnson/markdownlint) +- Formatowanie całego kodu Java za pomocą [Checkstyle](https://checkstyle.sourceforge.io/) +- Inne drobne poprawki lub ulepszenia + +## framework Współtworzenie frameworka {#contributing-framework} + +Framework odnosi się do wewnętrznej struktury strony. Wszelkie pull requesty, które go modyfikują będą oznaczone etykietą framework. + +Pull requesty dotyczące frameworka należy tworzyć wyłącznie po konsultacji z zespołem od dokumentacji na [Discordzie Fabric](https://discord.gg/v6v4pMv) lub za pośrednictwem zgłoszenia. + +:::info +Modyfikowanie plików paska bocznego i konfiguracji paska nawigacyjnego nie jest zaliczane jako pull request dotyczący frameworka. +::: + +## Wytyczne dotyczące stylu {#style-guidelines} + +Jeśli nie masz pewności co do czegokolwiek, możesz zapytać na [Discordzie Fabric](https://discord.gg/v6v4pMv) lub za pośrednictwem dyskusji na GitHubie. + +### Pisz wszystko w amerykańskim angielskim {#write-the-original-in-american-english} + +Cała oryginalna dokumentacja jest napisana w języku angielskim, zgodnie z amerykańskimi zasadami gramatyki. + +### Dodaj metadane do strony {#add-data-to-the-frontmatter} + +Każda strona musi zawierać tytuł (`title`) oraz opis (`description`) w segmencie nazywanym Frontmatter, który znajduje się na początku pliku. + +Pamiętaj również dodać swoją nazwę użytkownika na GitHubie w polu `authors`! W ten sposób będziemy mogli przyznać Ci należne wyróżnienie. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### Dodaj zakotwiczenia do nagłówków {#add-anchors-to-headings} + +Każdy nagłówek być zakotwiczony, aby można było go zlinkować: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +Zakotwiczenie może składać się tylko z małych liter, myślników i cyfr. + +### Umieść kod w modzie `/reference` {#place-code-within-the-reference-mod} + +Jeśli tworzysz lub modyfikujesz strony zawierające kod, umieść kod w odpowiednim miejscu w modzie referencyjnym (znajdującym się w folderze `/reference` repozytorium). Następnie użyj funkcji [importowania fragmentów kodu oferowanej przez VitePress](https://vitepress.dev/guide/markdown#import-code-snippets), aby osadzić kod. + +Na przykład, aby wyróżnić linie 15-21 pliku `FabricDocsReference.java` z moda referencyjnego, użyj: + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +Jeśli potrzebujesz większej kontroli, możesz użyć [funkcji transkluzji z `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + +Dla przykładu ten kod osadzi sekcje powyższego pliku, które są oznaczone tagiem `#entrypoint`: + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### Utwórz pasek boczny dla każdej nowej sekcji {#create-a-sidebar-for-each-new-section} + +Jeśli tworzysz nową sekcję musisz stworzyć dla niej nowy pasek boczny w folderze `.vitepress/sidebars` i dodać go do pliku `i18n.mts`. + +Jeśli potrzebujesz z tym pomocy, zapytaj na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#docs`. + +### Dodaj nowe strony do odpowiednich pasków bocznych {#add-new-pages-to-the-relevant-sidebars} + +Podczas tworzenia nowej strony należy dodać ją do odpowiedniego paska bocznego w folderze `.vitepress/sidebars`. + +Jeśli potrzebujesz z tym pomocy, zapytaj na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#docs`. + +### Umieść multimedia w folderze `/assets` {#place-media-in-assets} + +Wszelkie obrazy powinny zostać umieszczone w odpowiednim miejscu w folderze `/public/assets`. + +### Używaj linków względnych! {#use-relative-links} + +Powodem tego jest istniejący system wersjonowania, który przetwarza linki, dodając na początku numer wersji. Jeśli użyjesz linku bezwzględnego, numer wersji nie zostanie do niego dodany. + +Nie należy również dodawać rozszerzenia pliku do linku. + +Na przykład, aby utworzyć link do strony znajdującej się w `/players/index.md` ze strony `/develop/index.md`, należy zrobić to w następujący sposób: + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/pl_pl/develop/index.md b/versions/1.21/translated/pl_pl/develop/index.md new file mode 100644 index 000000000..a59fac118 --- /dev/null +++ b/versions/1.21/translated/pl_pl/develop/index.md @@ -0,0 +1,12 @@ +--- +title: Przewodniki dla deweloperów +description: Nasze napisane przez społeczność przewodniki dla deweloperów, obejmują wszystko — od konfiguracji środowiska programistycznego po zaawansowane tematy takie jak renderowanie i networking. +--- + +# Przewodniki dla deweloperów {#developer-guides} + +Napisane przez społeczność przewodniki dla deweloperów, obejmują wszystko — od konfiguracji środowiska programistycznego po bardziej zaawansowane obszary takie jak renderowanie i networking. + +Listę wszystkich dostępnych przewodników znajdziesz na pasku bocznym. Jeśli szukasz czegoś konkretnego, możesz skorzystać z paska wyszukiwania znajdującego się na górze strony. + +Jeśli chcesz przyczynić się do polepszenia dokumentacji Fabric to jej pełny kod źródłowy znajdziesz na [GitHubie](https://github.com/FabricMC/fabric-docs). Sprawdź również [wytyczne dotyczące współtworzenia](../contributing). diff --git a/versions/1.21/translated/pl_pl/index.md b/versions/1.21/translated/pl_pl/index.md new file mode 100644 index 000000000..c858f806b --- /dev/null +++ b/versions/1.21/translated/pl_pl/index.md @@ -0,0 +1,21 @@ +--- +title: Dokumentacja Fabric +description: Oficjalna dokumentacja Fabric — zestawu narzędzi do modowania Minecrafta. +layout: home +hero: + name: Dokumentacja Fabric + tagline: Oficjalna dokumentacja Fabric — zestawu narzędzi do modowania Minecrafta. +features: + - title: Przewodniki dla graczy + icon: 📚 + details: Jesteś graczem, który chce korzystać z modów opartych na Fabric? Nasze przewodniki dla graczy mają wszystko, czego potrzebujesz. Pomogą ci one w pobieraniu, instalowaniu i rozwiązywaniu problemów z modami Fabric. + link: /pl_pl/players/ + linkText: Więcej informacji + - title: Przewodniki dla deweloperów + icon: 🛠️ + details: Nasze napisane przez społeczność przewodniki dla deweloperów, obejmują wszystko — od konfiguracji środowiska programistycznego po zaawansowane tematy takie jak renderowanie i networking. + link: /pl_pl/develop/ + linkText: Rozpocznij +--- + +Jeśli chcesz przyczynić się do polepszenia dokumentacji Fabric to jej pełny kod źródłowy znajdziesz na [GitHubie](https://github.com/FabricMC/fabric-docs). Sprawdź również [wytyczne dotyczące współtworzenia](./contributing). diff --git a/versions/1.21/translated/pl_pl/players/faq.md b/versions/1.21/translated/pl_pl/players/faq.md new file mode 100644 index 000000000..1155d3acb --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Często zadawane pytania dla graczy +description: Często zadawane pytania dla graczy i administratorów serwerów dotyczące Fabric. +--- + +# Często zadawane pytania {#faq} + +Istnieje wiele często zadawanych pytań, więc zebraliśmy je tutaj w listę. + +## Jakie wersje Minecrafta obsługuje Fabric? {#what-minecraft-versions-does-fabric-support} + +Oficjalnie, Fabric obsługuje wszystkie wersje Minecraft począwszy od snapshota `18w43b` i nowsze oraz od wersji `1.14` i nowsze. + +## Skąd mogę pobrać mody do Fabric? {#where-can-i-download-published-fabric-mods} + +:::info +Upewniaj się zawsze czy mody pochodzą z wiarygodnego źródła. Po więcej informacji sprawdź przewodnik na temat [znajdowania wiarygodnych modów](./finding-mods). +::: + +Większość twórców publikuje swoje mody na [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) i [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4), niektórzy mogą jednak zdecydować się na opublikowanie ich na swojej własnej stronie internetowej lub innych platformach, takich jak repozytorium GitHub. + +## Gdzie mogę znaleźć gotowe paczki modów dla Fabric? {#where-can-i-find-premade-fabric-modpacks} + +Gotowe paczki modów dla Fabric znajdziesz na różnych platformach, takich jak: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/pl_pl/players/finding-mods.md b/versions/1.21/translated/pl_pl/players/finding-mods.md new file mode 100644 index 000000000..0e3204458 --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Znajdowanie wiarygodnych modów +description: Przewodnik na temat znajdowania modów do Fabric przy użyciu wiarygodnych źródeł. +authors: + - IMB11 +--- + +# Znajdowanie wiarygodnych modów {#finding-mods} + +Na wstępie warto wspomnieć, że zaufanie jest subiektywne, dlatego zawsze należy kierować się własnym rozsądkiem podczas pobierania modów. Jest jednak kilka rzeczy, które możesz zrobić, aby znaleźć wiarygodne mody. + +## 1. Korzystaj ze źródła, które jest powszechnie uznane za wiarygodne {#trustworthy-source} + +Większość twórców publikuje swoje mody na [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) i [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4). + +Strony te sprawdzają, czy mody są tym, za co się podają i czy nie zawierają żadnego złośliwego kodu. Możesz również zgłaszać szkodliwe mody na tych stronach, a one podejmą działania stosunkowo szybko. + +## 2. Pytaj innych! {#with-others} + +Jeśli pobierasz mody ze źródła, które nie jest znane i uznane za wiarygodne, warto spytać innych, czy pobierali już jakieś mody z tej strony i czy mieli z nimi jakiekolwiek problemy. + +W razie wątpliwości zachęcamy do zadawania pytań na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support`. + +## 3. Unikaj znanych szkodliwych stron! {#avoid-malware} + +:::info +Szkodliwe strony mogą nie być oczywiste dla każdego. Jeśli nie masz pewności, spytaj się innych o opinię lub całkowicie unikaj tej strony i polegaj na wiarygodnych źródłach, takich jak Modrinth i CurseForge. +::: + +Jest wiele stron, które twierdzi, że oferuje mody do Minecrafta, choć tak naprawdę zawiera szkodliwe oprogramowanie. Należy ich unikać za wszelką cenę. + +Do sprawdzenia pobranych modów możesz wykorzystać oprogramowanie antywirusowe, takie jak [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) lub strony, takie jak [VirusTotal](https://www.virustotal.com/). Nie należy jednak polegać wyłącznie na tych metodach, ponieważ czasami mogą one być nieprawidłowe. + +Ponownie, jeśli masz jakiekolwiek wątpliwości, możesz spytać się innych o opinię na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support`. diff --git a/versions/1.21/translated/pl_pl/players/index.md b/versions/1.21/translated/pl_pl/players/index.md new file mode 100644 index 000000000..f7e130f5b --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/index.md @@ -0,0 +1,12 @@ +--- +title: Przewodniki dla graczy +description: Zbiór przewodników dla graczy i administratorów serwerów na temat instalowania i korzystania z Fabric. +--- + +# Przewodniki dla graczy {#player-guides} + +Ta sekcja dokumentacji Fabric jest przeznaczona dla graczy i administratorów serwerów, którzy chcą się nauczyć jak zainstalować i korzystać z Fabric, a także rozwiązywać związane z nim problemy. + +Listę wszystkich dostępnych przewodników znajdziesz na pasku bocznym. + +Jeśli napotkasz jakiś problem, zgłoś go na [GitHubie](https://github.com/FabricMC/fabric-docs) lub poproś o pomoc na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support` albo `#server-admin-support`. diff --git a/versions/1.21/translated/pl_pl/players/installing-fabric.md b/versions/1.21/translated/pl_pl/players/installing-fabric.md new file mode 100644 index 000000000..cb3a2cffa --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/installing-fabric.md @@ -0,0 +1,55 @@ +--- +title: Instalowanie Fabric +description: Przewodnik krok po kroku o tym, jak zainstalować Fabric. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Instalowanie Fabric {#installing-fabric} + +Ten przewodnik pokaże ci, jak zainstalować Fabric dla oficjalnego launchera Minecrafta. + +W przypadku innych launcherów należy zapoznać się z ich dokumentacją. + +## 1. Pobierz instalator Fabric {#1-download-the-fabric-installer} + +Instalator Fabric możesz pobrać ze [strony Fabric](https://fabricmc.net/use/). + +Jeśli korzystasz z systemu Windows, pobierz wersję `.exe` (`Download for Windows`), ponieważ nie wymaga ona posiadania zainstalowanej Javy. Zamiast tego wykorzystuje Javę, która jest dołączona w oficjalnym launcherze. + +W przypadku systemów macOS i Linux należy pobrać wersję `.jar`. Czasami przed wykonaniem tego kroku konieczne jest zainstalowanie Javy. + +## 2. Uruchom instalator Fabric {#2-run-the-fabric-installer} + +:::warning +Przed instalacją należy zamknąć Minecrafta, jak i jego launcher. +::: + +:::details Informacja dla użytkowników systemu macOS + +Na systemie macOS do uruchomienia pliku `.jar` może być konieczne kliknięcie go prawym przyciskiem myszy, a następnie wybranie opcji `Otwórz`. + +![Menu kontekstowe macOS z instalatorem Fabric](/assets/players/installing-fabric/macos-downloads.png) + +Gdy pojawi się komunikat „Czy na pewno chcesz otworzyć ten plik?”, ponownie kliknij `Otwórz`. +::: + +Po otworzeniu instalatora powinno pojawić się takie okno: + +![Instalator Fabric z wyróżnionym tekstem „Zainstaluj”](/assets/players/installing-fabric/installer-screen.png) + +Aby zainstalować Fabric, wystarczy po prostu wybrać wersję gry z rozwijanej listy i kliknąć `Zainstaluj`. + +**Upewnij się, że opcja `Utwórz profil` jest zaznaczona.** + +## 3. I to tyle! {#3-you-re-done} + +Po zakończeniu instalacji możesz otworzyć launcher Minecrafta i wybrać z rozwijanej listy w lewym dolnym rogu profil Fabric, a następnie zacząć grać! + +![Launcher Minecrafta z wybranym profilem Fabric](/assets/players/installing-fabric/launcher-screen.png) + +Teraz, po zainstalowaniu Fabric możesz dodawać mody do swojej gry! Po więcej informacji sprawdź przewodnik na temat [znajdowania wiarygodnych modów](./finding-mods). + +Jeśli napotkasz jakiś problem podczas korzystania z tego przewodnika, możesz poprosić o pomoc na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support`. diff --git a/versions/1.21/translated/pl_pl/players/installing-java/linux.md b/versions/1.21/translated/pl_pl/players/installing-java/linux.md new file mode 100644 index 000000000..8327198a6 --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Instalowanie oprogramowania Java na Linux +description: Przewodnik krok po kroku o tym, jak zainstalować oprogramowanie Java na Linux. +authors: + - IMB11 +--- + +# Instalowanie oprogramowania Java na Linux {#installing-java-on-linux} + +Ten przewodnik pokaże ci, jak zainstalować Javę 21 na systemie Linux. + +## 1. Sprawdź, czy nie masz już zainstalowanej Javy {#1-check-if-java-is-already-installed} + +Otwórz terminal, wpisz `java -version` i naciśnij Enter. + +![Terminal z wpisanym poleceniem "java -version"](/assets/players/installing-java/linux-java-version.png) + +:::warning +Aby używać Minecrafta w wersji 1.21, musisz mieć zainstalowaną co najmniej Javę 21. Jeśli to polecenie wyświetla wersję mniejszą niż 21, wymagane będzie zaktualizowanie istniejącej instalacji Javy. +::: + +## 2. Pobieranie i instalowanie Javy 21 {#2-downloading-and-installing-java} + +Zalecamy wykorzystanie OpenJDK 21, który jest dostępny dla większości dystrybucji systemu Linux. + +### Arch Linux {#arch-linux} + +:::info +Więcej informacji na temat instalowania Javy na systemie Linux Arch, znajdziesz na [Arch Linux Wiki](https://wiki.archlinux.org/title/Java). +::: + +Najnowszą wersję środowiska JRE możesz zainstalować z oficjalnych repozytoriów: + +```sh +sudo pacman -S jre-openjdk +``` + +Jeśli prowadzisz serwer bez potrzeby korzystania z interfejsu graficznego, możesz zainstalować wersję headless (bez interfejsu graficznego): + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Natomiast jeśli planujesz tworzyć mody, będzie ci potrzebny JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu {#debian-ubuntu} + +Możesz zainstalować Javę 21 przy użyciu `apt` następującymi poleceniami: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora {#fedora} + +Możesz zainstalować Javę 21 przy użyciu `dnf` następującymi poleceniami: + +```sh +sudo dnf install java-21-openjdk +``` + +Jeśli nie potrzebujesz interfejsu graficznego, możesz zainstalować wersję headless (bez interfejsu graficznego): + +```sh +sudo dnf install java-21-openjdk-headless +``` + +Natomiast jeśli planujesz tworzyć mody, będzie ci potrzebny JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Inne dystrybucje systemu Linux {#other-linux-distributions} + +Jeśli twoja dystrybucja nie jest wymieniona powyżej, możesz pobrać najnowszą wersję środowiska JRE ze strony [Adoptium](https://adoptium.net/temurin/) + +Jeśli planujesz tworzyć mody, zapoznaj się z alternatywnym przewodnikiem dla swojej dystrybucji. + +## 3. Zweryfikuj czy Java 21 została zainstalowana {#3-verify-that-java-is-installed} + +Po zakończeniu instalacji możesz zweryfikować czy Java 21 została zainstalowana, otwierając terminal i wpisując `java -version`. + +Jeśli polecenie zostanie uruchomione pomyślnie, to zobaczysz coś takiego, gdzie wyświetlana jest wersja Javy: + +![Terminal z wpisanym poleceniem "java -version"](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/pl_pl/players/installing-java/windows.md b/versions/1.21/translated/pl_pl/players/installing-java/windows.md new file mode 100644 index 000000000..c965dbebc --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Instalowanie oprogramowania Java na Windows +description: Przewodnik krok po kroku o tym, jak zainstalować oprogramowanie Java na Windows. +authors: + - IMB11 +--- + +# Instalowanie oprogramowania Java na Windows {#installing-java-on-windows} + +Ten przewodnik pokaże ci, jak zainstalować Javę 21 na systemie Windows. + +Launcher Minecrafta zawiera własną instalację Javy, więc ta sekcja jest istotna tylko, jeśli chcesz użyć instalatora Fabric w formacie `.jar` lub jeśli chcesz użyć pliku `.jar` serwera Minecraft. + +## 1. Sprawdź, czy nie masz już zainstalowanej Javy {#1-check-if-java-is-already-installed} + +Aby sprawdzić, czy masz już zainstalowaną Javę, musisz najpierw otworzyć wiersz poleceń. + +Możesz to zrobić poprzez wciśnięcie klawiszy Win + R i wpisanie `cmd.exe` w wyświetlonym oknie. + +![Okno dialogowe Uruchamiania w systemie Windows z wpisanym tekstem "cmd.exe" w pasku uruchamiania](/assets/players/installing-java/windows-run-dialog.png) + +Po otwarciu wiersza poleceń wpisz `java -version` i naciśnij Enter. + +Jeśli polecenie zostanie wykonane pomyślnie, to zobaczysz coś takiego. Jeśli polecenie się nie powiodło, przejdź do następnego kroku. + +![Wiersz poleceń z wpisanym poleceniem "java -version"](/assets/players/installing-java/windows-java-version.png) + +:::warning +Aby używać Minecrafta w wersji 1.21, musisz mieć zainstalowaną co najmniej Javę 21. Jeśli to polecenie wyświetla wersję mniejszą niż 21, wymagane będzie zaktualizowanie istniejącej instalacji Javy. +::: + +## 2. Pobierz instalator Javy 21 {#2-download-the-java-installer} + +Do zainstalowania Javy 21 wymagane jest pobranie instalatora ze strony [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21). + +Pobierz wersję `Windows Installer (.msi)`: + +![Strona pobierania Adoptium z wyróżnioną wersją Windows Installer (.msi)](/assets/players/installing-java/windows-download-java.png) + +Jeśli masz 32-bitowy system operacyjny wybierz `x86`, natomiast jeśli masz 64-bitowy system wybierz `x64`. + +Większość nowoczesnych komputerów posiada 64-bitowy system operacyjny. Jeśli nie masz pewności, spróbuj pobrać wersję 64-bitową. + +## 3. Uruchom instalator! {#3-run-the-installer} + +Aby zainstalować Javę 21, postępuj zgodnie z instrukcjami w instalatorze. Gdy dotrzesz do tej strony, ustaw następujące funkcje na "Cała funkcja zostanie zainstalowana na lokalnym dysku twardym": + +- `Set JAVA_HOME environment variable` - zostanie to dodane do PATH. +- `JavaSoft (Oracle) registry keys` + +![Instalator Javy 21 wyróżnionymi polami "Set JAVA\_HOME variable" i "JavaSoft (Oracle) registry keys"](/assets/players/installing-java/windows-wizard-screenshot.png) + +Po zrobieniu tego kliknij `Next` i kontynuuj instalację. + +## 4. Zweryfikuj czy Java 21 została zainstalowana {#4-verify-that-java-is-installed} + +Po zakończeniu instalacji możesz zweryfikować czy Java 21 została zainstalowana, ponownie otwierając wiersz poleceń i wpisując `java -version`. + +Jeśli polecenie zostanie uruchomione pomyślnie, to zobaczysz coś takiego, gdzie wyświetlana jest wersja Javy: + +![Wiersz poleceń z wpisanym poleceniem "java -version"](/assets/players/installing-java/windows-java-version.png) + +--- + +Jeśli napotkasz jakiś problem, śmiało możesz poprosić o pomoc na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support`. diff --git a/versions/1.21/translated/pl_pl/players/installing-mods.md b/versions/1.21/translated/pl_pl/players/installing-mods.md new file mode 100644 index 000000000..e01a23db2 --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Instalowanie modów +description: Przewodnik krok po kroku o tym, jak zainstalować mody do Fabric. +authors: + - IMB11 +--- + +# Instalowanie modów {#installing-mods} + +Ten przewodnik pokaże ci, jak zainstalować mody do Fabric dla oficjalnego launchera Minecrafta. + +W przypadku innych launcherów należy zapoznać się z ich dokumentacją. + +## 1. Pobierz moda {#1-download-the-mod} + +:::warning +Mody należy pobierać wyłącznie z zaufanych źródeł. Po więcej informacji sprawdź przewodnik na temat [znajdowania wiarygodnych modów](./finding-mods). +::: + +Większość modów wymaga również Fabric API, które można pobrać z [Modrinth](https://modrinth.com/mod/fabric-api) lub [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +Podczas pobierania modów upewnij się, że: + +- Działają na wersji Minecrafta, na której chcesz grać. Dla przykładu mod działający na wersji 1.20 może nie działać na wersji 1.20.2. +- Są przeznaczone dla Fabric, a nie innego mod loadera. +- Są przeznaczone dla właściwej edycji Minecrafta (Java Edition). + +## 2. Przenieś moda do folderu `mods` {#2-move-the-mod-to-the-mods-folder} + +Folder `mods` znajdziesz w następujących lokalizacjach dla poszczególnych systemów operacyjnych. + +Zazwyczaj możesz wkleić te ścieżki do paska adresu swojego eksploratora plików, aby szybko przejść do folderu. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Po znalezieniu folderu `mods`, przenieś do niego pliki `.jar` modów. + +![Zainstalowane mody w folderze mods](/assets/players/installing-mods.png) + +## 3. I to tyle! {#3-you-re-done} + +Po przeniesieniu modów do folderu `mods` możesz otworzyć launcher Minecrafta i wybrać z rozwijanej listy w lewym dolnym rogu profil Fabric, a następnie zacząć grać! + +![Launcher Minecrafta z wybranym profilem Fabric](/assets/players/installing-fabric/launcher-screen.png) + +## Rozwiązywanie problemów {#troubleshooting} + +Jeśli napotkasz jakiś problem podczas korzystania z tego przewodnika, możesz poprosić o pomoc na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support`. + +Możesz również spróbować samodzielnie rozwiązać problem, czytając strony poświęcone rozwiązywaniu problemów: + +- [Raporty awarii](./troubleshooting/crash-reports) +- [Przesyłanie logów](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/pl_pl/players/troubleshooting/crash-reports.md b/versions/1.21/translated/pl_pl/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..a6622bc7e --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: Raporty awarii +description: Dowiedz się, co robić z raportami awarii i jak je odczytywać. +authors: + - IMB11 +--- + +# Raporty awarii {#crash-reports} + +:::tip +Jeśli masz jakiekolwiek problemy ze znalezieniem przyczyny awarii, możesz poprosić o pomoc na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support` lub `#server-admin-support`. +::: + +Raporty awarii są bardzo ważną częścią rozwiązywania problemów z grą lub serwerem. Zawierają one dużo informacji na temat awarii i mogą pomóc w ustaleniu jej przyczyny. + +## Znajdowanie raportów awarii {#finding-crash-reports} + +Raporty awarii są przechowywane w folderze `crash-reports` w katalogu gry. W przypadku serwera przechowywane są w folderze `crash-reports` w katalogu serwera. + +W przypadku innych launcherów należy zapoznać się z ich dokumentacją, aby wiedzieć, gdzie znaleźć raporty awarii. + +Raporty awarii znajdziesz w następujących lokalizacjach: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Odczytywanie raportów awarii {#reading-crash-reports} + +Raporty awarii są bardzo długie i potrafią być skomplikowane do odczytania. Zawierają one jednak dużo informacji na temat awarii i mogą pomóc w ustaleniu jej przyczyny. + +W tym przewodniku będziemy wykorzystywać [ten raport awarii](/assets/players/crash-report-example.txt). + +:::details Pokaż raport awarii + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Sekcje raportu awarii {#crash-report-sections} + +Raporty awarii składają się z kilku sekcji, a każda z nich oddzielona jest nagłówkiem: + +- `---- Minecraft Crash Report ----`, podsumowanie raportu. Ta sekcja zawiera główny błąd, który spowodował awarię, godzinę jego wystąpienia oraz powiązany ślad stosu. Jest to najważniejsza sekcja raportu awarii, ponieważ ślad stosu zazwyczaj zawiera odniesienia do moda, który spowodował awarię. +- `-- Last Reload --`, ta sekcja nie jest szczególnie przydatna, chyba że awaria wystąpiła podczas przeładowywania zasobów (F3 + T). Zawiera ona godzinę ostatniego przeładowania i powiązany ślad stosu wszelkich błędów, które wystąpiły podczas procesu przeładowywania. Błędy te są zazwyczaj powodowane przez paczki zasobów i można je zignorować, chyba że powodują problemy z grą. +- `-- System Details --`, ta sekcja zawiera informacje o Twoim systemie, takie jak system operacyjny, wersja Javy i ilość pamięci przydzielonej grze. Jest przydatna do określenia, czy używasz odpowiedniej wersji Javy oraz czy grze została przydzielona wystarczająca ilość pamięci. + - W tej sekcji Fabric doda niestandardową linijkę `Fabric Mods`, a po niej listę wszystkich zainstalowanych modów. Ta sekcja jest przydatna do określenia, czy między modami mogły wystąpić jakiekolwiek konflikty. + +### Analizowanie raportu awarii {#breaking-down-the-crash-report} + +Teraz, gdy już wiemy, co zawiera każda sekcja raportu awarii, możemy zacząć go analizować i znaleźć przyczynę awarii. + +Korzystając z powyższego przykładu, możemy przeanalizować raport awarii i znaleźć jej przyczynę, w tym mody, które ją spowodowały. + +Ślad stosu w sekcji `---- Minecraft Crash Report ----` jest w tym przypadku najważniejszy, ponieważ zawiera główny błąd, który spowodował awarię. + +:::details Pokaż błąd + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +Ze względu na liczbę modów wymienionych w śladzie stosu, może być trudno od razu wskazać winowajcę, ale pierwszą rzeczą, jaką należy zrobić, jest poszukanie moda, który spowodował awarię. + +W tym przypadku modem, który spowodował awarię jest `snownee`, ponieważ jest to pierwszy mod wymieniony w śladzie stosu. + +Patrząc jednak na liczbę wymienionych modów, możliwe jest, że istnieją pewne problemy z kompatybilnością między modami, a mod, który spowodował awarię, może nie być winowajcą. W takim przypadku najlepiej zgłosić awarię autorowi moda i pozwolić mu ją zbadać. + +## Awarie mixinów {#mixin-crashes} + +:::info +Mixiny są sposobem, w jaki mody mogą modyfikować grę bez konieczności modyfikowania jej kodu źródłowego. Są one używane przez wiele modów i stanowią bardzo potężne narzędzie dla twórców modów. +::: + +Kiedy mixin ulegnie awarii, zazwyczaj zostanie wspomniany w śladzie stosu wraz z klasą, którą modyfikuje. + +Metody mixinów będą zawierać w śladzie stosu `modid$handlerName`, gdzie `modid` to ID moda, a `handlerName` to nazwa obsługi mixina. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +Możesz wykorzystać te informacje, aby znaleźć moda, który spowodował awarię, a następnie zgłosić ją autorowi moda. + +## Co robić z raportami awarii {#what-to-do-with-crash-reports} + +Najlepszą rzeczą, jaką można zrobić z raportami awarii to przesłanie ich na stronę do wklejania tekstów, a następnie udostępnienie linku autorowi moda przez jego system zgłaszania błędów lub jakąkolwiek inną formą komunikacji (np. na Discordzie). + +Pozwoli to autorowi moda na zbadanie awarii, potencjalne jej odtworzenie i rozwiązanie problemu, który ją spowodował. + +Popularne strony do wklejania i udostępniania raportów awarii: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/pl_pl/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/pl_pl/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..6cd97610a --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Przesyłanie logów +description: Jak przesyłać logi na potrzeby rozwiązywania problemów. +authors: + - IMB11 +--- + +# Przesyłanie logów {#uploading-logs} + +Podczas rozwiązywania problemów często konieczne jest udostępnienie logów, aby móc zidentyfikować przyczynę problemu. + +## Dlaczego warto przesyłać logi? {#why-should-i-upload-logs} + +Przesyłanie logów pozwala innym pomóc ci w rozwiązywaniu problemów znacznie szybciej niż poprzez zwykłe wklejenie logów na czat lub post na forum. Pozwala również na udostępnianie logów innym, bez konieczności ich kopiowania i wklejania. + +Niektóre strony do wklejania tekstu zapewniają również podświetlanie składni logów, co ułatwia ich czytanie, oraz mogą cenzurować poufne informacje, takie jak twoja nazwa użytkownika czy informacje o systemie. + +## Raporty awarii {#crash-reports} + +Raporty awarii są automatycznie generowane podczas awarii gry. Zawierają one jednak tylko informacje o awarii, a nie rzeczywiste logi gry. Znajdują się one w folderze `crash-reports` w katalogu gry. + +Więcej informacji na temat raportów awarii znajdziesz w przewodniku [Raporty awarii](./crash-reports). + +## Znajdowanie logów {#locating-logs} + +Ten przewodnik dotyczy oficjalnego launchera Minecrafta (powszechnie określanego jako „vanilla launcher”) — w przypadku innych launcherów należy zapoznać się z ich dokumentacją. + +Logi znajdują się w folderze `logs` w katalogu gry, który można znaleźć w następujących lokalizacjach dla poszczególnych systemów operacyjnych: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +Najnowszy log ma nazwę `latest.log`, a poprzednie logi nazywane są według wzorca `rrrr-mm-dd_numer.log.gz`. + +## Przesyłanie logów online {#uploading-logs-online} + +Logi można przesłać do różnych usług, takich jak: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/pl_pl/players/updating-fabric.md b/versions/1.21/translated/pl_pl/players/updating-fabric.md new file mode 100644 index 000000000..a87397f24 --- /dev/null +++ b/versions/1.21/translated/pl_pl/players/updating-fabric.md @@ -0,0 +1,43 @@ +--- +title: Aktualizowanie Fabric +description: Przewodnik krok po kroku o tym, jak zaktualizować Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Aktualizowanie Fabric {#updating-fabric} + +Ten przewodnik pokaże ci, jak zaktualizować Fabric dla oficjalnego launchera Minecrafta. + +W przypadku innych launcherów należy zapoznać się z ich dokumentacją. + +Aktualizowanie Fabric jest procesem bardzo podobnym do jego instalowania, więc część tego przewodnika będzie taka sama jak w przypadku przewodnika do [instalowania Fabric](./installing-fabric). + +## Dlaczego warto aktualizować Fabric Loadera? {#why-should-i-update-fabric-loader} + +Nowsze mody mogą wymagać do działania nowszej wersji Fabric Loadera, więc ważne jest, aby go aktualizować, aby móc korzystać z najnowszych modów. + + + + + +Aby zaktualizować Fabric, wystarczy upewnić się, że wersje gry i Loadera są poprawne, a następnie kliknąć `Zainstaluj`. + +:::warning WAŻNE +Upewnij się, że opcja `Utwórz profil` jest odznaczona podczas uruchamiania instalatora, w przeciwnym razie zostanie utworzony nowy profil, którego w tym przypadku nie potrzebujemy. +::: + +## 3. Otwórz profil w launcherze Minecrafta {#3-open-the-profile-in-the-minecraft-launcher} + +Po zakończeniu instalacji możesz otworzyć launcher Minecrafta i przejść do zakładki `Instalacje`. Następnie przejdź do swojego profilu Fabric i otwórz ekran edycji. + +Zastąp aktualnie wybraną wersję nowo zainstalowaną wersją Fabric Loadera i naciśnij `Zapisz`. + +![Aktualizowanie wersji Fabric Loadera w launcherze Minecrafta](/assets/players/updating-fabric.png) + +## 4. I to tyle! {#4-you-re-done} + +Po wykonaniu wszystkich kroków możesz z powrotem przejść do zakładki `Graj`, wybrać z rozwijanej listy w lewym dolnym rogu profil Fabric, a następnie zacząć grać! + +Jeśli napotkasz jakiś problem podczas korzystania z tego przewodnika, możesz poprosić o pomoc na [Discordzie Fabric](https://discord.gg/v6v4pMv) na kanale `#player-support`. diff --git a/versions/1.21/translated/pl_pl/sidebar_translations.json b/versions/1.21/translated/pl_pl/sidebar_translations.json new file mode 100644 index 000000000..9737a882c --- /dev/null +++ b/versions/1.21/translated/pl_pl/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "Przewodniki dla graczy", + "players.faq": "Często zadawane pytania", + "players.installingJava": "Instalowanie Javy", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Instalowanie Fabric", + "players.findingMods": "Znajdowanie wiarygodnych modów", + "players.installingMods": "Instalowanie modów", + "players.troubleshooting": "Rozwiązywanie problemów", + "players.troubleshooting.uploadingLogs": "Przesyłanie logów", + "players.troubleshooting.crashReports": "Raporty awarii", + "players.updatingFabric": "Aktualizowanie Fabric", + "develop.title": "Przewodniki dla deweloperów", + "develop.gettingStarted": "Pierwsze kroki", + "develop.gettingStarted.introduction": "Wprowadzenie do Fabric i modowania", + "develop.gettingStarted.devEnvSetup": "Konfiguracja środowiska programistycznego", + "develop.gettingStarted.creatingProject": "Tworzenie projektu", + "develop.gettingStarted.projectStructure": "Struktura projektu", + "develop.gettingStarted.launchGame": "Uruchamianie gry", + "develop.gettingStarted.solvingProblems": "Podstawowe rozwiązywanie problemów", + "develop.items": "Przedmioty", + "develop.items.first-item": "Tworzenie pierwszego własnego przedmiotu", + "develop.items.food": "Żywność", + "develop.items.custom-armor": "Niestandardowa zbroja", + "develop.items.custom-tools": "Niestandardowe narzędzia", + "develop.items.custom-item-groups": "Niestandardowe zakładki przedmiotów", + "develop.items.custom-item-interactions": "Niestandardowe interakcje przedmiotów", + "develop.items.potions": "Mikstury", + "develop.items.custom-data-components": "Niestandardowe komponenty danych", + "develop.blocks": "Bloki", + "develop.blocks.first-block": "Tworzenie pierwszego własnego bloku", + "develop.blocks.blockstates": "Stany bloku", + "develop.entities": "Byty", + "develop.entities.effects": "Efekty statusu", + "develop.entities.damage-types": "Rodzaje obrażeń", + "develop.commands": "Polecenia", + "develop.commands.basics": "Tworzenie poleceń", + "develop.commands.arguments": "Argumenty polecenia", + "develop.commands.suggestions": "Sugestie polecenia", + "develop.rendering": "Renderowanie", + "develop.rendering.basicConcepts": "Podstawowe koncepcje renderowania", + "develop.rendering.drawContext": "Korzystanie z kontekstu rysowania", + "develop.rendering.hud": "Renderowanie w HUD", + "develop.rendering.gui": "GUI i ekrany", + "develop.rendering.gui.customScreens": "Niestandardowe ekrany", + "develop.rendering.gui.customWidgets": "Niestandardowe widżety", + "develop.rendering.particles": "Cząsteczki", + "develop.rendering.particles.creatingParticles": "Tworzenie niestandardowych cząsteczek", + "develop.misc": "Inne strony", + "develop.misc.codecs": "Kodeki", + "develop.misc.events": "Wydarzenia", + "develop.misc.text-and-translations": "Tekst i tłumaczenia", + "develop.misc.ideTipsAndTricks": "Wskazówki i porady dla IDE", + "develop.misc.automatic-testing": "Zautomatyzowane testowanie", + "develop.sounds": "Dźwięki", + "develop.sounds.using-sounds": "Odtwarzanie dźwięków", + "develop.sounds.custom": "Tworzenie niestandardowych dźwięków" +} diff --git a/versions/1.21/translated/pl_pl/website_translations.json b/versions/1.21/translated/pl_pl/website_translations.json new file mode 100644 index 000000000..5aee13637 --- /dev/null +++ b/versions/1.21/translated/pl_pl/website_translations.json @@ -0,0 +1,46 @@ +{ + "authors.heading": "Autorzy strony", + "authors.nogithub": "%s (nie na GitHub)", + "banner": "Dokumentacja Fabric wciąż jest w trakcie opracowywania. Jakiekolwiek problemy zgłaszaj na %s lub %s.", + "description": "Obszerna dokumentacja dla Fabric — zestawu narzędzi do modowania Minecrafta.", + "footer.next": "Następna strona", + "footer.prev": "Poprzednia strona", + "github_edit": "Edytuj tę stronę na GitHubie", + "lang_switcher": "Zmień język", + "last_updated": "Ostatnio zaktualizowano", + "mode_dark": "Przełącz na ciemny motyw", + "mode_light": "Przełącz na jasny motyw", + "mode_switcher": "Wygląd", + "nav.contribute": "Współtwórz projekt", + "nav.contribute.api": "Fabric API", + "nav.download": "Pobierz", + "nav.home": "Strona główna", + "outline": "Na tej stronie", + "return_to_top": "Powrót na górę", + "search.back": "Zamknij wyszukiwanie", + "search.button": "Szukaj", + "search.display_details": "Wyświetl szczegółową listę", + "search.footer.close": "zamknięcie", + "search.footer.close.key": "Escape", + "search.footer.down.key": "Strzałka w dół", + "search.footer.navigate": "nawigacja", + "search.footer.up.key": "Strzałka w górę", + "search.footer.select": "wybór", + "search.footer.select.key": "Enter", + "search.no_results": "Brak wyników dla", + "search.reset": "Resetuj wyszukiwanie", + "sidebar_menu": "Menu", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Dokumentacja Fabric", + "version_switcher": "Przełącz wersję", + "404.code": "404", + "404.crowdin_link": "Przetłumacz na Crowdin", + "404.crowdin_link.label": "Otwórz edytor Crowdin", + "404.english_link": "Przełącz na angielski", + "404.english_link.label": "Otwórz wersję angielską", + "404.link": "Przejdź na stronę główną", + "404.link.label": "Przejdź na stronę główną", + "404.quote": "Ta strona próbowała pływać w lawie", + "404.title": "Nie znaleziono strony" +} \ No newline at end of file diff --git a/versions/1.21/translated/pt_br/contributing.md b/versions/1.21/translated/pt_br/contributing.md new file mode 100644 index 000000000..2aab6e44e --- /dev/null +++ b/versions/1.21/translated/pt_br/contributing.md @@ -0,0 +1,181 @@ +# Diretrizes de Contribuição da Documentação do Fabric + +Este site usa [VitePress](https://vitepress.dev/) para gerar HTML estático de vários arquivos do Markdown. Você deve estar familiarizado com as extensões Markdown que o VitePress suporta [aqui](https://vitepress.dev/guide/markdown#features). + +## Sumário + +- [Diretrizes de contribuição da documentação do Fabric](#fabric-documentation-contribution-guidelines) + - [Como Contribuir](#how-to-contribute) + - [Estrutura Da Contribuição](#contributing-framework) + - [Conteúdo Da Contribuição](#contributing-content) + - [Diretrizes A Se Seguir](#style-guidelines) + - [Instruções para Expandir](#guidance-for-expansion) + - [Verificação De Conteúdo](#content-verification) + - [Apuração](#cleanup) + - [Traduzindo a Documentação](#translating-documentation) + +## Como contribuir + +É recomendado que você crie uma nova "branch" no seu "fork do repositório" a cada "pull request" que você faça. Isso faz ser mais fácil de gerenciar múltiplos "pull requests" de uma vez. + +**Se você quiser visualizar suas alterações localmente, basta instalar [Node.js 18+](https://nodejs.org/en/)** + +Antes de executar alguns desses comandos, certifique-se de executar `npm install` para instalar todas as dependências. + +**Executando o ambiente de desenvolvimento.** + +Isso vai permitir que você visualize as alterações localmente em: `localhost:3000` e recarregará automaticamente a página quando você fizer alterações. + +```sh +npm run dev +``` + +**Fazendo o Website.** + +Isto irá compilar todos os arquivos Markdown em arquivos HTML estáticos e colocá-los em: `.vitepress/dist` + +```sh +npm run build +``` + +**Visualizando o Site Feito.** + +Isso iniciará um servidor local na porta 3000 servindo o conteúdo encontrado em `.vitepress/dist` + +```sh +npm run preview +``` + +## Estrutura Da Contribuição + +"Estrutura" refere-se a estrutura interna do website, qualquer "pull request" que modifique essa "estrutura" do site vai ser relatada como: `framework` + +Na verdade, você só deve fazer solicitações e "pull request" de frameworks após consultar a equipe da documentação do [Fabric Discord](https://discord.gg/v6v4pMv) ou após relatar um problema. + +**Observação: modificar os arquivos da barra lateral e da configuração da barra de navegação não conta como uma solicitação de "pull request de framework.** + +## Contribuindo com Conteúdo + +Contribuições com conteúdo são a principal forma de contribuir com a documentação do Fabric. + +Todo o conteúdo deve seguir as nossas diretrizes. + +### Diretrizes A Se Seguir + +Todas as páginas de site de documentação do Fabric devem seguir as diretrizes. Se estiver em duvida de alguma coisa, você pode perguntar no [Fabric Discord](https://discord.gg/v6v4pMv) ou por meio de discussões no GitHub. + +As diretrizes a serem seguidas: + +1. Todas as páginas devem ter a descrição e o título no topo, a mostra. + + ```md + --- + título: Esse é o Título da Pagina + Descrição: Essa é a descrição da página + autores: + - NomeAleatórioDoGitHub + --- + + # ... + ``` + +2. Se você criar ou modificar páginas contendo código, coloque o código em um local apropriado com o mod de referência (localizado na pasta `/reference` do repositório). Em seguida, use o [recurso de "snippet" de código oferecido pelo "VitePress"](https://vitepress.dev/guide/markdown#import-code-snippets) para incorporar o código ou, se precisar de maior controle, você pode usar o [transcluir recurso de `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + + **Exemplo.** + + ```md + <<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21 java} + ``` + + Isso incorporará as linhas 15-21 do arquivo `FabricDocsReference.java` no mod de referência. + + O trecho do código ficará assim: + + ```java + @Override + public void onInitialize() { + // Este código é executado quando o Minecraft esta pronto para carregar mods. + // No entanto, algumas coisas (como recursos) ainda podem não ser inicializadas. + // Proceda com atenção. + + LOGGER.info("Olá Mundo Fabric!"); + } + ``` + + **Exemplo de transclusão:** + + ```md + @[code transcludeWith=#test_transclude](@/reference/.../blah.java) + ``` + + Isso incorporará as seções de `blah.java` marcadas com a tag `#test_transclude`. + + Como por exemplo: + + ```java + public final String test = "Tchau Mundo!" + + // #test_transclude + public void test() { + System.out.println("Olá Mundo!"); + } + // #test_transclude + ``` + + Somente o código entre as tags `#test_transclude` será incorporado. + + ```java + public void test() { + System.out.println("Olá Mundo!"); + } + ``` + +3. A documentação original inteira é escrita em Inglês, seguindo as regras da gramática Estadunidense. Embora você possa usar o [LanguageTool](https://languagetool.org/) para verificar sua gramática enquanto digita,mas não se encuque muito com isso. Nossa equipe de documentação revisará e corrigirá a gramática durante a fase de revisão. No entanto, se esforçar para acertar inicialmente pode nos poupar um bom tempo. + +4. Se você estiver criando uma nova seção, você deve criar uma nova barra lateral na pasta `.vitepress/sidebars` e adicioná-la ao arquivo `config.mts`. Se você precisa de assistência com isso, por favor peça no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#docs`. + +5. Ao criar uma nova página, você deve adicioná-la à barra lateral relevante na pasta `.vitepress/sidebars`. De novo, se precisar de ajuda, nos chame no Discord do Fabric no canal `#docs`. + +6. Quaisquer imagens devem ser colocadas em um "local adequado" na pasta `/assets`. + +7. ⚠️ **Ao vincular outras páginas, use links relativos.** ⚠️ + + Isso se deve ao sistema de versionamento em vigor, que processará os links para adicionar uma versão de antemão. Se você usar links absolutos, o número da versão não será adicionado ao link. + + Por exemplo, para uma página na pasta `/players`, para vincular à página `installing-fabric` encontrada em `/players/installing-fabric.md`, você teria que fazer o seguinte: + + ```md + [Isto é um link para outra página](./installing-fabric) + ``` + + Você **NÃO** deve fazer o seguinte: + + ```md + [Isto é um link para outra página](/players/installing-fabric) + ``` + +Todas as contribuições de conteúdo passam por três etapas: + +1. Instruções para Expandir (se necessário) +2. Verificação de Conteúdo +3. Revisão (Gramatica, etc.) + +### Instruções para Expandir + +Se a equipe de documentação julgar que você poderia expandir seu "pull request", um membro da equipe adicionará o rótulo `can-expand` ao seu "pull request" com um comentário explicando o que eles pensam que você poderia expandir. Se você concordar com a sugestão, poderá expandir seu "pull request" + +**Não se sinta pressionado em expandir seu "pull request".** Se não quiser expandir seu "pull request", você pode simplesmente solicitar que o rótulo `can-expand` seja removido. + +Se você não deseja expandir seu "Pull Request", mas deseja que outra pessoa a expanda posteriormente, é melhor criar um "Issue" na [página de "issues"](https://github.com/FabricMC/fabric-docs/issues) e explique o que você acha que pode ser expandido. + +### Verificação de Conteúdo + +Todas as "Pull Requests" que adicionam conteúdo passam por verificação de conteúdo, esta é a etapa mais importante, pois garante que o conteúdo seja preciso e siga as diretrizes da documentação do Fabric. + +### Verificação + +Esta etapa é onde a equipe de documentação corrigirá quaisquer problemas gramaticais e fará quaisquer outras alterações que julgar necessárias antes de mesclar o "Pull Request"! + +## Traduzindo a Documentação + +Se você desejar traduzir a documentação para a sua linguagem, você pode fazer isso na [pagina do Crowdin do Fabric](https://crowdin.com/project/fabricmc). diff --git a/versions/1.21/translated/pt_br/develop/entities/damage-types.md b/versions/1.21/translated/pt_br/develop/entities/damage-types.md new file mode 100644 index 000000000..d9202ccfe --- /dev/null +++ b/versions/1.21/translated/pt_br/develop/entities/damage-types.md @@ -0,0 +1,96 @@ +--- +title: Tipos de dano +description: Aprenda a adicionar tipos de dano personalizados. +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# Tipos de Dano {#damage-types} + +Os tipos de dano definem os tipos de dano que as entidades podem sofrer. A partir do Minecraft 1.19.4, a criação de novos tipos de dano passou a ser baseada em dados, o que significa que eles são criados usando arquivos JSON. + +## Criando um Tipo de Dano + +Vamos criar um tipo de dano customizado chamado _Tater_. Começaremos criando um arquivo JSON para seu dano. Este arquivo será colocado na pasta `data` do seu mod, em uma subpasta chamada `damage_type`. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +Ele terá a seguinte estrutura: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +Esse tipo de dano causa aumento de 0.1 na [exaustão de fome](https://minecraft.wiki/w/Hunger#Exhaustion_level_increase) toda vez que um jogador sofrer dano, quando o dano for causado por uma fonte viva que não seja um jogador (ex: um bloco). Além disso, a quantidade de dano causado escalonará com a dificuldade do mundo. + +::: info + +Consulte a [Wiki do Minecraft](https://pt.minecraft.wiki/w/Tipo_de_dano) para todas as chaves e valores possíveis. + +::: + +### Acessando Tipos de Dano Através de Código + +Quando precisarmos acessar nosso tipo de dano através de código, usaremos a sua `RegistryKey` (Chave de Registro) para construir uma instância de `DamageSource` (Fonte de Dano). + +A `RegistryKey` pode ser obtida da seguinte maneira: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### Usando Tipos de Dano {#using-damage-types} + +Para demonstrar o uso de tipos de dano personalizados, usaremos um bloco personalizado chamado _Tater Block_. Façamos com que quando uma entidade viva pisar em um _Tater Block_, ele causará dano de _Tater_. + +Você pode substituir `onSteppedOn` para infligir este dano. + +Começaremos criando uma `DamageSource` do nosso tipo de dano customizado. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Então, chamamos `entity.damage()` com o nosso `DamageSource`e uma quantidade. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +A implementação completa do bloco: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Agora, quando uma entidade viva pisar no nosso bloco, ela sofrerá 5 de dano (2,5 corações) usando nosso tipo de dano personalizado. + +### Mensagem de Morte Personalizada + +Você pode definir uma mensagem de morte para o tipo de dano no formato de `death.attack.` no arquivo `en_us.json` do mod. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +Ao morrer devido ao nosso tipo de dano, você verá a seguinte mensagem: + +![Efeito no inventário do jogador](/assets/develop/tater-damage-death.png) + +### Tags de Tipo de Dano + +Alguns danos podem ignorar a armadura, efeitos de estado, e similares. Tags (etiquetas) são usadas para controlar tais propriedades dos tipos de dano. + +As tags de tipo de dano existentes se encontram em `data/minecraft/tags/damage_type`. + +::: info + +Consulte a [Wiki do Minecraft](https://pt.minecraft.wiki/w/Tipo_de_dano) para uma lista compreensiva de tags de tipos de dano. + +::: + +Vamos adicionar nosso dano Tater para a tag `bypasses_armor` (ignora armadura). + +Para adicionar nosso dano a uma dessas tags, criamos um arquivo JSON sob o namespace de `minecraft`. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +Com o seguinte conteúdo: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +Certifique-se de que sua tag não substitua a tag existente definindo a chave `replace` como `false`. diff --git a/versions/1.21/translated/pt_br/develop/entities/effects.md b/versions/1.21/translated/pt_br/develop/entities/effects.md new file mode 100644 index 000000000..78f41cac9 --- /dev/null +++ b/versions/1.21/translated/pt_br/develop/entities/effects.md @@ -0,0 +1,65 @@ +--- +title: Efeitos de Estado +description: Aprenda a adicionar efeitos de estado personalizados. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil +authors-nogithub: + - siglong + - tao0lu +--- + +# Efeitos de Estado + +Efeitos de estado, conhecidos como efeitos, são condições que podem afetar uma entidade. Eles podem ser de natureza positiva, negativa ou neutra. O jogo base aplica esses efeitos de vários modos, como comidas, poções, etc. + +O comando `/effect` pode ser usado para aplicar efeitos numa entidade. + +## Efeitos Personalizados + +Neste tutorial adicionaremos um novo efeito personalizado chamado _Tater_, que lhe dará um ponto de experiência a cada tick do jogo. + +### Estenda `StatusEffect` {#extend-statuseffect} + +Vamos criar uma classe de efeito personalizado estendendo `StatusEffect`, sendo uma classe base para todos os efeitos. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### Registrando seu Efeito Personalizado + +Similar a registração de blocos e itens, usamos `Registry.register` para registrar nosso efeito ao registro de `STATUS_EFFECT`. Isso pode ser feito no nosso inicializador. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### Textura + +Estenda `StatusEffect` Traduções e Texturas Você pode atribuir um nome ao seu efeito e providenciar uma textura de ícone que aparecerá na tela de inventário do jogador. O ícone de textura é um PNG de 18x18. Coloque seu ícone personalizado em: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + + + +### Traduções + +Assim como outras traduções, você pode adicionar uma entrada com o formato de ID `"effect..": "Value"` ao arquivo de idioma. + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### Testando + +Uso o comando `/effect give @p fabric-docs-reference:tater` para dar ao jogador nosso efeito Tater. +Use `/effect clear @p fabric-docs-reference:tater` para remover o efeito. + +:::info +::: info +Para criar uma poção que utiliza este efeito, consulte o [guia de Poções](../items/potions). +::: diff --git a/versions/1.21/translated/pt_br/develop/index.md b/versions/1.21/translated/pt_br/develop/index.md new file mode 100644 index 000000000..d512f1ffb --- /dev/null +++ b/versions/1.21/translated/pt_br/develop/index.md @@ -0,0 +1,12 @@ +--- +title: Guias do desenvolvedor +description: Nossos guias de desenvolvedor, escritos pela comunidade, abrangem uma variedade de tópicos desde a configuração de um ambiente de desenvolvimento até tópicos mais avançados, como renderização e networking. +--- + +# Guias do desenvolvedor + +Nossos guias de desenvolvedor, escritos pela comunidade, abrangem uma variedade de tópicos desde a configuração de um ambiente de desenvolvimento até tópicos mais avançados, como renderização e networking. + +Consulte a barra lateral para uma lista de todos os guias de desenvolvedor disponíveis. Se estiver procurando algo específico, você pode usar a barra de pesquisa no topo da página para achar o que precisa. + +Se desejar contribuir à Documentação do Fabric, você pode encontrar o código-fonte no [GitHub](https://github.com/FabricMC/fabric-docs), leia também as [diretrizes de contribuição](../contributing). diff --git a/versions/1.21/translated/pt_br/index.md b/versions/1.21/translated/pt_br/index.md new file mode 100644 index 000000000..d0165d69e --- /dev/null +++ b/versions/1.21/translated/pt_br/index.md @@ -0,0 +1,27 @@ +--- +title: Documentação do Fabric +description: A documentação oficial para o Fabric, um conjunto de ferramentas para mods de Minecraft. +layout: home +hero: + name: Documentação do Fabric + tagline: A documentação oficial para o Fabric, um conjunto de ferramentas para mods de Minecraft. +features: + - title: Guias para desenvolvedores + icon: 🛠️ + details: Nossos guias de desenvolvedor, escritos pela comunidade, abrangem uma variedade de tópicos desde a configuração de um ambiente de desenvolvimento até tópicos mais avançados, como renderização e networking. + link: /develop/ + linkText: Guia de Introdução + - title: Guias do Jogador + icon: 📚 + details: Você é um jogador que deseja usar mods desenvolvidos para o Fabric? Nossos guias de jogador irão te ajudar. Esses guias te ajudarão a baixar, instalar e solucionar problemas com mods do Fabric. + link: /players/ + linkText: Leia Mais +--- + +
+ +## Deseja ajudar? + +If you want to contribute to the Fabric Documentation, you can find the source code on [GitHub](https://github.com/FabricMC/fabric-docs), and the relevant [contribution guidelines](./contributing). + +
diff --git a/versions/1.21/translated/pt_br/navbar_translations.json b/versions/1.21/translated/pt_br/navbar_translations.json new file mode 100644 index 000000000..839f29951 --- /dev/null +++ b/versions/1.21/translated/pt_br/navbar_translations.json @@ -0,0 +1,8 @@ +{ + "title": "Documentação do Fabric", + "home": "Início", + "download": "Download", + "contribute": "Contribua", + "contribute.api": "API do Fabric", + "version_switcher": "Mudar Versão" +} \ No newline at end of file diff --git a/versions/1.21/translated/pt_br/players/faq.md b/versions/1.21/translated/pt_br/players/faq.md new file mode 100644 index 000000000..5d9ea3642 --- /dev/null +++ b/versions/1.21/translated/pt_br/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Perguntas frequentes dos jogadores +description: Dúvidas mais frequentes dos jogadores e administradores de servidor sobre o Fabric. +--- + +# Perguntas Frequentes (FAQ) + +Há muitas perguntas feitas com frequência, então compilamos uma lista delas aqui. + +## Quais versões do Minecraft são compatíveis com o Fabric? {#what-minecraft-versions-does-fabric-support} + +Oficialmente, o Fabric é compatível com todas as versões do Minecraft começando da snapshot `18w43b` em diante, e versões da `1.14` em diante. + +## Onde eu posso baixar mods publicados do Fabric? {#where-can-i-download-published-fabric-mods} + +:::info +Você deve sempre verificar se os mods são de fontes confiáveis. Visite o guia [Encontrando Mods Confiáveis](./finding-mods) para mais informações. +::: + +A maioria dos autores publicam seus mods no [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) e no [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4), no entando, alguns preferem publicá-los em seus sites pessoais, ou em outras plataformas, como um repositório GitHub. + +## Onde eu posso achar modpacks pré-feitos para Fabric? {#where-can-i-find-premade-fabric-modpacks} + +Você pode achar modpacks para Fabric pré-feitos em várias plataformas, como: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/pt_br/players/finding-mods.md b/versions/1.21/translated/pt_br/players/finding-mods.md new file mode 100644 index 000000000..f71318f9c --- /dev/null +++ b/versions/1.21/translated/pt_br/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Encontrando Mods Confiáveis +description: Um guia para achar mods para Fabric usando fontes confiáveis. +authors: + - IMB11 +--- + +# Encontrando Mods Confiáveis + +Primeiramente, a confiança é subjetiva, e você sempre deve usar seu próprio julgamento ao baixar mods. No entanto, há algumas coisas que você pode fazer para te ajudar a encontrar mods confiáveis. + +## 1. Usar uma Fonte que Seja Reconhecidamente Confiável + +A maioria dos autores publicam seus mods no [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) e no [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4). + +Estes sites verificam se os mods são o que dizem ser e se não contêm código malicioso. Você também pode denunciar mods maliciosos nestes sites, e eles tomarão providência quanto antes. + +## 2. Verificar com Outros! {#with-others} + +Se você estiver baixando um mod por uma fonte não confiável, cheque com outros para ver se já baixaram o mod pelo mesmo local antes e se não tiveram algum problema com ele. + +Em caso de dúvidas, sinta-se à vontade para perguntar no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#player-support`. + +## 3. Evitar Sites Comuns de Malware! {#avoid-malware} + +:::info +Sites de malware podem não ser óbvios para todos. Se estiver incerto, peça a opinião de outros ou evite este site por completo e use apenas fontes confiáveis, como Modrinth e CurseForge. +::: + +Há muitos sites que dizem ter mods para Minecraft, mas, na verdade, são apenas malware. Você deve evitar estes sites a todo custo. + +Você pode usar programas de antivírus e sites como o [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) ou o [VirusTotal](https://www.virustotal.com/) para verificar os mods baixados. No entanto, não confie apenas nestes métodos, pois às vezes eles também podem estar incorretos. + +Novamente, em caso de dúvidas, sinta-se à vontade para pedir opiniões no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#player-support`. diff --git a/versions/1.21/translated/pt_br/players/index.md b/versions/1.21/translated/pt_br/players/index.md new file mode 100644 index 000000000..38aace130 --- /dev/null +++ b/versions/1.21/translated/pt_br/players/index.md @@ -0,0 +1,12 @@ +--- +title: Guias para jogadores +description: Uma coleção de guias para jogadores e administradores de servidores ao instalar e usar o Fabric. +--- + +# Guias para jogadores + +Esta seção da Documentação do Fabric é dedicada à jogadores e administradores de servidores que querem aprender a como instalar, usar, e diagnosticar problemas com Fabric. + +Você pode consultar a barra lateral para uma lista de todos os guias disponíveis. + +Se você encontrar qualquer problema, por favor reporte-os [no GitHub](https://github.com/FabricMC/fabric-docs) ou peça ajuda no [Discord do Fabric](https://discord.gg/v6v4pMv) nos canais `#player-support` ou `#server-admin-support`. diff --git a/versions/1.21/translated/pt_br/players/installing-fabric.md b/versions/1.21/translated/pt_br/players/installing-fabric.md new file mode 100644 index 000000000..e70b6c746 --- /dev/null +++ b/versions/1.21/translated/pt_br/players/installing-fabric.md @@ -0,0 +1,55 @@ +--- +title: Instalando Fabric +description: Um guia passo a passo de como instalar Fabric. +authors: + - IMB11 +--- + +# Instalando Fabric + +Este guia o orientará na instalação do Fabric para o Launcher oficial do Minecraft. + +Para launchers de terceiros, você deve consultar suas devidas documentações. + +## 1. Baixar o instalador do Fabric + +Você pode baixar o Instalador do Fabric pelo [Site do Fabric](https://fabricmc.net/use/). + +Se você usa Windows, baixe a versão `.exe` (`Download For Windows`), pois ela não necessita da presença do Java no seu sistema. Ela usa o Java que acompanha o launcher oficial. + +Para macOS e Linux, você deve baixar a versão `.jar`. A instalação do Java antes desse passo pode ser necessária. + +## 2. Executar o instalador do Fabric + +:::warning +Feche o Minecraft e Minecraft Launcher antes da instalação. +::: + +:::details Informação para usuários do macOS + +No macOS, talvez seja necessário clicar com o botão direito no arquivo `.jar` em sua pasta de downloads e clicar em `Open` para executá-lo. + +![Menu de contexto do macOS no Instalador do Fabric](/assets/players/installing-fabric/macos-downloads.png) + +Quando perguntado "Tem certeza de que deseja abrir isso?", aperte em `Abrir` novamente. +::: + +Assim que você abrir o instalador, deverá ver uma tela como essa: + +![Instalador do Fabric com "Instalar" destacado](/assets/players/installing-fabric/installer-screen.png) + +Para instalar o Fabric, apenas escolha a versão do seu jogo e clique em `Instalar`. + +**Certifique-se de que `Criar Perfil` está marcado.** + +## 3. Tudo Pronto! + +Assim que o instalador terminar, você pode abrir o Minecraft Launcher, selecionar o perfil Fabric através do botão no canto inferior esquerdo e clicar em Jogar! + +![Minecraft Launcher com o perfil Fabric selecionado](/assets/players/installing-fabric/launcher-screen.png) + +## Próximos passos + +Agora que você instalou o Fabric, você pode adicionar mods ao seu jogo! Dê uma olhada no guia [Encontrando Mods Confiáveis](./finding-mods) para mais informações. + +Se você encontrar algum problema, sinta-se à vontade para pedir ajuda no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#player-support`. diff --git a/versions/1.21/translated/pt_br/players/installing-java/linux.md b/versions/1.21/translated/pt_br/players/installing-java/linux.md new file mode 100644 index 000000000..e9dcb2a85 --- /dev/null +++ b/versions/1.21/translated/pt_br/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Instalando Java no Linux +description: Um guia passo a passo de como instalar Java no Linux. +authors: + - IMB11 +--- + +# Instalando Java no Linux + +Este guia o orientará na instalação do Java 17 no Linux. + +## 1. Verificar Se o Java Já Está Instalado + +Abra um terminal, digite `java -version`, e pressione Enter. + +![Terminal com "java -version" digitado](/assets/players/installing-java/linux-java-version.png) + +:::warning +Para usar a maioria das versões modernas do Minecraft, você precisará ter pelo menos o Java 17 instalado. Se este comando exibir uma versão inferior a 17, será necessário atualizar sua instalação do Java atual. +::: + +## 2. Baixando e instalando Java 17 + +Recomendamos usar o OpenJDK 17, que está disponível para a maioria das distribuições Linux. + +### Arch Linux + +:::info +Para mais informações na instalação do Java no Arch Linux, veja a [Wiki do Arch Linux](https://wiki.archlinux.org/title/Java_(Portugu%C3%AAs)). +::: + +Você pode instalar a JRE mais recente através de repositórios oficiais: + +```sh +sudo pacman -S jre-openjdk +``` + +Se estiver rodando um servidor sem a necessidade de uma interface gráfica, você pode instalar a versão headless: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Se você planeja desenvolver mods, precisará do JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu + +Você pode instalar o Java 17 usando `apt` com os seguintes comandos: + +```sh +sudo apt update +sudo apt install openjdk-17-jdk +``` + +### Fedora + +Você pode instalar o Java 17 usando `dnf` com os seguintes comandos: + +```sh +sudo dnf install java-17-openjdk +``` + +Se você não precisa de uma interface gráfica, você pode instalar a versão headless: + +```sh +sudo dnf install java-17-openjdk-headless +``` + +Se você planeja desenvolver mods, precisará do JDK: + +```sh +sudo dnf install java-17-openjdk-devel +``` + +### Outras distribuições Linux + +Se sua distribuição não foi listada acima, você pode baixar a JRE mais recente pelo [Adoptium](https://adoptium.net/temurin/) + +Você deve consultar um guia próprio de sua distribuição se planeja desenvolver mods. + +## 3. Verificar se o Java 17 está instalado + +Assim que a instalação terminar, você pode verificar se o Java 17 está instalado abrindo o terminal novamente e digitando `java -version`. + +Se o comando for executado com êxito, você verá algo como mostrado anteriormente onde a versão do Java é exibida: + +![Terminal com "java -version" digitado](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/pt_br/players/installing-java/windows.md b/versions/1.21/translated/pt_br/players/installing-java/windows.md new file mode 100644 index 000000000..3f337622d --- /dev/null +++ b/versions/1.21/translated/pt_br/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Instalando Java no Windows +description: Um guia passo a passo de como instalar Java no Windows. +authors: + - IMB11 +--- + +# Instalando Java no Windows + +Este guia o orientará na instalação do Java 17 no Windows. + +O Launcher do Minecraft vem com sua própria instalação do Java, portanto esta seção só é relevante se você quiser usar o instalador baseado em `.jar` do Fabric ou se quiser usar o `.jar` do Servidor do Minecraft. + +## 1. Verificar Se o Java Já Está Instalado + +Para verificar se o Java já está instalado, você deve primeiro abrir o prompt de comando. + +Você pode fazer isso apertando Win + R e digitando `cmd.exe` na janela aberta. + +![Caixa de diálogo Executar do Windows com "cmd.exe" na barra de execução](/assets/players/installing-java/windows-run-dialog.png) + +Após abrir o prompt de comando, digite `java -version` e pressione Enter. + +Se o comando for executado com êxito, você verá algo parecido com isto. Se o comando falhar, prossiga para o próximo passo. + +![Prompt de comando com "java -version" digitado](/assets/players/installing-java/windows-java-version.png) + +:::warning +Para usar a maioria das versões modernas do Minecraft, você precisará ter pelo menos o Java 17 instalado. Se este comando exibir uma versão inferior a 17, será necessário atualizar sua instalação do Java atual. +::: + +## 2. Baixar o Instalador do Java 17 + +Para instalar o Java 17, você precisará baixar o instalador pelo [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows&package=jdk&version=17). + +Você deverá baixar a versão `Windows Installer (.msi)`: + +![Página de download do Adoptium com Windows Installer (.msi) destacado](/assets/players/installing-java/windows-download-java.png) + +Você deverá escolher 'x86' se tiver um sistema operacional 32-bit, ou 'x64' se tiver um sistema operacional 64-bit. + +A maioria dos computadores modernos terão um sistema operacional 64-bit. Em caso de dúvida, tente usar o download 64-bit. + +## 3. Executar o Instalador! + +Siga os passos do instalador para instalar o Java 17. Ao chegar nesta página, você deve definir os seguintes recursos como "Todo o recurso será instalado no disco rígido local": + +- `Set JAVA_HOME environment variable` - Isso será adicionado ou seu PATH. +- `JavaSoft (Oracle) registry keys` + +![Instalador do Java 17 com "Set JAVA_HOME variable" e "JavaSoft (Oracle) registry keys" destacados](/assets/players/installing-java/windows-wizard-screenshot.png) + +Assim que fizer isto, clique em 'Next' e continue com a instalação. + +## 4. Verificar se o Java 17 está instalado + +Assim que a instalação terminar, você pode verificar se o Java 17 está instalado abrindo o prompt de comando novamente e digitando `java -version`. + +Se o comando for executado com êxito, você verá algo como mostrado anteriormente onde a versão do Java é exibida: + +![Prompt de comando com "java -version" digitado](/assets/players/installing-java/windows-java-version.png) + +--- + +Se você encontrar algum problema, sinta-se à vontade para pedir ajuda no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#player-support`. diff --git a/versions/1.21/translated/pt_br/players/installing-mods.md b/versions/1.21/translated/pt_br/players/installing-mods.md new file mode 100644 index 000000000..38c8ac5d2 --- /dev/null +++ b/versions/1.21/translated/pt_br/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Instalando Mods +description: Um guia passo a passo de como instalar mods para Fabric. +authors: + - IMB11 +--- + +# Instalando Mods + +Este guia o orientará na instalação de mods para Fabric usando o Minecraft Launcher. + +Para launchers de terceiros, você deve consultar suas devidas documentações. + +## 1. Baixar o Mod + +:::warning +Você deve baixar mods apenas de fontes que confia. Para mais informações sobre achar mods, veja o guia [Encontrando Mods Confiáveis](./finding-mods). +::: + +A maioria dos mods necessitam do Fabric API, que pode ser baixado através do [Modrinth](https://modrinth.com/mod/fabric-api) ou [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +Ao baixar mods, certifique-se de que: + +- Eles funcionam na versão do Minecraft que você quer jogar. Um mod feito para a versão 1.20, por exemplo, pode não funcionar na versão 1.20.2. +- Eles são para o Fabric, não outro mod loader (carregador de mods). +- Eles são feitos para a edição certa do Minecraft (Edição Java). + +## 2. Mover o Mod para a Pasta `mods` + +A pasta de mods pode ser encontrada nos seguintes locais para cada sistema operacional. + +Você pode colar esses endereços na barra de endereços do seu navegador de arquivos para rapidamente achar a pasta. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Encontrada a pasta `mods`, você pode mover os arquivos `.jar` dos mods para dentro dela. + +![Mods instalados na pasta de mods](/assets/players/installing-mods.png) + +## 3. Tudo Pronto! + +Assim que movidos os mods para a pasta `mods`, você pode abrir o Minecraft Launcher, selecionar o perfil Fabric através do botão no canto inferior esquerdo e clicar em jogar! + +![Minecraft Launcher com o perfil Fabric selecionado](/assets/players/installing-fabric/launcher-screen.png) + +## Solução de Problemas + +Se você encontrar algum problema, sinta-se à vontade para pedir ajuda no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#player-support`. + +Você também pode tentar diagnosticar o problema por si mesmo através das páginas de solução de problemas: + +- [Relatórios de Crash](./troubleshooting/crash-reports) +- [Upload de Logs](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/pt_br/players/updating-fabric.md b/versions/1.21/translated/pt_br/players/updating-fabric.md new file mode 100644 index 000000000..60d446981 --- /dev/null +++ b/versions/1.21/translated/pt_br/players/updating-fabric.md @@ -0,0 +1,41 @@ +--- +title: Atualizando o Fabric +description: Um guia passo a passo de como atualizar o Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Atualizando o Fabric + +Este guia o orientará na atualização do Fabric para o Minecraft Launcher. + +Para launchers de terceiros, você deve consultar suas devidas documentações. + +Atualizar o Fabric é um processo similar ao de instalação, portanto partes deste guia serão iguais ao guia de [Instalação do Fabric](./installing-fabric). + +## Por que eu deveria atualizar o Fabric Loader? + +Mods novos podem requerir a versão mais nova do Fabric Loader para funcionar, então é importante mantê-lo atualizado para se poder usar os mods mais recentes. + + + + + +Para atualizar o Fabric, simplesmente certifique-se de que a versão do jogo e a versão do Loader estejam corretas, então clique em `Instalar`. + +**Desmarque 'Criar Perfil' ao rodar o instalador, caso contrário será criado um novo perfil, que nesse caso não é necessário.** + +## 3. Abrir o Perfil no Minecraft Launcher + +Terminada a instalação, abra o Minecraft Launcher e vá para a aba de `Instalações`. Vá para seu perfil Fabric e abra a tela de edição. + +Substitua a versão com a nova versão do Fabric Loader que você acabou de instalar, e aperte `Salvar`. + +![Atualizando a versão do Fabric Loader no Minecraft Launcher](/assets/players/updating-fabric.png) + +## 4. Tudo Pronto! + +Terminado os passsos acima, você pode voltar à aba `Jogar`, selecionar o perfil Fabric através do botão no canto inferior esquerdo e clicar em Jogar! + +Se você encontrar algum problema, sinta-se à vontade para pedir ajuda no [Discord do Fabric](https://discord.gg/v6v4pMv) no canal `#player-support`. diff --git a/versions/1.21/translated/pt_br/sidebar_translations.json b/versions/1.21/translated/pt_br/sidebar_translations.json new file mode 100644 index 000000000..53104646d --- /dev/null +++ b/versions/1.21/translated/pt_br/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "Guia para jogadores", + "players.faq": "Perguntas Frequentes", + "players.installingJava": "Instalando o Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Instalando o Fabric", + "players.findingMods": "Encontrando Mods Confiáveis", + "players.installingMods": "Instalando mods", + "players.troubleshooting": "Resolução de Problemas", + "players.troubleshooting.uploadingLogs": "Enviando Seus Logs", + "players.troubleshooting.crashReports": "Relatórios de Erros", + "players.updatingFabric": "Atualizando o Fabric", + "develop.title": "Guia do desenvolvedor", + "develop.gettingStarted": "Primeiros Passos", + "develop.gettingStarted.introduction": "Introdução ao Fabric e Modding", + "develop.gettingStarted.devEnvSetup": "Configurando o Ambiente de Desenvolvimento", + "develop.gettingStarted.creatingProject": "Criando um Projeto", + "develop.gettingStarted.projectStructure": "Estrutura de Projeto", + "develop.gettingStarted.launchGame": "Iniciando o Jogo", + "develop.gettingStarted.solvingProblems": "Solução de problemas básicos", + "develop.items": "Itens", + "develop.items.first-item": "Criando seu Primeiro Item", + "develop.items.food": "Food Items: Comidas Customizadas", + "develop.items.custom-armor": "Custom Armor: Armaduras Customizadas", + "develop.items.custom-tools": "Custom Tools: Ferramentas Personalizadas", + "develop.items.custom-item-groups": "Custom Item Groups: Grupos de Itens Personalizados", + "develop.items.custom-item-interactions": "Custom Item Interactions: Customizando as Interações de Itens", + "develop.items.potions": "Poções", + "develop.items.custom-data-components": "Custom Data Components: Personalizando Dados de Itens", + "develop.blocks": "Blocos", + "develop.blocks.first-block": "Criando seu Primeiro Bloco", + "develop.blocks.blockstates": "Estados de Bloco", + "develop.entities": "Entidades", + "develop.entities.effects": "Efeitos de Estado", + "develop.entities.damage-types": "Tipos de dano", + "develop.commands": "Comandos", + "develop.commands.basics": "Criando comandos", + "develop.commands.arguments": "Argumentos de Comando", + "develop.commands.suggestions": "Sugestões", + "develop.rendering": "Renderização", + "develop.rendering.basicConcepts": "Conceitos básicos de renderização", + "develop.rendering.drawContext": "Utilizando o \"Drawing Context\"", + "develop.rendering.hud": "Renderizando a Interface", + "develop.rendering.gui": "Interface do Usuário e Telas", + "develop.rendering.gui.customScreens": "Telas Personalizadas", + "develop.rendering.gui.customWidgets": "Widgets Personalizados", + "develop.rendering.particles": "Partículas", + "develop.rendering.particles.creatingParticles": "Criando partículas", + "develop.misc": "Paginas Diversas", + "develop.misc.codecs": "Codecs", + "develop.misc.events": "Eventos", + "develop.misc.text-and-translations": "Texto e Traduções", + "develop.misc.ideTipsAndTricks": "IDE Dicas e Truques", + "develop.misc.automatic-testing": "Teste automatizado", + "develop.sounds": "Sons", + "develop.sounds.using-sounds": "Tocando \"SoundEvents\"", + "develop.sounds.custom": "Criando Sons Personalizados" +} diff --git a/versions/1.21/translated/pt_br/website_translations.json b/versions/1.21/translated/pt_br/website_translations.json new file mode 100644 index 000000000..a52cdeae9 --- /dev/null +++ b/versions/1.21/translated/pt_br/website_translations.json @@ -0,0 +1,46 @@ +{ + "authors.heading": "Autores da página", + "authors.nogithub": "%s (não no GitHub)", + "banner": "A documentação do Fabric está em desenvolvimento. Reporte problemas no %s ou no %s.", + "description": "Documentação compreensiva para Fabric, conjunto de ferramentas para mods de Minecraft.", + "footer.next": "Próxima Página", + "footer.prev": "Página Anterior", + "github_edit": "Edite essa Página no GitHub", + "lang_switcher": "Mudar o idioma", + "last_updated": "Atualizado pela última vez", + "mode_dark": "Mudar para o tema escuro", + "mode_light": "Mudar para o tema claro", + "mode_switcher": "Aparência", + "nav.contribute": "Contribuir", + "nav.contribute.api": "Fabric API", + "nav.download": "Baixar", + "nav.home": "Início", + "outline": "Nesta Página", + "return_to_top": "Voltar ao Topo", + "search.back": "Fechar busca", + "search.button": "Buscar", + "search.display_details": "Mostrar Lista Detalhada", + "search.footer.close": "para fechar", + "search.footer.close.key": "Fechar", + "search.footer.down.key": "Seta para baixo", + "search.footer.navigate": "para navegar", + "search.footer.up.key": "Seta para cima", + "search.footer.select": "para selecionar", + "search.footer.select.key": "Enter", + "search.no_results": "Sem resultados para", + "search.reset": "Redefinir busca", + "sidebar_menu": "Menu", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Documentação do Fabric", + "version_switcher": "Mudar Versão", + "404.code": "404", + "404.crowdin_link": "Localizar no Crowdin", + "404.crowdin_link.label": "Abrir no editor Crowdin", + "404.english_link": "Ler em inglês", + "404.english_link.label": "Abrir na versão em inglês", + "404.link": "Leve-me para o início", + "404.link.label": "Ir para a página inicial", + "404.quote": "Está página tentou nadar na lava", + "404.title": "Página não encontrada" +} \ No newline at end of file diff --git a/versions/1.21/translated/ru_ru/contributing.md b/versions/1.21/translated/ru_ru/contributing.md new file mode 100644 index 000000000..e23fe6db7 --- /dev/null +++ b/versions/1.21/translated/ru_ru/contributing.md @@ -0,0 +1,253 @@ +--- +title: Руководство по внесению вклада +description: Руководство по внесению вклада в документацию Fabric +--- + +# Руководство по внесению вклада {#contributing} + +Этот сайт использует [VitePress](https://vitepress.dev/) для генерации статического HTML-кода из различных Markdown-файлов. Вы можете ознакомиться с Markdown-расширениями для VitePress [здесь](https://vitepress.dev/guide/markdown#features). + +Есть три пути для внесения своего вклада для сайта: + +- [Перевод документации](#translating-documentation) +- [Вклад в содержимое](#contributing-content) +- [Как внести свой вклад](#how-to-contribute) + +Все материалы должны соответствовать нашим [рекомендациям по стилю](#style-guidelines). + +## Перевод документации {#translating-documentation} + +Если вы хотите перевести документацию на свой язык, вы можете сделать это на [странице Fabric на Crowdin](https://crowdin.com/project/fabricmc). + + + +## new-content Внесение контента {#contributing-content} + +Основной способ внести вклад в документацию Fabric — это внесение контента. + +Все материалы, добавляемые в контент, проходят следующие этапы, каждому из которых соответствует метка: + +1. локально Подготовьте свои изменения и отправьте PR +2. stage:expansion: Руководство по расширению при необходимости +3. этап:проверка: проверка содержимого +4. stage:cleanup: Грамматика, Линтер... +5. stage:ready: Готово к релизу! + +Всё содержимое должно соответствовать нашим [рекомендациям по стилю](#style-guidelines). + +### 1. Подготовьте свои изменения {#1-prepare-your-changes} + +Этот сайт с открытым исходным кодом, он разрабатывается в репозитории GitHub, что означает, что мы полагаемся на поток GitHub: + +1. [Создайте форк репозитория на GitHub](https://github.com/FabricMC/fabric-docs/fork) +2. Создайте новую ветку в вашем форке +3. Сделайте свои изменения в этой ветке +4. Откройте запрос на изменение в оригинальном репозитории (Pull Request) + +Вы можете прочитать больше о потоке GitHub [здесь](https://docs.github.com/ru/get-started/using-github/github-flow). + +Вы можете либо внести изменения из веб-интерфейса на GitHub, либо разработать и предварительно просмотреть сайт локально. + +#### Клонирование вашего форка {#clone-your-fork} + +Если вы хотите разрабатывать локально, вам нужно будет установить [Git](https://git-scm.com/). + +После этого клонируйте свой форк репозитория с помощью: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### Установка зависимостей {#install-dependencies} + +**Если вы хотите предварительно локально просматривать свои изменения, вам нужно будет установить [Node.js версии 18 или выше](https://nodejs.org/en/)**. + +После этого убедитесь, что все зависимости установлены с помощью: + +```sh +npm install +``` + +#### Запуск сервера разработки {#run-the-development-server} + +Это позволит вам предварительно просматривать ваши изменения локально по адресу `localhost:5173` и автоматически перезагрузит страницу при внесении изменений. + +```sh +npm run dev +``` + +Теперь вы можете открыть сайт и просматривать его из браузера, посетив `http://localhost:5173`. + +#### Создание веб-сайта {#building-the-website} + +Это преобразует все файлы Markdown в статические HTML-файлы и разместит их в папке `.vitepress/dist`: + +```sh +npm run build +``` + +#### Предварительный просмотр созданного веб-сайта {#previewing-the-built-website} + +Это запустит локальный сервер на порту 3000, отображающий содержимое, найденное в `.vitepress/dist`: + +```sh +npm run preview +``` + +#### Открытие запроса {#opening-a-pull-request} + +Если вы довольны своими изменениями, вы можете `push` ваши изменения: + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +Затем, зайдите по ссылке в выводе команды `git push`, чтобы открыть PR. + +### 2. stage:expansion Руководство по расширению, если необходимо {#2-guidance-for-expansion-if-needed} + +Если команда по документированию считает, что вы могли бы расширить свой запрос, один из членов команды добавит метку stage:expansion к вашему запросу на извлечение вместе с комментарием, объясняющим, что, по их мнению, вы могли бы расширить. Если вы согласны с этим предложением, вы можете дополнить свой реквест. + +Если по документированию считается, что вы могли бы расширить свой запрос, один из членов команды, добавит метку <0>stage:expansion к вашему запросу вместе с комментарием, объясняющим, что, по их мнению, нужно изменить. Затем группа по документированию добавит метку требуется помощь к вашему PR. + +### 3. stage:verification Проверка содержимого {#3-content-verification} + +Это самый важный этап, поскольку он гарантирует точность контента и его соответствие руководству по стилю Fabric Documentation. + +На этом этапе необходимо ответить на следующие вопросы: + +- Все ли содержания верно? +- Весь ли контент актуален? +- Охватывает ли контент все случаи, например, различные операционные системы? + +### 4. этап:очистка Очистка {#4-cleanup} + +На этом этапе происходит следующее: + +- Исправление любых грамматических ошибок с помощью [LanguageTool](https://languagetool.org/) +- Анализ всех файлов Markdown с помощью [`markdownlint`](https://github.com/DavidAnson/markdownlint) +- Форматирование всего кода Java с использованием [Checkstyle](https://checkstyle.sourceforge.io/) +- Другие различные исправления и улучшения + +## framework Вносящий вклад в фреймворк {#contributing-framework} + +Фреймворк относится к внутренней структуре веб-сайта. Любые запросы, которые изменяют фреймворк веб-сайта, будут помечены меткой framework. + +К вашему сведению, вы должны делать pull requests, касающиеся фреймворка, только после консультации с командой документации на [Discord-сервере Fabric](https://discord.gg/v6v4pMv) или через issue. + +:::info +Изменение файлов боковой панели и конфигурации панели навигации не считается pull request, касающимся фреймворка. +::: + +## Стандарты оформления {#style-guidelines} + +Если вы насчёт чего-то не уверены, можете задать свой вопрос в [Discord-сервере Fabric](https://discord.gg/v6v4pMv) или через GitHub Discussions. + +### Корректура (проверка грамматики и т. д.) + +Вся оригинальная документация написана на английском языке в соответствии с американскими правилами грамматики. + +### Добавляем данные в начало файла {#add-data-to-the-frontmatter} + +Все страницы должны иметь заголовок и описание. + +Не забывайте также добавлять ваше имя пользователя GitHub в поле `authors` в начале Markdown-файла! Таким образом, мы сможем отдать вам должное. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### Добавьте "Якорь" к заголовкам {#add-anchors-to-headings} + +Каждый заголовок должен иметь якорь, который используется для создания ссылки на этот заголовок: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +Якорь должен использовать строчные буквы, цифры и дефисы. + +### Разместите код внутри `/reference` мода {#place-code-within-the-reference-mod} + +Если вы создаёте или изменяете страницы, содержащие код, разместите этот код в каком-нибудь месте мода с примерами (он находится в папке `/reference` репозитория). Фрагмент кода будет выглядеть следующим образом: + +Это выведет все линии с 15 по 21 из файла `FabricDocsReference.java` из мода с примерами: + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +Затем используйте [функцию вставки кода от VitePress](https://vitepress.dev/guide/markdown#import-code-snippets), чтобы встроить код, или, если вам требуется более широкий контроль, вы можете использовать функцию [transclude из `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + +Например, это встроит секции файла выше, которые помечены тегом `#entrypoint`: + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### Создавайте боковую панель для каждого нового раздела {#create-a-sidebar-for-each-new-section} + +Если вы создаете новую категорию, вам следует создать новую боковую панель в папке `.vitepress/sidebars` и добавить её в файл `config.mts`. + +Если вам нужна помощь с этим, спросите [в дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#docs`. + +### ⚠️ **Ссылки на другие страницы должны быть относительными.** ⚠️ + +При создании новой страницы вы должны добавить ее на соответствующую боковую панель в папке `.vitepress/sidebars`. + +Опять же, если вам нужна помощь, спросите в дискорде Fabric в канале `#docs`. + +### Используйте `/assets` для хранения медиаконтента {#place-media-in-assets} + +Любые изображения должны находиться в соответствующем месте в папке `/assets`. + +### Используйте относительные ссылки! ⚠️ **Если ты ссылаешься на другие страницы, используй относительные ссылки.** ⚠️ {#use-relative-links} + +Это требуется для правильной работы системы с разными версиями, которая заранее обрабатывает ссылки для добавления версии. Если вы используете обычные ссылки, номер версии не будет добавлен к ссылке. + +Вы также не должны добавлять расширение файла к ссылке. + +Например, для страницы в папке `/players`, ссылка на страницу `installing-fabric` по пути `/players/installing-fabric.md`, вы должны сделать следующее: + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/ru_ru/develop/automatic-testing.md b/versions/1.21/translated/ru_ru/develop/automatic-testing.md new file mode 100644 index 000000000..00b615e36 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/automatic-testing.md @@ -0,0 +1,91 @@ +--- +title: Автоматизированное тестирование +description: Руководство по написанию автоматических тестов с помощью Fabric Loader JUnit. +authors: + - kevinthegreat1 +--- + +# Автоматизированное тестирование {#automated-testing} + +На этой странице объясняется, как написать код для автоматического тестирования частей вашего мода. Существует два способа автоматического тестирования вашего мода: модульные тесты с помощью Fabric Loader JUnit или игровые тесты с помощью фреймворка Gametest из Minecraft. + +Модульные тесты следует использовать для тестирования компонентов вашего кода, таких как методы и вспомогательные классы, в то время как игровые тесты запускают реальный клиент и сервер Minecraft для запуска ваших тестов, что делает их подходящими для тестирования функций и игрового процесса. + +:::warning +В настоящее время данное руководство охватывает только модульное тестирование. +::: + +## Модульное тестирование {#unit-testing} + +Поскольку моддинг Minecraft основан на инструментах модификации байт-кода во время выполнения, таких как Mixin, простое добавление и использование JUnit обычно не работает. Вот почему Fabric предоставляет Fabric Loader JUnit — плагин JUnit, который позволяет проводить модульное тестирование в Minecraft. + +### Настройка Fabric Loader JUnit {#setting-up-fabric-loader-junit} + +Сначала нам необходимо добавить Fabric Loader JUnit в среду разработки. Добавьте следующее в блок зависимостей в `build.gradle`: + +@[code lang=groovy transcludeWith=:::automatic-testing:1](@/reference/build.gradle) + +Затем нам нужно указать Gradle использовать Fabric Loader JUnit для тестирования. Это можно сделать, добавив следующий код в `build.gradle`: + +@[code lang=groovy transcludeWith=:::automatic-testing:2](@/reference/1.21/build.gradle) + +### Написание тестов {#writing-tests} + +После перезагрузки Gradle вы будете готовы писать тесты. + +Эти тесты пишутся так же, как и обычные тесты JUnit, с небольшой дополнительной настройкой, если вам нужно получить доступ к любому классу, зависящему от реестра, например `ItemStack`. Если вы знакомы с JUnit, можете перейти к разделу [Настройка реестров](#setting-up-registries). + +#### Настройка вашего первого тестового класса {#setting-up-your-first-test-class} + +Тесты пишутся в каталоге `src/test/java`. + +Одним из правил именования является отражение структуры пакета тестируемого класса. Например, чтобы протестировать `src/main/java/com/example/docs/codec/BeanType.java`, вам нужно создать класс в `src/test/java/com/example/docs/codec/BeanTypeTest.java`. Обратите внимание, как мы добавили `Test` в конец имени класса. Это также позволяет легко получить доступ к методам и полям, закрытым для пакета. + +Другое соглашение об именовании — наличие пакета `test`, например `src/test/java/com/example/docs/test/codec/BeanTypeTest.java`. Это предотвращает некоторые проблемы, которые могут возникнуть при использовании того же пакета, если вы используете модули Java. + +После создания тестового класса используйте ⌘/CTRLN, чтобы вызвать меню «Создать». Выберите Test и начните вводить имя метода, обычно начинающееся с `test`. Выберите Test и начните вводить имя метода, обычно начинающееся с `test`. Нажмите ENTER, когда закончите. Дополнительные советы и рекомендации по использованию IDE см. в разделе [Советы и рекомендации по IDE](ide-tips-and-tricks#code-generation). + +![Создание метода тестирования](/assets/develop/misc/automatic-testing/unit_testing_01.png) + +Конечно, вы можете написать сигнатуру метода вручную, и любой метод экземпляра без параметров и с типом возвращаемого значения void будет идентифицирован как тестовый метод. В итоге у вас должно получиться следующее: + +![Пустой метод тестирования с тестовыми индикаторами](/assets/develop/misc/automatic-testing/unit_testing_02.png) + +Обратите внимание на зеленые стрелки индикаторы в желобе: вы можете легко запустить тест, щелкнув по ним. В качестве альтернативы ваши тесты будут запускаться автоматически для каждой сборки, включая сборки CI такие, как GitHub Actions. Если вы используете GitHub Actions, не забудьте прочитать [Настройка GitHub Actions](#setting-up-github-actions). + +Теперь пришло время написать настоящий тестовый код. Вы можете утверждать условия, используя `org.junit.jupiter.api.Assertions`. Проверьте следующий тест: + +@[code lang=java transcludeWith=:::automatic-testing:4](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +Объяснение того, что на самом деле делает этот код, см. в [Кодеки](codecs#registry-dispatch). + +#### Настройка реестров {#setting-up-registries} + +Отлично, первый тест сработал! Но подождите, второй тест не прошёл? В журналах мы получаем одну из следующих ошибок. + +@[code lang=java transcludeWith=:::automatic-testing:5](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +Это происходит потому, что мы пытаемся получить доступ к реестру или классу, который зависит от реестра (или, в редких случаях, зависит от других классов Minecraft таких, как `SharedConstants`), но Minecraft не инициализирован. Нам нужно просто немного инициализировать его, чтобы реестры заработали. Просто добавьте следующий код в начало метода `beforeAll`. + +@[code lang=java transcludeWith=:::automatic-testing:7](@/reference/1.21/src/test/java/com/example/docs/codec/BeanTypeTest.java) + +### Настройка действий GitHub {#setting-up-github-actions} + +:::info +В этом разделе предполагается, что вы используете стандартный рабочий процесс GitHub Action, включенный в пример мода и в шаблон мода. +::: + +Теперь ваши тесты будут запускаться для каждой сборки, включая сборки поставщиков непрерывной интеграции, таких как GitHub Actions. Но что делать, если сборка не удалась? Нам необходимо загрузить журналы как артефакт, чтобы мы могли просматривать отчеты об испытаниях. + +Добавьте это в файл `.github/workflows/build.yml`, ниже шага `./gradlew build`. + +```yaml + - name: Store reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: reports + path: | + **/build/reports/ + **/build/test-results/ +``` diff --git a/versions/1.21/translated/ru_ru/develop/blocks/blockstates.md b/versions/1.21/translated/ru_ru/develop/blocks/blockstates.md new file mode 100644 index 000000000..07b3c8ee5 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/blocks/blockstates.md @@ -0,0 +1,127 @@ +--- +title: Состояния блока +description: Узнать почему состояния блока — это отличный способ добавить визуальной функциональности вашим блокам. +authors: + - IMB11 +--- + +# Состояния блока {#block-states} + +Состояния блока — это фрагмент данных, привязанный к одному блоку в мире Minecraft, содержащий информацию о блоке в виде свойств. Вот несколько примеров свойств, которые стандартный Minecraft хранит в состояниях блока: + +- Rotation: В основном используется для древесины и других природных блоков. +- Activated: Широко используется в редстоун-устройствах, а также в таких блоках, как печь или коптильня. +- Age: Используется для культур, растений, саженцев, водорослей и т.п. + +Вы, вероятно, понимаете, почему они полезны — они позволяют избежать необходимости хранения данных NBT в сущности блока, что уменьшает размер мира и предотвращает проблемы с TPS! + +Определения состояний блока можно найти в папке `assets//blockstates`. + +## Пример: Блок Колонна {#pillar-block} + + + +Minecraft уже имеет несколько пользовательских классов, которые позволяют быстро создавать определенные типы блоков. Этот пример демонстрирует создание блока со свойством `axis` на примере блока "Обтёсанная дубовая древесина". + +Стандартный класс `PillarBlock` позволяет размещать блоки вдоль осей X, Y или Z. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Колоновые блоки имеют две текстуры: верхнюю и боковую. Они используют модель `block/cube_column`. + +Как всегда, со всеми текстурами блоков, файлы текстур могут быть найдены в `assets//textures/block` + +Текстуры + +Из-за того что колоновый блок имеет две позиции: горизонтальную и вертикальную, мы должны сделать два отдельных файла моделей: + +- `condensed_oak_log_horizontal.json`, который дополняет модель `block/cube_column_horizontal`. +- `condensed_oak_log.json`, который дополняет модель `block/cube_column`. + +Пример файла `condensed_oak_log_horizontal.json`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +Для более подробного изучения всех доступных модификаторов в файле состояний блоков, ознакомьтесь со страницей [Minecraft Wiki - Models (Block States)](https://minecraft.wiki/w/Tutorials/Models#Block_states). +::: + +Далее, нам нужно создать файл состояний блока. Файл состояний блока — это где происходит магия — колоновые блоки имеют три оси, поэтому мы будем использовать конкретные модели для следующих ситуаций: + +- `axis=x` - Когда блок помещён вдоль оси X, мы повернём модель так, чтобы она была ориентирована в положительном направлении оси X. +- `axis=y` - Когда блок помещён вдоль оси Y, мы будем использовать нормальную вертикальную модель. +- `axis=z` - Когда блок помещён вдоль оси Z, мы повернём модель так, чтобы она была ориентирована в положительном направлении оси X. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +Как всегда, вам нужно создать перевод для вашего блока и модель предмета, которая будет наследовать одну из двух моделей. + +![Пример колонового блока в игре](/assets/develop/blocks/blockstates_1.png) + +## Пользовательские состояния блока {#custom-block-states} + +Пользовательские состояния блока хороши если ваш блок имеет уникальные свойства. Иногда вы можете обнаружить, что ваш блок может использовать стандартные свойства. + +Этот пример создаст уникальное boolean-свойство под названием `activated` - когда игрок нажимает ПКМ на блок, состояние блока меняется с `activated=false` на `activated=true` - соответствующим образом меняя его текстуру. + +### Создаём свойство {#creating-the-property} + +Сначала вам нужно создать свойство — так как это булево значение, мы будем использовать метод `BooleanProperty.of`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Далее нам необходимо добавить свойство к менеджеру состояний блока в методе `appendProperties`. Вам необходимо переопределить метод для доступа к конструктору: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Вам также придется установить состояние по умолчанию для свойства `activated` в конструкторе вашего пользовательского блока. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +Не забудьте зарегистрировать свой блок, используя пользовательский класс вместо `Block`! +::: + +### Использование свойства {#using-the-property} + +В этом примере булево свойство `activated` инвертируется, когда игрок взаимодействует с блоком. Для этого мы можем переопределить метод `onUse`: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### Визуализация недвижимости {#visualizing-the-property} + +Перед созданием файла состояния блока вам необходимо предоставить текстуры для активированного и деактивированного состояний блока, а также модель блока. + +Текстуры + +Используйте свои знания о моделях блоков, чтобы создать две модели блока: одну для активированного состояния и одну для деактивированного состояния. После этого можно приступать к созданию файла blockstate. + +Поскольку вы создали новое свойство, вам необходимо обновить файл blockstate для блока, чтобы учесть это свойство. + +Если в блоке имеется несколько свой блока, вам необходимо учитывать все возможные комбинации. Например, «activated» и «axis» приведут к 6 комбинациям (два возможных значения для «activated» и три возможных значения для «axis»). + +Поскольку этот блок имеет только два возможных варианта, поскольку у него есть только одно свойство (`activated`), JSON-код состояния блока будет выглядеть примерно так: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +Поскольку пример блока представляет собой лампу, нам также необходимо заставить ее излучать свет, когда свойство `activated` имеет значение true. Это можно сделать с помощью настроек блока, передаваемых конструктору при регистрации блока. + +Вы можете использовать метод `luminance` для установки уровня освещенности, излучаемой блоком. Мы можем создать статический метод в классе `PrismarineLampBlock` для возврата уровня освещенности на основе свойства `activated` и передать его как ссылку на метод `luminance`: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +После того как вы все завершите, конечный результат должен выглядеть примерно так: + + diff --git a/versions/1.21/translated/ru_ru/develop/blocks/first-block.md b/versions/1.21/translated/ru_ru/develop/blocks/first-block.md new file mode 100644 index 000000000..b9ebe10ed --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/blocks/first-block.md @@ -0,0 +1,166 @@ +--- +title: Создание вашего первого блока +description: Научитесь создавать собственные блоки в Minecraft. +authors: + - IMB11 +--- + +# Создание вашего первого блока {#creating-your-first-block} + +Блоки являются основой строительства в Minecraft. Как и всё здесь, блоки хранятся в реестрах. + +## Подготовка класса вашего блока {#preparing-your-blocks-class} + +Если вы прошли туториал [Создание первого предмета](../items/first-item), этот процесс будет вам хорошо знаком. Необходимо создать метод для регистрации блока и предмета блока. + +Поместите этот метод в класс `ModBlocks` (или как вы его назовете). + +Что-то подобное Mojang делают с ванильными блоками. Вы можете обратиться к классу `Blocks`, чтобы увидеть, как они это делают. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Как и в случае с предметами, необходимо убедиться, что класс загружен, чтобы все статические поля с экземплярами ваших блоков были инициализированы. + +Это можно сделать, создав пустой метод `initialize`, который может быть вызван в инициализаторе вашего мода, чтобы запустить статическую инициализацию. + +:::info +Если вы не знаете, что такое статическая инициализация, это процесс инициализации статических полей в классе. Она выполняется, когда JVM загружает класс, и завершается до создания какого-либо экземпляра класса. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## Создание и регистрация вашего блока {#creating-and-registering-your-block} + +Подобно предметам, блоки имеют в своем конструкторе класс `Blocks.Settings`, который определяет такие свойства блока как его звуковые эффекты и уровень добычи. + +Мы не будем рассматривать здесь все настройки, вы можете сами заглянуть в класс, чтобы увидеть их варианты, которые говорят сами за себя. + +Для примера мы создадим простой блок, который имеет свойства земли, но представляет другой материал. + +:::tip +Вы можете использовать `AbstractBlock.Settings.copy(AbstractBlock block)`, чтобы скопировать параметры существующего блока. В данном случае мы могли бы использовать `Blocks.DIRT` для копирования параметров блока земли, но для примера мы используем конструктор. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Для автоматического создания предмета блока мы можем передать `true` параметру `shouldRegisterItem` метода `register`, который мы создали на предыдущем шаге. + +### Добавление вашего блока в группу предметов {#adding-your-block-to-an-item-group} + +Поскольку `BlockItem` был создан и зарегистрирован автоматически, для добавления его в группу элементов необходимо использовать метод `Block.asItem()` для получения экземпляра `BlockItem`. + +Для этого примера мы используем пользовательскую группу предметов, созданную на странице [Собственные вкладки предметов](../items/custom-item-groups). + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +После этого ваш блок появится в творческом инвентаре, и вы сможете разместить его в мире! + +![Блок без модели и текстуры](/assets/develop/blocks/first_block_0.png). + +Осталось несколько проблем: предмет блока не имеет названия, а блок не имеет текстуры, модели блока и модели предмета. + +## Добавление переводов блоков {#adding-block-translations} + +Чтобы добавить перевод, необходимо создать ключ перевода в файле перевода - `assets//lang/en_us.json`. + +Minecraft будет использовать этот перевод в творческом инвентаре и других местах, где отображается название блока, например, в качестве ответе команды. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +Вы можете перезапустить игру или создать свой мод и нажать F3 + T, чтобы применить изменения. После этого вы увидите, что у блока есть имя в творческом инвентаре и других местах, например на экране статистики. + +## Модели и текстуры {#models-and-textures} + +Все текстуры блоков можно найти в папке `assets//textures/block` - пример текстуры для блока «Condensed Dirt» доступен для бесплатного использования. + + + +Чтобы текстура отображалась в игре, необходимо создать блок и модель предмета, которые можно найти в соответствующих местах для блока «Condensed Dirt»: + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +Модель элемента довольно проста, она может просто использовать модель блока в качестве родительской, поскольку большинство моделей блоков поддерживают визуализацию в графическом интерфейсе: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +Однако в нашем случае модель блока должна быть родительской для модели `block/cube_all`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +При загрузке игры вы можете заметить, что текстура по-прежнему отсутствует. Это связано с тем, что вам необходимо добавить определение состояния блока. + +## Создание определения состояния блока {#creating-the-block-state-definition} + +Определение blockstate используется для указания игре, какую модель следует визуализировать на основе текущего состояния блока. + +Для примера блок, который не имеет сложного состояния, в определении требуется только одна запись. + +Этот файл должен находиться в папке `assets/mod_id/blockstates`, а его имя должно совпадать с идентификатором блока, использованным при регистрации вашего блока в классе `ModBlocks`. Например, если идентификатор блока — `condensed_dirt`, файл должен называться `condensed_dirt.json`. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +Состояния блоков действительно сложны, поэтому они рассматриваются на следующей странице: [Состояния блоков](./blockstates) + +Перезапустите игру или перезагрузите только assets с помощью F3 + T, чтобы применить изменения. Вы должны будете увидеть текстуру блока в инвентаре и в мире: + +![Block in world with suitable texture and model](/assets/develop/blocks/first_block_4.png) + +## Добавление выпадения для блоков {#adding-block-drops} + +При разрушении блока в режиме выживания вы можете увидеть, что блок не выпадает. Возможно для этого вам понадобится эта функция, однако, чтобы блок выпадал как предмет при разрушении, необходимо реализовать его таблицу добычи. Файл таблицы добычи должен быть помещен в папку `data//loot_table/blocks/`. + +:::info +Для более глубокого понимания таблиц добычи вы можете обратиться к официальной странице [Minecraft Wiki - Loot Tables](https://minecraft.wiki/w/Loot_table). +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +В таблице добычи указано, какой предмет выпадет из блока, когда блок сломан и когда он взорван взрывом. + +## Рекомендация по выбору инструмента для сбора {#recommending-a-harvesting-tool} + +Вы также можете захотеть, чтобы ваш блок можно было собирать только определенным инструментом — например, вы можете захотеть ускорить сбор с помощью лопаты. + +Все теги инструментов должны быть помещены в папку `data/minecraft/tags/block/mineable/`, где имя файла зависит от типа используемого инструмента, одного из следующих: + +- `hoe.json` +- `axe.json` +- `pickaxe.json` +- `shovel.json` + +Содержимое файла довольно простое — это список элементов, которые следует добавить в теге. + +В этом примере, блок «Condensed Dirt» добавляется к тегу `shovel`. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +## Уровни добычи {#mining-levels} + +Аналогично тег уровня добычи можно найти в той же папке, он имеет следующий формат: + +- `needs_stone_tool.json` - Минимальный уровень: каменные инструменты +- `needs_iron_tool.json` - Минимальный уровень: железные инструменты +- `needs_diamond_tool.json` - Минимальный уровень: алмазные инструменты. + +Файл имеет тот же формат, что и файл инструмента для сбора — список элементов, которые необходимо добавить в теге. + +## Дополнительные заметки {#extra-notes} + +Если вы добавляете в свой mod несколько блоков, вы можете рассмотреть возможность использования [Генерации данных](https://fabricmc.net/wiki/tutorial:datagen_setup) для автоматизации процесса создания моделей блоков и предметов, определений состояний блоков и таблиц добычи. diff --git a/versions/1.21/translated/ru_ru/develop/codecs.md b/versions/1.21/translated/ru_ru/develop/codecs.md new file mode 100644 index 000000000..083d8d95e --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/codecs.md @@ -0,0 +1,396 @@ +--- +title: Кодеки +description: Исчерпывающее руководство по пониманию и использованию системы кодеков Mojang для сериализации и десериализации объектов. +authors: + - enjarai + - Syst3ms +--- + +# Кодеки {#codecs} + +Codec — это система для простой сериализации объектов Java, входящая в библиотеку DataFixerUpper (DFU) от Mojang, которая включена в Minecraft. В контексте разработки модов они могут использоваться в качестве альтернативы GSON и Jankson при чтении и записи пользовательских JSON-файлов и их значение со временем растёт, поскольку Mojang переписывает множество старого кода с использованием Codec. + +Кодеки используются вместе с другим API из DFU — `DynamicOps`. Кодек определяет структуру объекта, в то время как динамические операции (dynamic ops) используются для определения формата, в который и из которого происходит сериализация, например JSON или NBT. Это означает, что любой кодек может быть использован с любыми динамическими операциями и наоборот, что обеспечивает большую гибкость. + +## Использование кодеков {#using-codecs} + +### Сериализация и десериализация {#serializing-and-deserializing} + +Основное использование кодека — это сериализация и десериализация объектов в определённый формат и из него. + +Поскольку для некоторых стандартных классов уже определены кодеки, мы можем использовать их в качестве примера. Mojang также предоставила нам два класса динамических операций по умолчанию: `JsonOps` и `NbtOps`, которые охватывают большинство случаев использования. + +Итак, допустим, мы хотим сериализовать `BlockPos` в JSON и обратно. Для этого мы можем использовать кодек, статически хранящийся в `BlockPos.CODEC`, используя такие его методы как `Codec#encodeStart` и `Codec#parse`. + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// Сериализуем BlockPos в JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +Когда мы используем кодек, возвращаемые данные будут в виде `DataResult`. Это оболочка, которая может означать как успешное, так и неудачное выполнение. Мы можем пойти разными путями: если нам просто нужно наше сериализованное значение, `DataResult#result` просто вернёт `Optional`, содержащий наше значение, в то время как `DataResult#resultOrPartial` также позволяет нам добавить обработку ошибок, которые могли бы произойти в процессе. Последнее особенно полезно для своих ресурсов для наборов данных, где мы хотим журналировать ошибки без создания проблем в других местах. + +Итак, теперь возьмём сериализованное нами значение и превратим его обратно в `BlockPos`: + +```java +// При реальном написании мода вам, конечно, нужно правильно обрабатывать пустые Optionals +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// Здесь у нас есть наше JSON-значение, которое должно соответствовать `[1, 2, 3]`, +// так как это формат, используемый кодеком BlockPos. +LOGGER.info("Serialized BlockPos: {}", json); + +// Теперь десериализуем JsonElement обратно в BlockPos +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// Снова просто получаем наше значение из результата +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// И мы видим, что успешно сериализовали и десериализовали наш BlockPos! +LOGGER.info("Десериализованный BlockPos: {}", pos); +``` + +### Встроенные кодеки {#built-in-codecs} + +Как упоминалось ранее, Mojang уже определила кодеки для нескольких стандартных и Java-классов, включая, но не ограничиваясь, `BlockPos`, `BlockState`, `ItemStack`, `Identifier`, `Text` и шаблоны (`Pattern`) регулярных выражений. Кодеки для собственных классов Mojang обычно можно найти в статических полях с именем `CODEC` в самом классе, в то время как большинство других кодеков содержатся в классе `Codecs`. Также следует отметить, что все стандартные реестры содержат метод `getCodec()`. Например, вы можете использовать `Registries.BLOCK.getCodec()`, чтобы получить `Codec`, который сериализует идентификатор блока и обратно. + +Сам API Codec также содержит некоторые кодеки для примитивных типов, такие как `Codec.INT` и `Codec.STRING`. Они доступны как статические поля в классе Codec и обычно используются как основа для более сложных кодеков, как объясняется ниже. + +## Сборка кодеков {#building-codecs} + +Теперь, когда мы увидели, как использовать кодеки, давайте посмотрим, как мы можем собрать свои собственные. Предположим, у нас есть следующий класс, и мы хотим десериализовать его экземпляры из JSON-файлов: + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +Соответствующий JSON-файл может выглядеть примерно так: + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +Мы можем создать кодек для этого класса, объединив несколько меньших кодеков в один большой. В данном случае нам понадобится по одному кодеку для каждого поля: + +- `Codec` +- `Codec` +- `Codec>` + +Мы можем получить первый из упомянутых ранее примитивных кодеков в классе `Codec`, а именно `Codec.INT`. Второй можно получить из реестра `Registries.ITEM`, который имеет метод `getCodec()`, возвращающий `Codec`. У нас нет стандартного кодека для `List`, но мы можем создать его из `BlockPos.CODEC`. + +### Списки {#lists} + +Метод `Codec#listOf` можно использовать для создания версии кодека для списка любого типа: + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +Следует отметить, что кодеки, созданные таким образом, всегда будут десериализоваться в `ImmutableList`. Если вам нужна изменяемая (mutable) коллекция, вы можете воспользоваться [xmap](#mutually-convertible-types) для преобразования её при десериализации. + +### Объединение кодеков для классов, похожих на Record {#merging-codecs-for-record-like-classes} + +Теперь, когда у нас есть отдельные кодеки для каждого поля, мы можем объединить их в один кодек для нашего класса, используя `RecordCodecBuilder`. Это предполагает, что наш класс имеет конструктор, содержащий каждое поле, которое мы хотим сериализовать, и что для каждого поля есть соответствующий метод доступа (геттер). Это делает его идеальным для использования вместе с записями (records), но он также может быть использован с обычными классами. + +Давайте посмотрим, как создать кодек для нашего `CoolBeansClass`: + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // Здесь можно объявить до 16 полей +).apply(instance, CoolBeansClass::new)); +``` + +Каждая строка в группе указывает кодек, имя поля и метод доступа. Вызов `Codec#fieldOf` используется для преобразования кодека в [MapCodec](#mapcodec), а `forGetter` указывает метод, используемый для получения значения поля из экземпляра класса. Между тем, вызов `apply` указывает конструктор, используемый для создания новых экземпляров. Обратите внимание, что порядок полей в группе должен совпадать с порядком аргументов в конструкторе. + +Вы также можете использовать `Codec#optionalFieldOf` в этом контексте, чтобы сделать поле необязательным, как объясняется в разделе [«Необязательные поля»](#optional-fields). + +### MapCodec, не путать с Codec&lt;Map&gt; {#mapcodec} + +Вызов `Codec#fieldOf` преобразует `Codec` в `MapCodec`, который является вариантом, но не прямой реализацией `Codec`. `MapCodec`, как следует из названия, гарантированно сериализуется в карту «ключ-значение» или её эквивалент в используемых `DynamicOps`. Некоторые функции могут требовать именно MapCodec вместо обычного кодека. + +Этот способ создания `MapCodec` по сути оборачивает значение исходного кодека внутри карты, используя указанное имя поля в качестве ключа. Например, `Codec`, когда сериализуется в JSON, выглядел бы так: + +```json +[1, 2, 3] +``` + +Но при преобразовании в `MapCodec` с помощью `BlockPos.CODEC.fieldOf("pos")` он будет выглядеть так: + +```json +{ + "pos": [1, 2, 3] +} +``` + +Хотя наиболее распространённое использование MapCodec — объединение с другими MapCodec для построения кодека для полного класса полей, как объясняется в разделе [«Объединение кодеков для классов, похожих на Record»](#merging-codecs-for-record-like-classes) выше, они также могут быть преобразованы обратно в обычные кодеки с помощью `MapCodec#codec`, который сохранит то же поведение оборачивания их входного значения. + +#### Необязательные поля {#optional-fields} + +`Codec#optionalFieldOf` можно использовать для создания необязательного MapCodec. Это означает, что когда указанное поле отсутствует в контейнере при десериализации, оно будет десериализовано как пустой Optional или заданное значение по умолчанию. + +```java +// Без значения по умолчанию +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// Со значением по умолчанию +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +Обратите внимание, что необязательные поля будут молча игнорировать любые ошибки, которые могут возникнуть при десериализации. Это означает, что если поле присутствует, но значение недопустимо, поле всегда будет десериализовано как значение по умолчанию. + +**Начиная с версии 1.20.2**, сам Minecraft (не DFU!) предоставляет `Codecs#createStrictOptionalFieldCodec`, который вовсе не удаётся десериализовать, если значение поля недопустимо. + +### Константы, ограничения и композиция {#constants-constraints-composition} + +#### Unit {#unit} + +`Codec.unit` можно использовать для создания кодека, который всегда десериализуется в постоянное значение, независимо от входных данных. При сериализации он ничего не будет делать. + +```java +Codec theMeaningOfCodec = Codec.unit(42); +``` + +#### Числовые диапазоны {#numeric-ranges} + +`Codec.intRange` и его аналоги, `Codec.floatRange` и `Codec.doubleRange`, можно использовать для создания кодека, который принимает только числовые значения в заданном **включающем** диапазоне. Это применяется как к сериализации, так и к десериализации. + +```java +// Не может быть больше 2 +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Пары {#pair} + +`Codec.pair` объединяет два кодека, `Codec
` и `Codec`, в `Codec>`. Имейте в виду, что это работает правильно только с кодеками, которые сериализуются в определённое поле, такие как [преобразованные `MapCodec`](#mapcodec) или [record-кодеки](#merging-codecs-for-record-like-classes). +Полученный кодек будет сериализоваться в карту, объединяющую поля обоих используемых кодеков. + +Например, запуск такого кода: + +```java +// Создаём два отдельных коробочных кодека +Codec firstCodec = Codec.INT.fieldOf("i_am_number").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("this_statement_is_false").codec(); + +// Объединяем их в пару кодеков +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// Используем её для сериализации данных +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +Выведет следующий JSON: + +```json +{ + "i_am_number": 23, + "this_statement_is_false": true +} +``` + +#### Either {#either} + +`Codec.either` объединяет два кодека, `Codec` и `Codec`, в `Codec>`. Полученный кодек при десериализации попытается использовать первый кодек, и _только если это не удастся_, попытается использовать второй. +Если второй также не справится, будет возвращена ошибка _второго_ кодека. + +#### Карты {#maps} + +Для обработки карт с произвольными ключами, таких как `HashMap`, можно использовать `Codec.unboundedMap`. Это возвращает `Codec>` для заданных `Codec` и `Codec`. Полученный кодек будет сериализоваться в объект JSON или любой эквивалент, доступный для текущих динамических операций. + +Из-за ограничений JSON и NBT, используемый кодек ключа _должен_ сериализоваться в строку. Это включает кодеки для типов, которые сами по себе не являются строками, но сериализуются в них, такие как `Identifier.CODEC`. Смотрите пример ниже: + +```java +// Создаём кодек для карты идентификаторов к целым числам +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// Используем его для сериализации данных +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "number"), 23, + new Identifier("example", "the_cooler_number"), 42 +)); +``` + +Это выведет следующий JSON: + +```json +{ + "example:number": 23, + "example:the_cooler_number": 42 +} +``` + +Как вы можете видеть, это работает, потому что `Identifier.CODEC` сериализуется непосредственно в строковое значение. Похожий эффект можно достичь для простых объектов, которые не сериализуются в строки, используя [xmap и другие функции](#mutually-convertible-types) для их преобразования. + +### Взаимно преобразуемые типы {#mutually-convertible-types} + +#### `xmap` {#xmap} + +Предположим, у нас есть два класса, которые могут быть преобразованы друг в друга, но не имеют отношения наследования. Например, стандартные `BlockPos` и `Vec3d`. Если у нас есть кодек для одного, мы можем использовать `Codec#xmap`, чтобы создать кодек для другого, указав функцию преобразования для каждого направления. + +`BlockPos` уже имеет кодек, но предположим, что его нет. Мы можем создать его, основываясь на кодеке для `Vec3d`, следующим образом: + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // Преобразование Vec3d в BlockPos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // Преобразование BlockPos в Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// При преобразовании существующего класса (например, `X`) +// в ваш собственный класс (`Y`) таким образом, может быть полезно +// добавить методы `toX` и статический `fromX` в `Y` и использовать +// ссылки на методы в вашем вызове `xmap`. +``` + +#### flatComapMap, comapFlatMap и flatXMap {#flatcomapmap-comapflatmap-flatxmap} + +`Codec#flatComapMap`, `Codec#comapFlatMap` и `flatXMap` похожи на xmap, но они позволяют одной или обеим функциям преобразования возвращать DataResult. Это полезно на практике, потому что конкретный экземпляр объекта может быть не всегда допустим для преобразования. + +Возьмём, например, стандартные идентификаторы (`Identifier`). Хотя все идентификаторы можно превратить в строки, не все строки являются допустимыми идентификаторами, поэтому при неудачном преобразовании использование xmap приведёт к тому, что вы столкнётесь с некрасивыми исключениями. +Из-за этого его встроенный кодек на самом деле является `comapFlatMap` на `Codec.STRING`, что хорошо иллюстрирует, как его использовать: + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Недопустимое местоположение ресурса: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +Хотя эти методы действительно полезны, их названия немного сбивают с толку, поэтому вот таблица, которая поможет вам запомнить, какой из них использовать: + +| Метод | A → B всегда допустимо? | B → A всегда допустимо? | +| ----------------------- | ----------------------- | ----------------------- | +| `Codec#xmap` | Да | Да | +| `Codec#comapFlatMap` | Нет | Да | +| `Codec#flatComapMap` | Да | Нет | +| `Codec#flatXMap` | Нет | Нет | + +### Диспетчер реестров {#registry-dispatch} + +`Codec#dispatch` позволяет нам определить реестр кодеков и направлять к конкретному кодеку на основе значения поля в сериализованных данных. Это очень полезно при десериализации объектов, которые имеют разные поля в зависимости от их типа, но всё же представляют одно и то же. + +Например, предположим, у нас есть абстрактный интерфейс `Bean` с двумя реализующими классами: `StringyBean` и `CountingBean`. Чтобы сериализовать их с помощью диспетчера реестров, нам понадобится несколько вещей: + +- Отдельные кодеки для каждого типа бобов (beans; как мы их назвали ранее); +- Класс или запись `BeanType`, представляющий тип боба и способный возвращать кодек для него; +- Функция в `Bean` для получения его `BeanType`; +- Карта или реестр для сопоставления `идентификаторов` с `BeanType`; +- `Codec>`, основанный на этом реестре. Если вы используете `net.minecraft.registry.Registry`, его можно легко создать с помощью `Registry#getCodec`. + +Имея всё это, мы можем создать кодек диспетчера реестров для бобов: + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// Теперь мы можем создать кодек для типов бобов +// на основе ранее созданного реестра +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// И на основе этого, вот наш кодек диспетчера реестра для бобов! +// Первый аргумент — это имя поля для типа боба. +// Если его не указать, по умолчанию будет «type». +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::codec); +``` + +Наш новый кодек будет сериализовать наши бобы в JSON следующим образом, захватывая только поля, которые относятся к их конкретному типу: + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "Этот боб — строка!" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### Рекурсивные кодеки {#recursive-codecs} + +Иногда бывает полезно иметь кодек, который использует сам себя для декодирования определённых полей, например, при работе с некоторыми рекурсивными структурами данных. В стандартном коде это используется для объектов `Text`, которые могут хранить другие `Text` как дочерние. Такой кодек можно построить с помощью `Codec#recursive`. + +Например, давайте попробуем сериализовать односвязный список. Этот способ представления списков состоит из набора узлов, которые хранят значение и ссылку на следующий узел в списке. Список представлен своим первым узлом, и обход списка осуществляется путём следования по следующему узлу, пока они не закончатся. Вот простая реализация узлов, которые хранят целые числа: + +```java +public record ListNode(int value, ListNode next) {} +``` + +Мы не можем создать кодек для этого обычными средствами, потому что какой кодек мы будем использовать для поля `next`? Нам нужен `Codec`, который мы как раз и пытаемся создать! `Codec#recursive` позволяет нам достичь этого, используя «волшебную» лямбду: + +```java +Codec codec = Codec.recursive( + "ListNode", // имя для кодека + selfCodec -> { + // Здесь `selfCodec` представляет `Codec`, как если бы он уже был создан + // Эта лямбда должна возвращать кодек, который мы хотим использовать, и который ссылается на себя через `selfCodec` + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // поле `next` будет обрабатываться рекурсивно с помощью `selfCodec` + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +Сериализованный `ListNode` может выглядеть так: + +```json +{ + "value": 2, + "next": { + "value": 3, + "next": { + "value": 5 + } + } +} +``` + +## Ссылки {#references} + +- Более полную документацию по кодекам и связанным API можно найти в [неофициальной Java-документации DFU](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec); +- Общая структура этого руководства была сильно вдохновлена [страницей о кодеках на Forge Community Wiki](https://forge.gemwire.uk/wiki/Codecs), более специфичным для Forge подходом к той же теме. diff --git a/versions/1.21/translated/ru_ru/develop/commands/arguments.md b/versions/1.21/translated/ru_ru/develop/commands/arguments.md new file mode 100644 index 000000000..c4f7bf8ca --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/commands/arguments.md @@ -0,0 +1,64 @@ +--- +title: Аргументы команд +description: Узнайте, как создавать команды со сложными аргументами. +--- + +# Аргументы команд {#command-arguments} + +Большинство команд используют аргументы. Иногда они могут быть необязательными, что означает, что команда выполнится, даже если вы не предоставите этот аргумент. Один узел может иметь несколько типов аргументов, но будьте внимательны, чтобы избежать неоднозначности. + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +В этом случае после текста команды `/command_with_arg` следует ввести целое число. Например, если вы запустите `/command_with_arg 3`, вы получите сообщение: + +> Вызывается /command_with_arg со значением = 3 + +Если ввести /command_with_arg без аргументов, команду не удастся правильно обработать. + +Далее мы добавим необязательный второй аргумент: + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Теперь вы можете указать одно или два целых числа. Если вы укажете одно число, будет выведено сообщение с одним значением. Если вы укажете два числа, будет выведено сообщение с двумя значениями. + +Возможно, вам покажется излишним дважды указывать схожие исполнения. Поэтому мы можем создать метод, который будет использоваться в обоих случаях. + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Собственные типы аргументов {#custom-argument-types} + +Если в стандартной библиотеке нет нужного вам типа аргументов, вы можете создать свой. Для этого нужно создать класс, который наследуется от интерфейса `ArgumentType`, где `T` — это тип аргумента. + +Вам нужно будет реализовать метод `parse`, который преобразует входную строку в нужный тип. + +Например, вы можете создать тип аргумента, который преобразует строку в `BlockPos` с форматом: `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Регистрация своих типов аргументов {#registering-custom-argument-types} + +:::warning +Необходимо зарегистрировать свой тип аргументов как на сервере, так и на клиенте, иначе команда не будет работать! +::: + +Вы можете зарегистрировать свой тип аргументов в методе `onInitialize` вашего инициализатора мода, используя класс `ArgumentTypeRegistry`: + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Использование своих типов аргументовs {#using-custom-argument-types} + +Мы можем использовать наш собственный тип аргумента в команде, передав его экземпляр в метод `.argument` при создании команды. + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Выполнив команду, мы можем проверить, работает ли наш тип аргумента: + +![Недопустимый аргумент](/assets/develop/commands/custom-arguments_fail.png) + +![Допустимый аргумент](/assets/develop/commands/custom-arguments_valid.png) + +![Результат команды](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/ru_ru/develop/commands/basics.md b/versions/1.21/translated/ru_ru/develop/commands/basics.md new file mode 100644 index 000000000..cb42f94f1 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/commands/basics.md @@ -0,0 +1,175 @@ +--- +title: Создание команд +description: Создавайте команды со сложными аргументами и действиями. +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple +--- + +# Создание команд {#creating-commands} + +Создание команд позволяет разработчику мода добавлять функционал, который может быть использован при вызове команд. Это руководство научит вас регистрировать команды и общую структуру команд Brigadier. + +::: info +Brigadier is a command parser and dispatcher written by Mojang for Minecraft. It is a tree-based command library where +you build a tree of commands and arguments. + +Исходный код библиотеки Brigadier: +::: + +## Интерфейс `Command` {#the-command-interface} + +`com.mojang.brigadier.Command` это функциональный интерфейс, который запускает конкретный код, и исключает `CommandSyntaxException` в определённых случаях. Он имеет общий тип `S`, который определяет тип _источник команды_. +Источник команды предоставляет контекст, в котором была запущена команда. В Майнкрафт, источником команды является `ServerCommandSource` который может представлять сервер, командному блоку, удалённому соединению(RCON), игроку или сущности. + +Единственный метод в `Command`, это `run(CommandContext)` он берёт `CommandContext` в качестве единственного аргумента и возвращает целое число. Командный контекст содержит источник вашей команды как `S` и позволяет получить аргументы, посмотрите на разобранные командные ноды и увидите вводные данные, используемые в этой команде. + +Как и другие функциональные интерфейсы, этот используется постоянно как лямбда или ссылка на метод: + +```java +Command command = context -> { + return 0; +}; +``` + +Целое число может быть результатом команды. Обычно значения меньше или равные нулю означают, что команда не выполнена и ничего не сделает. Позитивные значения означают, что команда успешно выполнилась и что-то выполнила. Brigadier предоставляет константу для обозначения успеха; `Command#SINGLE_SUCCESS`. + +### Что может делать \`ServerCommandSource? {#what-can-the-servercommandsource-do} + +`ServerCommandSource` предоставляет дополнительный контекст когда команда выполняется. Это добавляет возможность получить сущность которая выполнила команду, мир в котором команда выполнилась команда или сервер на котором запустилась команда. + +Вы можете получить командный источник из командного контекста при вызове `getSource()` в экземпляре `CommandContext`. + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## Регистрация основной команды {#registering-a-basic-command} + +Команды регистрируются в `CommandRegistrationCallback`, предоставляемый Fabric API. + +:::info +Сведения о регистрации обратных вызовов смотрите в [События](../events). +::: + +Событие должно быть зарегистрировано в вашем [инициализаторе мода](./getting-started/project-structure#entrypoints). + +Обратный вызов имеет три аргумента: + +- `CommandDispatcher dispatcher` - используется для регистрации, парсинга и выполнения команд. `S` - это тип источника команд, который поддерживает диспатчер команд. +- `CommandRegistryAccess registryAccess` - предоставляет абстракцию которую можно передать определённой команде методы аргументов +- `CommandManager.RegistrationEnvironment environment` - Определяет тип сервера, на котором регистрируются команды. + +В инициализаторе мода мы просто регистрируем простую команду: + +@[code lang=java transcludeWith=:::test_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +В методе`sendFeedback()`, первый аргумент это текст для отправки, который является `Supplier`, чтобы избежать создание экземпляров текстовых объектов когда они не нужны. + +Второй аргумент определяет, следует ли транслировать обратную связь с другими операторами. Обычно, если команда предназначена для запроса чего-либо без затрагивания мира, например запросить текущее время или счёт игрока, оно должно быть `false`. Если команда делает что-либо, например изменение времени или изменение чего-либо счёт, оно должно быть `true`. + +Если команда не выполняется, вместо вызова `sendFeedback()`, вы напрямую можете выбросить любое исключение и сервер или клиент справится с этим соответствующим образом. + +`CommandSyntaxException` обычно выбрасывается для обозначения синтаксических ошибок в команде или в аргументах. Вы можете так же имплементировать своё исключение. + +Чтобы выполнить эту команду, необходимо ввести `/test_command`, при этом регистр символов имеет значение. + +:::info +С этого момента мы будем извлекать логику, написанную в лямбде, передаваемой в сборщики `.execute()`, в отдельные методы. Затем мы можем передать ссылку на метод в `.execute()`. Это сделано для ясности. +::: + +### Регистрационная среда {#registration-environment} + +При желании вы так же можете сделать так, чтобы когда команда регистрировалась с определёнными условиями, например только в выделенной среде: + +@[code lang=java highlight={2} transcludeWith=:::dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Требования к команде {#command-requirements} + +Допустим, что у вас есть команда и вы хотите чтобы её могли выполнять только операторы. Здесь метод `requires()` вступает в игру. Метод `requires()` имеет один аргумент `Predicate` который будет предоставлять `ServerCommandSource` для проверки возможности `CommandSource` выполнять команду. + +@[code lang=java highlight={3} transcludeWith=:::required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Команда выполнится только, если источник команды имеет второй уровень минимально, включая команду блоков. Иначе, команда не зарегистрируется. + +Побочным эффектом этого является то, что эта команда не показывается при завершение всем игрокам кто не имеет второй уровень оператора. Это также объясняет почему вы не можете выполнить большинство команда, когда не включены читы. + +### Подкоманды {#sub-commands} + +Чтобы добавить подкоманду, вы должны зарегистрировать первый литеральный нод команды. Чтобы иметь подкоманду, вы должны добавить следующий литеральный нод к существующему ноду. + +@[code lang=java highlight={3} transcludeWith=:::sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Подобно аргументам, ноды подкоманд могут также быть опциональными. В следующем случае будут допустимы как `/command_two`, так и `/command_two sub_command_two`. + +@[code lang=java highlight={2,8} transcludeWith=:::sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Клиентские команды {#client-commands} + +Fabric API имеет `ClientCommandManager` в пакете`net.fabricmc.fabric.api.client.command.v2` который можно использовать для регистрации команд на клиентской стороне. Код должен существовать только в коде клиентской стороны. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## Перенаправление команд {#command-redirects} + +Перенаправление команд - также известное как псевдонимы - это способ перенаправить функционал одной команды к другой. Это полезно, если вы хотите изменить название команды, но всё равно хотите поддерживать старое название. + +:::warning +Brigadier [будет перенаправлять только командные узлы с аргументами](https://github.com/Mojang/brigadier/issues/46). Если вы хотите перенаправить командный узел без аргументов, предоставьте конструктор `.executes()` со ссылкой на ту же логику, что описана в примере. +::: + +@[code lang=java transcludeWith=:::redirect_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_redirected_by](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## ЧАВО {#faq} + +### Почему мой код не компилируется? {#why-does-my-code-not-compile} + +- Словите или выбросите `CommandSyntaxException` - `CommandSyntaxException`- это не `RuntimeException`. Если вы выбросите это, то оно должно быть в методах, которые выбрасывают `CommandSyntaxException` в сигнатурном методе, или его нужно будет поймать. + Brigadier обработает проверенные исключение и отправит вам сообщение об ошибке в игре. + +- Время от времени у вас могут возникать проблемы с джинериками. Если вы регистрируете серверные команды (в большинстве случаев), убедитесь, что вы используете `CommandManager.literal` или `CommandManager.argument` вместо `LiteralArgumentBuilder.literal` или `RequiredArgumentBuilder.argument`. + +- Проверьте метод `sendFeedback()` - Возможно вы забыли указать логическое значение как второй аргумент. Также помните что, начиная с версии Майнкрафта 1.20, первым аргументом должен быть `Supplier` вместо `Text`. + +- Команда должна возвращать целое число - При регистрации команд, метод `executes()` принимает объект `Command`, обычно это лямбда. Лямбда должна возвращать только целое число. + +### Могу я зарегистрировать команды во время выполнения? {#can-i-register-commands-at-runtime} + +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +После этого вам нужно опять отправить команду tree ко всем игрокам используя `CommandManager.sendCommandTree(ServerPlayerEntity)`. + +Это необходимо, поскольку клиент локально кэширует команду tree, которую он получает во время логина (или когда пакеты оператора отправлены) для локальных сообщений об ошибках с большим дополнением. +::: + +### Могу я отменить регистрацию команд во время выполнения? {#can-i-unregister-commands-at-runtime} + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +Для простоты, вы должны использовать отражение Brigadier и удалить ноды. После этого, вам нужно отправить команду tree каждому игроку заново используя `sendCommandTree(ServerPlayerEntity)`. + +Если вы не будете отправлять обновления команде tree, клиент может всё ещё подумать, что команда существует, хотя сервер провалит его выполнение. +::: diff --git a/versions/1.21/translated/ru_ru/develop/commands/suggestions.md b/versions/1.21/translated/ru_ru/develop/commands/suggestions.md new file mode 100644 index 000000000..e94b2bf74 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/commands/suggestions.md @@ -0,0 +1,49 @@ +--- +title: Предложения по командам +description: Узнайте, как предлагать пользователям значения аргументов команд. +authors: + - IMB11 +--- + +# Предложения по командам {#command-suggestions} + +Майнкрафт имеет мощную систему предложений по командам, которая используется много где, например в команде `/give`. Эта система позволяет вам предложение значения к аргументам ваших команд для пользователей, которые они могут выбрать - это отличная возможность сделать вашу команду больше удобнее и эргономичной. + +## Поставщики предложений {#suggestion-providers} + +`SuggestionProvider` - используется для создания списка предложений, который будет отправлен на клиент. Поставщик предложений - это функциональный интерфейс, который использует `CommandContext` и `SuggestionBuilder`, а также возвращает `Suggestions`. `SuggestionProvider` возвращает `CompletableFuture`, потому что предложения могут быть доступны не сразу. + +## Использование поставщиков предложений {#using-suggestion-providers} + +Чтобы использовать поставщика предложений, необходимо вызвать метод `suggests` в конструкторе аргументов. Этот метод берёт `SuggestionProvider` и возвращает модифицированный аргумент конструктора с прикрепленным поставщиком предложений. + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Встроенные поставщики предложений {#built-in-suggestion-providers} + +Несколько встроенных поставщиков предложений которые вы можете использовать: + +| Поставщик предложений | Описание | +| ----------------------------------------- | -------------------------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | Предлагает всех вызываемых сущностей. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | Предлагает все производимые звуки. | +| `LootCommand.SUGGESTION_PROVIDER` | Предлагает все возможные таблицы добычи. | +| `SuggestionProviders.ALL_BIOMES` | Предлагает всевозможные биомы. | + +## Создание собственного поставщика предложений {#creating-a-custom-suggestion-provider} + +Если встроенные провайдеры не удовлетворяют вашим потребностям, вы можете создать свой поставщик предложений. Для этого, вам нужно создать класс который имплементирует интерфейс `SuggestionProvider` и перезаписать метод `getSuggestions`. + +Например, мы сделаем поставщик предложений предлагающий все имена игроков на сервере. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +Для использования этого поставщика предложений, просто передадите его экземпляр в метод `.suggests` в конструктор аргументов. + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Очевидно, что поставщики предложений могут быть более сложными, поскольку они также могут считывать контекст команды, чтобы предоставлять предложения на основе состояния команды, например аргументов, которые уже были предоставлены. + +Это может быть в виде чтения инвентаря игрока и предлагать предметы, или сущностей вокруг игрока. diff --git a/versions/1.21/translated/ru_ru/develop/entities/damage-types.md b/versions/1.21/translated/ru_ru/develop/entities/damage-types.md new file mode 100644 index 000000000..e290f3851 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/entities/damage-types.md @@ -0,0 +1,99 @@ +--- +title: Типы урона +description: Узнайте, как добавлять пользовательские типы урона. +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# Типы урона {#damage-types} + +Типы урона определяют типы повреждений, которые могут получить сущности. Начиная с Minecraft 1.19.4, создание новых типов урона стало управляться данными, то есть они создаются с использованием файлов JSON. + +## Создание типа урона {#creating-a-damage-type} + +Давайте создадим собственный тип повреждений под названием _Tater_. Начнем с создания JSON-файла для вашего индивидуального типа урона. Этот файл +будет +помещён в директорию вашего мода: `data`, в подпапку с названием `damage_type`. + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +Он имеет следующую структуру: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +Этот пользовательский тип урона увеличивает [истощение голодом](https://minecraft.wiki/w/Hunger#Exhaustion_level_increase) на 0,1 каждый раз, когда игрок получает урон, когда урон наносится живым, неигровым источником (например, блоком). Кроме того, количество нанесенного урона будет масштабироваться в зависимости от сложности мира + +::: info + +Все возможные ключи и значения можно найти на [Minecraft Wiki](https://minecraft.wiki/w/Damage_type#JSON_format). + +::: + +### Доступ к типам урона через код {#accessing-damage-types-through-code} + +Когда нам нужно получить доступ к нашему пользовательскому типу урона через код, мы будем использовать его `RegistryKey` для создания экземпляра `DamageSource`. + +`RegistryKey` можно получить следующим образом: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### Использование типов урона {#using-damage-types} + +Чтобы продемонстрировать использование пользовательских типов урона, мы будем использовать пользовательский блок под названием _Tater Block_. Давайте сделаем так, что когда живое существо наступает на _Tater Block_, оно наносит _Tater_ урон. + +Вы можете переопределить `onSteppedOn`, чтобы нанести этот урон. + +Начнем с создания `DamageSource` нашего пользовательского типа урона. + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Затем мы вызываем `entity.damage()` с нашим `DamageSource` и суммой. + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Полная реализация блока: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +Теперь, когда живое существо наступит на наш блок, оно получит 5 единиц урона (2,5 сердца) с использованием нашего типа урона. + +### Пользовательское сообщение о смерти {#custom-death-message} + +Вы можете определить сообщение о смерти для типа урона в формате `death.attack.` в файле `en_us.json`. + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +После смерти от нашего типа урона вы увидите следующее сообщение о смерти: + +![Effect in player inventory](/assets/develop/tater-damage-death.png) + +### Теги типа урона {#damage-type-tags} + +Некоторые типы урона могут обходить броню, обходить эффекты сущности и т.д. Теги используются для управления этими свойствами +типов урона. + +Существующие теги типов урона можно найти в `data/minecraft/tags/damage_type`. + +::: info + +Полный список тегов типов урона см. на [Minecraft Wiki](https://minecraft.wiki/w/Tag#Damage_types). + +::: + +Давайте добавим наш тип урона Tater к тегу типа урона `bypasses_armor`. + +Чтобы добавить наш тип урона к одному из этих тегов, мы создаем JSON-файл в пространстве имен `minecraft`. + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +Со следующим содержанием: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +Убедитесь, что ваш тег не заменяет существующий тег, установив ключ `replace` в значение `false`. diff --git a/versions/1.21/translated/ru_ru/develop/entities/effects.md b/versions/1.21/translated/ru_ru/develop/entities/effects.md new file mode 100644 index 000000000..a2b31b048 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/entities/effects.md @@ -0,0 +1,65 @@ +--- +title: Эффекты состояния +description: Узнайте, как создавать свои собственные эффекты состояния. +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil +authors-nogithub: + - siglong + - tao0lu +--- + +# Эффекты состояния {#status-effects} + +Эффекты состояния, также известные как просто эффекты, представляют собой состояние, которое может воздействовать на сущность. Они могут сказываться положительно, отрицательно или нейтрально на сущности. В обычном случае в игре эти эффекты применяются несколькими способами, такими как поедание еды, распитие зелий и так далее. + +Можно использовать команду `/effect` для применения эффектов к сущности. + +## Свои эффекты состояния {#custom-status-effects} + +В этом руководстве мы добавим новый эффект под названием _Tater_, который даёт игроку одно очко опыта каждый игровой такт. + +### Расширение `StatusEffect` {#extend-statuseffect} + +Давайте создадим класс нашего эффекта, который будет наследовать основной класс всех эффектов — `StatusEffect`. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### Регистрация своего эффекта {#registering-your-custom-effect} + +Схожим с регистрацией блоков и предметов образом, мы используем `Registry.register`, чтобы зарегистрировать наш эффект в реестре `STATUS_EFFECT`. Это можно сделать в нашем инициализаторе. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### Текстура + +Иконка эффекта состояния представляет собой PNG-файл размером 18×18 пикселей. Поместите свою иконку в папку: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + +Пример текстуры + +### Переводы {#translations} + +Как и с любыми другими переводами, вы можете добавить запись формата `"effect..": "Значение"` в языковой файл. + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### Тестирование + +Используйте команду `/effect give @p fabric-docs-reference:tater`, чтобы дать игроку наш эффект Tater. +Используйте команду `/effect clear @p fabric-docs-reference:tater`, чтобы удалить эффект. + +:::info +::: info +Чтобы узнать, как создать зелье, накладывающее этот эффект, ознакомьтесь с руководством по [зельям](../items/potions). +::: diff --git a/versions/1.21/translated/ru_ru/develop/events.md b/versions/1.21/translated/ru_ru/develop/events.md new file mode 100644 index 000000000..940325047 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/events.md @@ -0,0 +1,122 @@ +--- +title: События +description: Руководство по использование событий предоставляемых Fabric API. +authors: + - dicedpixels + - mkpoli + - daomephsta + - solidblock + - draylar + - jamieswhiteshirt + - PhoenixVX + - Juuxel + - YanisBft + - liach + - natanfudge +authors-nogithub: + - stormyfabric +--- + +# События {#events} + +Fabric API предоставляет систему, которая позволяет модам реагировать на действия или явления, так же известные как _события_, происходящие в игре. + +События — это хуки, которые удовлетворяют общим сценариям использования и/или обеспечивают улучшенную совместимость и производительность между модами, которые подключаются к одним и тем же областям кода. Использование событий часто заменяет использование mixins. + +API Fabric предоставляет события для важных областей кодовой базы Minecraft, в которых могут быть заинтересованы многие разработчики модов. + +События представлены экземплярами `net.fabricmc.fabric.api.event.Event`, которые хранят и вызывают _обртный вызов (callback)_. Часто для обратного вызова существует один экземпляр события, который хранится в статическом поле `EVENT` интерфейса обратного вызова, но существуют и другие шаблоны. Например, `ClientTickEvents` группирует несколько связанных событий вместе. + +## Обратные вызовы {#callbacks} + +Обратный вызов — это фрагмент кода, который передается в качестве аргумента событию. Когда игра инициирует событие, переданный фрагмент кода будет выполнен. + +### Интерфейсы обратных вызовов {#callback-interfaces} + +Каждое событие имеет соответствующий интерфейс обратного вызова, условно называемый `Callback`. Обратные вызовы регистрируются путем вызова метода `register()` для экземпляра события с экземпляром интерфейса обратного вызова в качестве аргумента. + +Все интерфейсы обратного вызова событий, предоставляемые Fabric API, можно найти в пакете `net.fabricmc.fabric.api.event`. + +## Прослушивание событий {#listening-to-events} + +В этом примере регистрируется `AttackBlockCallback` для нанесения урона игроку при столкновении с блоками, из которых не выпадает предмет при ручной добыче. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +### Добавление предмета к существующим таблицам лута {#adding-items-to-existing-loot-tables} + +Иногда вам может понадобиться добавить предметы в таблицы добычи. Например, добавляя свои капли в ванильный блок или сущность. + +Самое простое решение — замена файла таблицы добычи — это может сломать другие моды. А что, если они захотят изменить и их? Мы рассмотрим, как можно добавлять предметы в таблицы добычи, не переопределяя таблицу. + +Мы добавим особый элемент в таблицу лута угольной руды. + +#### Прослушивание загрузки таблицы добычи {#listening-to-loot-table-loading} + +В API Fabric есть событие, которое запускается при загрузке таблиц добычи, `LootTableEvents.MODIFY`. Вы можете зарегистрировать обратный вызов для него в инициализаторе мода. Давайте также проверим, что текущая таблица добычи — это таблица добычи угольной руды. + +@[code lang=java transclude={38-40}](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +#### Добавление предметов в таблицу добычи {#adding-items-to-the-loot-table} + +В таблицах лута предметы хранятся в _элементах лут пулов, а элементы хранятся в _лут пулах_. Чтобы добавить предмет, нам нужно добавить пул с записью предмета в таблицу добычи. + +Мы можем создать пул с помощью `LootPool#builder` и добавить его в таблицу добычи. + +В нашем пуле также нет элементов, поэтому мы создадим запись элемента с помощью `ItemEntry#builder` и добавим ее в пул. + +@[code highlight={6-7} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +## Собственные события {#custom-events} + +В некоторых областях игры отсутствуют хуки, предоставляемые API Fabric, поэтому вы можете либо использовать mixin, либо создать собственное событие. + +Мы рассмотрим создание события, которое запускается при стрижке овец. Процесс создания события: + +- Создание интерфейса обратного вызова события +- Запуск события из mixin +- Создание тестовой реализации + +### Создание интерфейса обратного вызова {#creating-the-event-callback-interface} + +Интерфейс обратного вызова описывает, что должно быть реализовано слушателем событий, которые будут прослушивать ваше событие. Интерфейс обратного вызова также описывает, как событие будет вызываться из нашего mixin. Традиционно, объект `Event` помещают в качестве поля в интерфейс обратного вызова, который будет идентифицировать наше фактическое событие. + +Для нашей реализации `Event` мы выберем использование события на основе массива. Массив будет содержать все слушатели событий, которые прослушивают событие. + +Наша реализация будет вызывать слушатели событий по порядку до тех пор, пока один из них не вернет `ActionResult.PASS`. Это означает, что слушатель может сказать «_отменить это_», «_одобрить это_» или «_неважно, оставьте это следующему слушателю событий_», используя возвращаемое значение. + +Использование `ActionResult` в качестве возвращаемого значения — это общепринятый способ заставить обработчики событий взаимодействовать таким образом. + +Вам необходимо создать интерфейс, имеющий экземпляр «События» и метод для реализации ответа. Базовая настройка обратного вызова для стрижки овец выглядит следующим образом: + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Давайте рассмотрим это более подробно. При вызове мы перебираем всех слушателей: + +@[code lang=java transclude={21-22}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Затем мы вызываем наш метод (в данном случае `interact`) для слушателя, чтобы получить его ответ: + +@[code lang=java transclude={33-33}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Если слушатель сообщает, что нам необходимо отменить (`ActionResult.FAIL`) или завершить (`ActionResult.SUCCESS`), обратный вызов возвращает результат и завершает цикл. `ActionResult.PASS` переходит к следующему слушателю и в большинстве случаев должен завершиться успешно, если больше нет зарегистрированных слушателей: + +@[code lang=java transclude={25-30}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +Мы можем добавить комментарии Javadoc в начало классов обратного вызова, чтобы документировать, что делает каждый `ActionResult`. В нашем случае это может быть: + +@[code lang=java transclude={9-16}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +### Запуск события из Mixin'а {#triggering-the-event-from-a-mixin} + +Теперь у нас есть базовый скелет события, но нам нужно его запустить. Поскольку мы хотим, чтобы событие вызывалось, когда игрок пытается постричь овцу, мы вызываем событие `invoker` в `SheepEntity#interactMob`, когда вызывается `sheared()` (т. е. овцу можно стричь, а игрок держит ножницы): + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java) + +### Создание тестовой имплементации {#creating-a-test-implementation} + +Теперь нам нужно протестировать наше событие. Вы можете зарегистрировать слушатель в своем методе инициализации (или в другой области, если вам так удобнее) и добавить туда пользовательскую логику. Вот пример, в котором вместо шерсти к ногам овцы падает алмаз: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +Если вы зайдете в игру и пострижете овцу, вместо шерсти должен выпасть алмаз. diff --git a/versions/1.21/translated/ru_ru/develop/getting-started/creating-a-project.md b/versions/1.21/translated/ru_ru/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..687debdb7 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/getting-started/creating-a-project.md @@ -0,0 +1,71 @@ +--- +title: Создание проекта +description: Пошаговое руководство по созданию нового проекта мода с использованием генератора шаблонов Fabric. +authors: + - IMB11 + - Cactooz +--- + +# Создание проекта {#creating-a-project} + +Fabric предоставляет лёгкий путь создания новых проектов мода используя генератор шаблонов модов Fabric, если вы хотите, вы можете создать новый проект используя репозиторий примерного мода, вам следует перейти на [Создание проекта вручную](#manual-project-creation). + +## Генерирование проекта {#generating-a-project} + +Вы можете использовать [Генератор модов Fabric Template](https://fabricmc.net/develop/template/) для создания нового проекта для вашего мода. Вам следует заполнить обязательные поля, такие как имя мода, имя пакета и версию Minecraft, для которой вы хотите разрабатывать. + +Имя пакета должно быть написано строчными буквами, разделено точками и быть уникальным, чтобы избежать конфликтов с пакетами других программистов. Обычно он форматируется как обратный интернет домен, например `com.example.modid`. + +![Предварительный просмотр генератора](/assets/develop/getting-started/template-generator.png) + +Если вы хотите использовать Kotlin, использовать официальные сопоставления Mojang вместо сопоставлений Yarn или хотите добавить генераторы данных, вы можете выбрать соответствующие параметры в разделе «Дополнительные параметры». + +![Секция расширенных настроек](/assets/develop/getting-started/template-generator-advanced.png) + +После того как вы заполнили обязательные поля, нажмите на кнопку `Generate`, и генератор для вас создадит новый проект в форме zip-файла. + +Вам следует извлечь этот zip-файл в выбранное вами место, а затем открыть извлечённую папку в IntelliJ IDEA: + +![Открытый интерпретатор проекта](/assets/develop/getting-started/open-project.png) + +## Импортирование проекта {#importing-the-project} + +После того как вы открыли проект в IntelliJ IDEA, IDE должен автоматически загрузить конфигурацию Gradle проекта и выполнит необходимые задачи по настройке. + +Если вы получите уведомление, говорящее о скрипте сборки Gradle, вам следует нажать кнопку `Import Gradle Project`: + +![Интерпретатор Gradle](/assets/develop/getting-started/gradle-prompt.png) + +После того как ваш проект был импортирован, вы должны увидеть файлы проекта в проводнике проекта, и сможете начать разработку вашего мода. + +## Создание проекта вручную {#manual-project-creation} + +:::warning +Для клонирования репозитория примера мода вам потребуется установленный [Git](https://git-scm.com/). +::: + +Если вы не можете использовать Fabric Template Mod Generator, вы можете создать новый проект вручную, следуя этим шагам. + +Первое, клонируйте репозиторий примера мода используя Git: + +```sh +клон git https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +Это клонирует репозиторий в новую папку под названием `my-mod-project`. + +Затем, вы должны удалить папку `.git` из клонированного репозитория, и затем открыть проект в IntelliJ IDEA. Если папка `.git` не отображается, вам следует включить отображение скрытых элементов в вашем файловом менеджере. + +После того как вы открыли проект в IntelliJ IDEA, оно должно автоматически загрузить конфигурацию Gradle проекта и должно выполнить необходимые задачи по настройке. + +Опять же, как описывалось выше, если вы получите уведомление, говорящее о скрипте сборки Gradle, вам следует нажать кнопку `Import Gradle Project`. + +### Изменение Шаблона {#modifying-the-template} + +После импорта проекта вам следует изменить детали проекта, чтобы они соответствовали деталям вашего мода: + +- Измените файл `gradle.properties` в вашем проекте, чтобы изменить свойства `maven_group` и `archive_base_name` чтобы соответствовать деталям вашего мода. +- Измените файл `fabric.mod.json`, чтобы изменить свойства `id`, `name`, и `description`, чтобы соответствовать деталям вашего мода. +- Убедитесь, что вы обновили версии Minecraft, маппингов, Loader и Loom — все из которых можно запросить через — чтобы они соответствовали версиям, которые вы хотите поддерживать. + +Вы конечно же можете изменить имя пакета и основной класс мода, чтобы соответствовать деталям вашего мода. diff --git a/versions/1.21/translated/ru_ru/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/ru_ru/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..cf4cdc617 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Введение в Fabric и создание модов +description: "Краткое знакомство с Fabric и созданием модов для Minecraft: Java Edition." +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Введение в Fabric и создание модов {#introduction-to-fabric-and-modding} + +## Предварительные условия {#prerequisites} + +Перед тем как начать, вам следует иметь базовые знания разработки на Java и понимание концепций объектно-ориентированного программирования (ООП). + +Если эти концепции вам не знакомы, рекомендуем сначала изучить несколько учебных материалов по Java и ООП. Эти ресурсы могут помочь: + +- [W3: уроки по Java](https://www.w3schools.com/java/); +- [Codecademy: выучите Java](https://www.codecademy.com/learn/learn-java); +- [W3: Java в ООП](https://www.w3schools.com/java/java_oop.asp); +- [Medium: введение в ООП](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd). + +### Терминология {#terminology} + +Прежде чем начнём, давайте рассмотрим некоторые термины, с которыми вы столкнётесь при создании мода на Fabric: + +- **Мод**: изменение игры, добавляющее новые функции или изменяющее существующие; +- **Загрузчик модов**: инструмент для загрузки модов в игру, такой как Fabric Loader; +- **Миксин**: инструмент для модификации кода игры во время её выполнения — подробнее в [знакомстве с миксинами](https://fabricmc.net/wiki/tutorial:mixin_introduction); +- **Gradle**: инструмент автоматизации сборки, применяемый для создания и компиляции модов. Fabric использует его для сборки своих модов; +- **Маппинги**: набор маппингов, преобразующих обфусцированный код в тот, который может прочесть человек; +- **Обфускация**: процесс усложнения кода для его затруднённого понимания, используемый Mojang для защиты кода Minecraft; +- **Ремаппинг**: процесс преобразования обфусцированного кода в тот, который будет читаем для людей. + +## Что такое Fabric? {#what-is-fabric} + +Fabric — лёгкий инструмент для создания модов для Minecraft: Java Edition. + +Он разработан как простая и удобная платформа для разработки модов. Fabric — это проект, который ведёт сообщество, и у него открытый исходный код, что означает, что любой может внести в него свой вклад. + +Вам следует знать о четырёх основных компонентах Fabric: + +- **Fabric Loader**: гибкий загрузчик модов, не зависящий от платформы, предназначенный для Minecraft и других игр и приложений; +- **Fabric Loom**: плагин для Gradle, позволяющий разработчикам легко разрабатывать и отлаживать моды; +- **Fabric API**: набор API и инструментов для разработчиков модов, которые можно использовать при создании модов; +- **Yarn**: набор открытых маппингов Minecraft, свободных для использования под лицензией Creative Commons Zero. + +## Почему Fabric необходим для модификации Minecraft? {#why-is-fabric-necessary-to-mod-minecraft} + +> Модификация игры — это процесс изменения игры с целью изменения её поведения или добавления новых возможностей. В случае Minecraft это может включать в себя всё, от добавления новых предметов, блоков или существ до изменения механик игры или добавления новых режимов игры. + +Minecraft: Java Edition обфусцирован компанией Mojang, что делает самостоятельное модифицирование сложным. Однако с помощью инструментов для модификации, таких как Fabric, процесс становится намного проще. Существуют различные системы маппинга, которые могут помочь в этом процессе. + +Loom преобразует обфусцированный код в читаемый формат с помощью этих маппингов, что облегчает мододелам понимание и изменение кода игры. Yarn является популярным и отличным выбором для маппинга, но также существуют и другие варианты. Каждый проект маппинга может иметь свои собственные достоинства и фокусироваться на различных аспектах. + +Loom позволяет с лёгкостью разрабатывать и компилировать моды на основе кода, над которым провели ремаппинг, а Fabric Loader позволяет загружать эти моды в игру. + +## Что даёт Fabric API и зачем это нужно? {#what-does-fabric-api-provide-and-why-is-it-needed} + +> Fabric API — это набор API и инструментов для разработчиков модов, которые можно использовать при создании модов. + +Fabric API предоставляет широкий набор API, которые расширяют существующие функциональные возможности Minecraft. Например, он предлагает новые хуки и события, которые могут использоваться мододелами, или новые утилиты и инструменты, упрощающие процесс модификации игры, такие как транзитивные расширители доступа и возможность доступа к внутренним реестрам, таким как реестр предметов, которые можно использовать в компостнице. + +Хотя Fabric API предлагает довольно мощные функции, некоторые задачи, такие как базовая регистрация блоков, можно выполнять и без него, используя стандартные API Minecraft. diff --git a/versions/1.21/translated/ru_ru/develop/getting-started/launching-the-game.md b/versions/1.21/translated/ru_ru/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..d066fc8b1 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/getting-started/launching-the-game.md @@ -0,0 +1,72 @@ +--- +title: Запуск игры +description: Узнайте, как использовать различные профили запуска для запуска и отладки ваших модов в реальной игровой среде. +authors: + - IMB11 + - Tenneb22 +--- + +# Запуск игры {#launching-the-game} + +Fabric Loom предоставляет различные профили запуска, которые помогут вам запускать и отлаживать моды в живой игровой среде. В данном руководстве мы рассмотрим различные профили запуска и то, как использовать их для отладки и тестирования ваших модов. + +## Профили запуска {#launch-profiles} + +Если вы используете IntelliJ IDEA, вы можете найти профили запуска в правом верхнем углу окна. Нажмите на выпадающее меню, чтобы увидеть доступные профили запуска. + +Должны быть доступны клиентский и серверный профили с возможностью запустить их в обычном или режиме отладки: + +![Запуск профилей](/assets/develop/getting-started/launch-profiles.png) + +## Задачи Gradle {#gradle-tasks} + +Если вы используете командную строку, вы можете использовать следующие команды Gradle для запуска игры: + +- `./gradlew runClient` — запускает игру в клиентском режиме. +- `./gradlew runServer` — запускает игру в серверном режиме. + +Единственная проблема с этим подходом заключается в том, что вы не можете легко отлаживать свой код. Если вы хотите отлаживать код, вам нужно использовать профили запуска в IntelliJ IDEA или через интеграцию Gradle в вашей ИСР (IDE). + +## Горячая замена классов {#hotswapping-classes} + +Когда вы запускаете игру в режиме отладки, вы можете делать горячую замену (hotswap) своих классов без перезапуска игры. Это полезно для быстрого тестирования изменений в коде. + +Однако у этого есть ограничения: + +- вы не можете добавлять или удалять методы, +- вы не можете изменять параметры методов, +- вы не можете добавлять или удалять поля. + +Однако, используя [Runtime от JetBrains](https://github.com/JetBrains/JetBrainsRuntime), вы можете обойти большинство ограничений и даже добавлять или удалять классы и методы. Это позволит большинству изменений вступать в силу без перезапуска игры. + +Не забудьте добавить следующее в опции VM Arguments в конфигурации запуска Minecraft: + +```:no-line-numbers +-XX:+AllowEnhancedClassRedefinition +``` + +## Горячая замена миксинов {#hotswapping-mixins} + +Если вы используете миксины, вы можете делать горячую замену классов миксинов без перезапуска игры. Это полезно для быстрого тестирования изменений в миксинах. + +Однако для этого вам нужно установить Java-агент для миксинов. + +### 1. Найдите JAR-файл библиотеки Mixin {#1-locate-the-mixin-library-jar} + +В IntelliJ IDEA вы можете найти JAR-файл библиотеки Mixin в разделе External Libraries в разделе Project: + +![Библиотека Mixin](/assets/develop/getting-started/mixin-library.png) + +Вам нужно скопировать «абсолютный путь» (Absolute Path) этого JAR-файла для следующего шага. + +### 2. Добавьте аргумент `-javaagent` в VM Arguments {#2-add-the--javaagent-vm-argument} + +В конфигурации запуска Minecraft Client и/или Minecraft Server добавьте следующее в опции VM Arguments: + +```:no-line-numbers +-javaagent:"путь к JAR-файлу библиотеки Mixin" +``` + +![Скриншот VM Arguments](/assets/develop/getting-started/vm-arguments.png) + +Теперь вы сможете изменять содержимое ваших Mixin-методов во время отладки, и изменения вступят в силу без перезапуска игры. diff --git a/versions/1.21/translated/ru_ru/develop/getting-started/project-structure.md b/versions/1.21/translated/ru_ru/develop/getting-started/project-structure.md new file mode 100644 index 000000000..d24f0b573 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/getting-started/project-structure.md @@ -0,0 +1,59 @@ +--- +title: Структура проекта +description: Обзор структуры проекта Fabric мода. +authors: + - IMB11 +--- + +# Структура проекта {#project-structure} + +На этой странице будет рассмотрена структура проекта Fabric мода, и назначение каждого файла и папки в проекте. + +## `fabric.mod.json` {#fabric-mod-json} + +Файл `fabric.mod.json` - это главный файл который описывает ваш мод загрузчику Fabric. Он содержит такую информацию как идентификатор мода, версию и зависимости. + +Важнейшие поля в файле `fabric.mod.json`: + +- `id`: Идентификатор мода (должен быть уникальным). +- `name`: Название мода. +- `environment`: Среда выполнения которую запускает ваш мод, например `client`, `server`, или `*` для обоих. +- `entrypoints`: Точки входа вашего мода, например `main` или `client`. +- `depends`: Зависимости вашего мода. +- `mixins`: Миксины, которые предоставляет ваш мод. + +Ниже вы можете увидеть пример файла `fabric.mod.json`, этот файл `fabric.mod.json` для примерного проекта, лежащего в основе этого сайта документации. + +:::details Примерный проект `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## Точки входа {#entrypoints} + +Как упоминалось ранее, файл `fabric.mod.json` имеет внутри поле `entrypoint`, это поле используется для указания точек входа, которые предоставляет ваш мод. + +Создатель шаблонов создает обе точки входа `main` и `client` по умолчанию, точка входа `main` используется для общего кода, а точка входа `client` используется для клиентоориентированного кода. Эти точки входа вызывается, когда игра запускается. + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +Выше приведён пример простой точки входа `main`, который записывает сообщение в консоль, когда игра запускается. + +## `src/main/resources` {#src-main-resources} + +Папка `src/main/resources` используется для хранения ресурсов которые использует ваш мод, например текстуры, модели, и звуки. + +Это так же папка хранения `fabric.mod.json` и все файлы конфигурации, которые использует ваш мод. + +Ресурсы хранятся в структуре, которые отражают структуру пакетов ресурсов, например, текстуре блока будет храниться в `assets/modid/textures/block/block.png`. + +## `src/client/resources` {#src-client-resources} + +Папка `src/client/resources` используется для хранения клиентоориентированных ресурсов. + +## `src/main/java` {#src-main-java} + +Папка `src/main/java` используется для хранения исходного кода вашего мода, она существует на клиентской так и на серверной среде. + +## `src/client/java` {#src-client-java} + +Папка `src/client/java` используется для хранения клиентоориентированного исходного кода, например код рендеринга или логика на стороне клиента - например предоставляемый цвет блока. diff --git a/versions/1.21/translated/ru_ru/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/ru_ru/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..21864e41b --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: Настройка среды разработки +description: Пошаговое руководство по настройке среды разработки для создания модов с помощью Fabric. +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# Настройка среды разработки {#setting-up-a-development-environment} + +Для начала разработки модов с использованием Fabric вам нужно настроить среду разработки в IntelliJ IDEA. + +## Установка JDK 21 {#installing-jdk-21} + +Для разработки модов для Minecraft 1.21 вам потребуется JDK 21. + +Если вам нужна помощь в установке Java, вы можете обратиться к различным руководствам по установке Java в [разделе руководств для игроков](../../players/index). + +## Установка IntelliJ IDEA {#installing-intellij-idea} + +:::info +Вы также можете использовать и другие IDE, например Eclipse или Visual Studio Code, но большинство страниц в этой документации предполагают что вы используете IntelliJ IDEA, если вы используете другую IDE, обратитесь к документации по ней. +::: + +Если у вас не установлена IntelliJ IDEA, вы можете её установить на [официальном сайте](https://www.jetbrains.com/idea/download/) - следуйте шагам установки для вашей операционной системы. + +Community edition IntelliJ IDEA бесплатна и имеет открытый исходный код, и также она рекомендуемая версия для модинга с Fabric. + +Возможно, вам придется прокрутить страницу вниз, чтобы найти ссылку на загрузку Community edition, она выглядит следующим образом: + +![Подсказка для загрузки Community Edition](/assets/develop/getting-started/idea-community.png) + +## Установка плагинов IDEA {#installing-idea-plugins} + +Хотя эти плагины не являются необходимыми, они могут сделать ваш процесс моддинга с Fabric более лёгким, вам следует подумать об их установкой. + +### Minecraft Development {#minecraft-development} + +Плагин Minecraft Development предоставляет поддержку моддинга с Fabric, и это самый важный плагин для установки. + +Вы можете установить его открытием IntelliJ IDEA, а затем перейти по адресу `File > Settings > Plugins > Marketplace Tab` и найти `Minecraft Development` в поисковой строке, и затем нажать кнопку `Install`. + +Альтернативный вариант: вы можете установить его на [странице плагина](https://plugins.jetbrains.com/plugin/8327-minecraft-development) и затем установите его по адресу `File > Settings > Plugins > Install Plugin From Disk`. diff --git a/versions/1.21/translated/ru_ru/develop/ide-tips-and-tricks.md b/versions/1.21/translated/ru_ru/develop/ide-tips-and-tricks.md new file mode 100644 index 000000000..2f3421838 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/ide-tips-and-tricks.md @@ -0,0 +1,245 @@ +--- +title: Советы и рекомендации по IDE +description: Полезная информация для эффективной обработки и перемещения по вашему проекту с использованием IDE. +authors: + - JR1811 +--- + +# Советы и рекомендации по IDE{#ide-tips-and-tricks} + +На этой странице представлена ​​полезная информация, которая поможет ускорить и облегчить работу разработчиков. Включите их в свой дизайн по своему вкусу. +Может потребоваться некоторое время, чтобы освоить и привыкнуть к сочетаниям клавиш и другим опциям. Вы можете использовать эту страницу в качестве справочного материала. + +:::warning +Сочетания клавиш в тексте указаны как сочетания клавиш Windows и соответствуют раскладке клавиш IntelliJ IDEA по умолчанию, если не указано иное. +Если вы используете другую раскладку клавиатуры, перейдите в раздел «Файл» > «Настройки» > «Раскладка клавиатуры» или поищите соответствующую функцию в другом месте. +::: + +## Проекты Traversing{#traversing-projects} + +### Вручную {#manually} + +IntelliJ имеет множество различных способов перемещения по проектам. Если вы сгенерировали исходники с помощью команд `./gradlew genSources` в терминале или использовали задачи Gradle `Tasks > fabric > genSources` в окне Gradle, вы можете вручную просмотреть исходные файлы Minecraft во внешних библиотеках окна проекта. + +![Задача Gradle](/assets/develop/misc/using-the-ide/traversing_01.png) + +Исходный код Minecraft можно найти, если поискать `net.minecraft` в разделе «Внешние библиотеки» окна проекта. Если ваш проект использует разделенные исходные коды из онлайн [шаблонов модов](https://fabricmc.net/develop/template/) —то будет два источника, как указано в названии (client/common). Кроме того, также будут доступны другие источники проектов, библиотек и зависимостей, которые импортируются через файл `build.gradle`. Этот метод часто используется при просмотре ресурсов, тегов и других файлов. + +![Внешняя библиотека](/assets/develop/misc/using-the-ide/traversing_02_1.png) + +![Разделить исходники](/assets/develop/misc/using-the-ide/traversing_02_2.png) + +### Поиск{#search} + +Двойное нажатие клавиши Shift открывает окно поиска. Там вы можете искать файлы и классы вашего проекта. При активации флажка «включить элементы, не входящие в проект» +или повторном нажатии клавиши Shift два раза поиск будет осуществляться не только в вашем проекте, но и в других, например, во внешних библиотеках. + +![Окно поиска](/assets/develop/misc/using-the-ide/traversing_03.png) + +### Недавнее окно{#recent-window} + +Еще один полезный инструмент IntelliJ — окно «Недавние». Вы можете открыть его с помощью сочетания клавиш CTRL + E. Там вы можете перейти к файлам, которые вы уже посещали, и открыть окна инструментов, такие как окно [Структура](#structure-of-a-class) или [Закладки](#bookmarks). + +![Недавнее окно](/assets/develop/misc/using-the-ide/traversing_04.png) + +## Код Traversing {#traversing-code} + +### Перейти к определению/использованию{#jump-to-definition-usage} + +Если вам нужно проверить определение или использование переменных, методов, классов и других вещей, вы можете нажать CTRL + левую кнопку мыши +или использовать среднюю кнопку мыши (нажатие колесика мыши) на их имени. Таким образом, вы сможете избежать длительных сеансов прокрутки или ручного поиска определения, которое находится в другом файле. + +### Закладки{#bookmarks} + +Вы можете добавлять в закладки строки кода, файлы или даже открытые вкладки редактора. +Особенно при исследовании исходных кодов это может помочь отметить места, которые вы захотите быстро найти в будущем. + +Щелкните правой кнопкой мыши файл в окне «Проект», на вкладке редактора или на номере строки в файле. +Создание «Мнемонических закладок» позволяет вам быстро переключаться обратно на эти закладки, используя их горячие клавиши, CTRL и цифру, которую вы для этого выбрали. + +![Установить закладку](/assets/develop/misc/using-the-ide/traversing_05.png) + +Если вам необходимо разделить или упорядочить их, можно создать несколько списков закладок одновременно в окне «Закладки». +Там же будут отображаться [Точки останова](./basic-problem-solving#breakpoint). + +![Окно закладки](/assets/develop/misc/using-the-ide/traversing_06.png) + +## Анализ классов{#analyzing-classes} + +### Структура класса{#structure-of-a-class} + +Открыв окно «Структура» (Alt + 7), вы получите обзор вашего текущего активного класса. Вы можете увидеть, какие классы и перечисления находятся в этом файле, какие методы реализованы и какие поля и переменные объявлены. + +Иногда может быть полезно активировать опцию «Наследуется» вверху в параметрах просмотра, когда ищешь потенциальные методы для переопределения. + +![Окно структуры](/assets/develop/misc/using-the-ide/analyzing_01.png) + +### Иерархия типов класса{#type-hierarchy-of-a-class} + +Поместив курсор на имя класса и нажав CTRL + H, вы можете открыть новое окно иерархии типов, в котором отображаются все родительские и дочерние классы. + +![Окно иерархии типов](/assets/develop/misc/using-the-ide/analyzing_02.png) + +## Утилита кода{#code-utility} + +### Автодополнение кода{#code-completion} + +Автодополнение кода должно быть активировано по умолчанию. Вы автоматически получите рекомендации по мере написания кода. Если вы закрыли его случайно или просто переместили курсор в новое место, вы можете использовать CTRL + Пробел, чтобы открыть его снова. + +Например, при использовании Lambda, вы можете быстро их написать, используя этот метод. + +![Лямбда со многими параметрами](/assets/develop/misc/using-the-ide/util_01.png) + +### Генерация кода {#code-generation} + +К меню «Создать» можно быстро получить доступ с помощью ⌘/CTRLN. +В файле Java вы сможете генерировать конструкторы, геттеры, сеттеры, переопределять или реализовывать методы и многое другое. +Вы также можете генерировать аксессоры и инвокеры, если у вас установлен [плагин Minecraft Development](./getting-started/setting-up-a-development-environment#minecraft-development). + +Кроме того, вы можете быстро переопределять методы с помощью ⌘/CTRLO и реализовывать методы с помощью ⌘/CTRLI. + +![Меню генерации кода в файле Java](/assets/develop/misc/using-the-ide/generate_01.png) + +В тестовом файле Java вам будут предоставлены возможности для генерации связанных методов тестирования, как указано ниже: + +![Меню генерации кода в тестовом файле Java](/assets/develop/misc/using-the-ide/generate_02.png) + +### Отображение параметров{#displaying-parameters} + +Отображение параметров должно быть активировано по умолчанию. Типы и имена параметров вы получите автоматически при написании кода. +Если вы случайно закрыли их или просто переместили курсор в новое место, вы можете использовать CTRL + P, чтобы снова открыть их. + +Методы и классы могут иметь несколько реализаций с разными параметрами, что также известно как перегрузка. Таким образом, вы можете решить, какую реализацию вы хотите использовать, при написании вызова метода. + +![Отображение параметров метода](/assets/develop/misc/using-the-ide/util_02.png) + +### Рефакторинг {#refactoring} + +Рефакторинг — это процесс реструктуризации кода без изменения его функциональности во время выполнения. Безопасное переименование и удаление частей кода является частью этого, но такие вещи, как извлечение частей кода в отдельные методы и введение новых переменных для повторяющихся операторов кода, также называются «рефакторингом». + +Многие IDE имеют обширный набор инструментов, помогающих в этом процессе. В IntelliJ просто щелкните правой кнопкой мыши по файлам или частям кода, чтобы получить доступ к доступным инструментам рефакторинга. + +![Рефакторинг](/assets/develop/misc/using-the-ide/refactoring_01.png) + +Особенно полезно привыкнуть к сочетанию клавиш инструмента рефакторинга `Rename`, Shift + F6, поскольку в будущем вам придется переименовывать множество вещей. Используя эту функцию, +каждое вхождение переименованного кода будет переименовано и останется функционально прежним. + +### Поиск и замена содержимого файла{#search-and-replace-file-content} + +Иногда для редактирования фрагментов кода требуются более простые инструменты. + +| Привязка клавиш | Функция | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| CTRL + F | Найти в текущем файле | +| CTRL + R | Заменить в текущем файле | +| CTRL + Shift + F | Найти в более широком диапазоне (можно задать маску определенного типа файла) | +| CTRL + Shift + R | Заменить в большей области (можно задать маску определенного типа файла) | + +Если эти инструменты включены, они позволяют выполнять более конкретное сопоставление с шаблоном с использованием «[Regex](https://en.wikipedia.org/wiki/Regular_expression)». + +![Замена регулярного выражения](/assets/develop/misc/using-the-ide/search_and_replace_01.png) + +## Комментарии {#comments} + +Хороший код должен быть легко читаемым и [самодокументирующимся](https://bytedev.medium.com/code-comment-anti-patterns-and-why-the-comment-you-just-wrote-is-probably-not-needed-919a92cf6758). Выбор выразительных имен для переменных, классов и методов может оказать большую помощь, но иногда комментарии необходимы, чтобы оставлять заметки или **временно** отключать код для тестирования. + +### Подготовить ярлыки{#prepare-shortcuts} + +Чтобы быстрее комментировать код, откройте настройки IntelliJ, найдите записи «Комментарий с помощью строчного комментария» и «Комментарий с помощью блочного комментария» и установите для них сочетания клавиш в соответствии с вашими предпочтениями. + +![Настройки раскладки клавиатуры](/assets/develop/misc/using-the-ide/comments_01.png) + +Теперь вы можете выделить нужный код и, используя сочетания клавиш, закомментировать раздел. + +```java +// private static final int PROTECTION_BOOTS = 2; +private static final int PROTECTION_LEGGINGS = 5; +// private static final int PROTECTION_CHESTPLATE = 6; +private static final int PROTECTION_HELMET = 1; +``` + +```java +/* +ModItems.initialize(); +ModSounds.initializeSounds(); +ModParticles.initialize(); +*/ + +private static int secondsToTicks(float seconds) { + return (int) (seconds * 20 /*+ 69*/); +} +``` + +### Комментарии региона{#region-comments} + +В IntelliJ рядом с номерами строк можно разместить небольшие значки [+] и [-]. Их можно использовать для временного сворачивания методов, операторов if, классов и многих других вещей, если вы не работаете над ними активно. Чтобы создать пользовательский блок, который можно свернуть, используйте комментарии `region` и `endregion`. + +```java +// region collapse block name + ModBlocks.initialize(); + ModBlockEntities.registerBlockEntityTypes(); + ModItems.initialize(); + ModSounds.initializeSounds(); + ModParticles.initialize(); +// endregion +``` + +![Свернуть регион](/assets/develop/misc/using-the-ide/comments_02.png) + +:::warning +Если вы заметили, что используете их слишком много, рассмотрите возможность рефакторинга кода, чтобы сделать его более читабельным! +::: + +### Примечания TODO и FIXME{#todo-and-fixme-notes} + +При работе с кодом может оказаться полезным оставлять заметки о том, над чем еще нужно позаботиться. Иногда вы также можете заметить потенциальную проблему в коде, но не хотите прекращать концентрироваться на текущей проблеме. В этом случае используйте комментарии `TODO` или `FIXME`. + +![Комментарии TODO и FIXME](/assets/develop/misc/using-the-ide/comments_03.png) + +IntelliJ будет отслеживать их в окне `TODO` и может уведомить вас, если вы зафиксируете код, +который использует этот тип комментариев. + +![Комментарии TODO и FIXME](/assets/develop/misc/using-the-ide/comments_04.png) + +![Коммит с TODO](/assets/develop/misc/using-the-ide/comments_05.png) + +### Javadocs{#javadocs} + +Отличным способом документирования вашего кода является использование JavaDoc. JavaDocs не только предоставляют полезную информацию для реализации методов и классов, но и глубоко интегрированы в IntelliJ. + +При наведении курсора на имена методов или классов, к которым добавлены комментарии JavaDoc, эта информация будет отображена в их информационном окне. + +![JavaDoc](/assets/develop/misc/using-the-ide/comments_06.png) + +Чтобы начать, просто напишите `/**` над определением метода или класса и нажмите Enter. IntelliJ автоматически сгенерирует строки для возвращаемого значения и параметров, но вы можете изменить их по своему усмотрению. Доступно множество пользовательских функций, а при необходимости можно использовать HTML. + +Класс `ScreenHandler` в Minecraft имеет несколько примеров. Чтобы переключить вид рендеринга, используйте кнопку пера рядом с номерами строк. + +![JavaDoc editing](/assets/develop/misc/using-the-ide/comments_07.png) + +## Дальнейшая оптимизация IntelliJ{#optimizing-intellij-further} + +Существует еще множество простых приемов и полезных трюков, описание которых выходит за рамки этой страницы. +На сайте Jetbrains есть много хороших статей, видео и страниц документации о том, как еще больше настроить свое рабочее пространство. + +### Постфиксное завершение{#postfix-completion} + +Используйте PostFix Completion для быстрого изменения кода после его написания. Часто используемые примеры содержат `.not`, `.if`, `.var`, `.null`, `.nn`, `.for`, `.fori`, `.return` и `.new`. Помимо существующих, вы также можете создать свои собственные в настройках IntelliJ. + + + +### Живые шаблоны{#live-templates} + +Используйте живые шаблоны для более быстрой генерации собственного шаблонного кода. + + + +### Дополнительные советы и рекомендации{#more-tips} + +Антон Архипов из Jetbrains также подробно рассказал о сопоставлении регулярных выражений, дополнении кода, отладке и многих других темах в IntelliJ. + + + +Для получения более подробной информации посетите [сайт советов и рекомендаций Jetbrains](https://blog.jetbrains.com/idea/category/tips-tricks/). Most of their posts are also applicable to Fabric's ecosystem. + +--- diff --git a/versions/1.21/translated/ru_ru/develop/index.md b/versions/1.21/translated/ru_ru/develop/index.md new file mode 100644 index 000000000..64243c4df --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/index.md @@ -0,0 +1,14 @@ +--- +title: Руководства для разработчиков +description: "Наш подбор руководств для разработчиков, написанных сообществом, охватывает широкий спектр тем: от настройки среды разработки до более продвинутых тем, таких как отрисовка и сетевое взаимодействие." +--- + +# Руководства для разработчиков {#developer-guides} + +Написанные сообществом, эти руководства охватывают широкий спектр тем: от настройки сред разработки до более сложных вопросов, таких как отрисовка и сетевые взаимодействия. + +Ознакомьтесь с боковой панелью, где собран полный список доступных руководств. Если вы ищете что-то конкретное, строка поиска в верхней части страницы — ваш лучший помощник. + +Готовый мод с исходным кодом, используемым в этой документации, доступен в [папке `/reference` на GitHub](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21). + +Если вы хотите внести свой вклад в документацию Fabric, вы можете найти её исходный код на [GitHub](https://github.com/FabricMC/fabric-docs) и ознакомиться с соответствующим [руководством по внесению вклада](../contributing). diff --git a/versions/1.21/translated/ru_ru/develop/items/custom-armor.md b/versions/1.21/translated/ru_ru/develop/items/custom-armor.md new file mode 100644 index 000000000..0d0e20dcc --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/custom-armor.md @@ -0,0 +1,160 @@ +--- +title: Собственная броня +description: Вы узнаете как создавать собственные комплекты брони. +authors: + - IMB11 +--- + +# Собственная броня {#custom-armor} + +Броня дает игроку повышенную защиту от атак мобов и других игроков. + +## Создание класса для материалов брони {#creating-an-armor-materials-class} + +Материалы брони, как и предметы и блоки, необходимо регистрировать. Создадим класс `ModArmorMaterials` для организации хранения наших материалов для брони. + +Вам нужно будет добавить статический метод `initialize()` к этому классу и вызвать его из точки входа вашего мода, чтобы зарегистрировать материалы. + +```java +// Within the ModArmorMaterials class +public static void initialize() {}; +``` + +:::warning +Убедитесь, что вызываете этот метод **до** регистрации предметов, так как материалы должны регистрироваться до создания предметов. +::: + +```java +@Override +public void onInitialize() { + ModArmorMaterials.initialize(); +} +``` + +--- + +Внутри класса `ModArmorMaterials` необходимо создать статический метод для регистрации материалов брони. Этот метод должен возвращать запись материала в реестре, которая в дальнейшем будет использована в конструкторе `ArmorItem` для создания предмета брони. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Свойства материала брони {#armor-material-properties} + +:::tip +Если вам сложно оценить значение любого из этих свойств, рассмотрите возможность изучения стандартных материалов брони в классе `ArmorMaterials`. +::: + +При создании материала брони вам необходимо определить следующие свойства: + +### Очки защиты {#defense-points} + +:::warning +Обязательно укажите стоимость каждого типа доспехов, которые вы планируете создать, и зарегистрируйте их как предмет. Если вы создадите предмет для брони без установленного значения очков защиты, игра сломается, а в следствии вылетит. +::: + +Карта `defensePoints` используется для определения количества очков защиты, которые будет обеспечивать каждая часть брони. Чем выше число, тем большую защиту обеспечит элемент брони. Карта должна содержать запись для каждого типа доспехов. + +### Зачарования {#enchantability} + +Свойство «зачаровываемость» определяет, насколько легко можно зачаровать доспехи. Чем выше число, тем больше чар может получить броня. + +### Звук экипировки {#equip-sound} + +Свойство `equipSound` — это звук, который будет воспроизводиться при надевании доспехов. Этот звук должен быть записью реестра `SoundEvent`. Если вы планируете создавать собственные звуки, а не полагаться на стандартные звуки в классе `SoundEvents`, рассмотрите возможность заглянуть на страницу [Пользовательские звуковые события](../sounds/custom). + +### Ингредиент(ы) для ремонта {#repair-ingredient} + +Свойство `repairIngredientSupplier` является поставщиком `Ингредиента`, который используется для ремонта брони. Этот ингредиент может быть практически любым, рекомендуется установить его таким же, как ингредиент материала, который использовался для изготовления самих предметов брони. + +### Прочность {#toughness} + +Свойство «прочность» определяет, какой урон может поглотить броня. Чем выше число, тем больше урона поглотит броня. + +### Сопротивление отбрасыванию {#knockback-resistance} + +Свойство «Сопротивление отбрасыванию» определяет, насколько сильно отбрасывает игрока при ударе. Чем выше число, тем меньше отбрасывание получит игрок. + +### Окрашиваемый {#dyeable} + +Свойство `dyeable` — это логическое значение, определяющее, можно ли красить броню. Если установлено значение `true`, броню можно красить с помощью красителей на верстаке. + +Если вы решили сделать свою броню окрашиваемой, то слои брони и текстуры предметов должны быть **предназначены для окрашивания**, поскольку краска будет накладываться на текстуру, а не заменять ее. Взгляните, например, на классическую кожаную броню из Minecraft: текстуры выполнены в оттенках серого, а краска нанесена поверх нее, из-за чего броня меняет цвет. + +## Регистрация материала брони {#registering-the-armor-material} + +Теперь, когда вы создали вспомогательный метод, который можно использовать для регистрации материалов брони, вы можете зарегистрировать свои собственные материалы брони как статическое поле в классе `ModArmorMaterials`. + +Для этого примера мы создадим броню Guidite со следующими свойствами: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## Создание предметов брони {#creating-the-armor-items} + +Теперь, когда вы зарегистрировали материал, вы можете создать предметы брони в своем классе `ModItems`: + +Очевидно, что комплект брони необязательно должен включать все типы предметов, вы можете иметь комплект, состоящий только из ботинок, штанов и т.д. — классический черепаший панцирь — хороший пример комплекта брони с отсутствующими слотами. + +### Долговечность {#durability} + +В отличие от `ToolMaterial`, `ArmorMaterial` не хранит никакой информации о прочности предметов. +По этой причине прочность необходимо вручную добавлять в «Item.Settings» предметов брони при их регистрации. + +Это достигается с помощью метода `maxDamage` в классе `Item.Settings`. +Различные слоты брони имеют разную базовую прочность, которая обычно умножается на общий множитель материала брони, но можно использовать и жестко запрограммированные значения. + +Для брони Guidite мы будем использовать общий множитель брони, хранящийся вместе с материалом брони: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +Затем мы можем создать предметы брони, используя константу прочности: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Вам также потребуется **добавить предметы в группу предметов**, если вы хотите, чтобы они были доступны из творческого инвентаря. + +Как и для всех элементов, для них также следует создать ключи перевода. + +## Текстурирование и моделирование {#texturing-and-modelling} + +Вам нужно будет создать два набора текстур: + +- Текстуры и модели самих предметов. +- Фактическая текстура брони, которая видна, когда существо носит броню. + +### Текстуры и модели предметов {#item-textures-and-model} + +Эти текстуры ничем не отличаются от других предметов — вам необходимо создать текстуры и создать общую сгенерированную модель предмета, что было рассмотрено в руководстве [Создание вашего первого предмета](./first-item#adding-a-texture-and-model). + +В качестве примера вы можете использовать следующие текстуры и модель JSON в качестве справочного материала. + + + +:::info +Вам понадобятся файлы моделей JSON для всех предметов, а не только для шлема, принцип тот же, что и для других моделей предметов. +::: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json) + +Как видите, в игре предметы брони должны иметь подходящие модели: + +![Модели предметов брони](/assets/develop/items/armor_1.png) + +## Текстуры и модели брони {#armor-textures-and-model} + +Когда сущность носит вашу броню, в настоящее время отображается отсутствующая текстура: + +![Сломанная модель брони на игроке](/assets/develop/items/armor_2.png). + +Для текстуры брони есть два слоя, оба должны присутствовать. + +Поскольку в нашем случае имя материала брони — `guidite`, то расположение текстур будет следующим: + +- `assets//textures/models/armor/guidite_layer_1.png` +- `assets//textures/models/armor/guidite_layer_2.png` + + + +Первый слой содержит текстуры для шлема и нагрудника, а второй слой содержит текстуры для штанов и ботинок. + +При наличии этих текстур вы сможете увидеть свою броню на существах, которые ее носят: + +![Рабочая модель брони на игроке](/assets/develop/items/armor_3.png). diff --git a/versions/1.21/translated/ru_ru/develop/items/custom-data-components.md b/versions/1.21/translated/ru_ru/develop/items/custom-data-components.md new file mode 100644 index 000000000..09912982f --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/custom-data-components.md @@ -0,0 +1,271 @@ +--- +title: Пользовательские компоненты данных +description: Узнайте, как добавлять пользовательские данные к вашим товарам, используя новую систему компонентов 1.20.5. +authors: + - Romejanic +--- + +# Пользовательские компоненты данных {#custom-data-components} + +По мере того как ваши элементы становятся более сложными, вам может потребоваться хранить специальные данные, связанные с каждым элементом. Игра позволяет хранить постоянные данные в `ItemStack`, и начиная с версии 1.20.5 мы делаем это с помощью **Компонентов данных**. + +Компоненты данных заменяют данные NBT из предыдущих версий структурированными типами данных, которые можно применять к `ItemStack` для хранения постоянных данных об этом стеке. Компоненты данных имеют пространство имен, что означает, что мы можем реализовать собственные компоненты данных для хранения пользовательских данных о `ItemStack` и доступа к ним позже. Полный список компонентов данных vanilla можно найти на этой [странице вики Minecraft](https://minecraft.wiki/w/Data_component_format#List_of_components). + +Наряду с регистрацией пользовательских компонентов на этой странице рассматривается общее использование API компонентов, которое также применимо к ванильным компонентам. Вы можете просмотреть и получить доступ к определениям всех ванильных компонентов в классе `DataComponentTypes`. + +## Регистрация компонента {#registering-a-component} + +Как и все остальное в вашем моде, вам необходимо зарегистрировать свой пользовательский компонент с помощью `ComponentType`. Этот тип компонента принимает универсальный аргумент, содержащий тип значения вашего компонента. Мы более подробно рассмотрим это далее, когда будем рассматривать [базовые](#basic-data-components) и [расширенные](#advanced-data-components) компоненты. + +Выберите подходящий класс для размещения этого кода. В этом примере мы создадим новый пакет с именем `component` и класс, содержащий все типы наших компонентов, с именем `ModComponents`. Убедитесь, что вы вызвали `ModComponents.initialize()` в вашем [инициализаторе мода](./getting-started/project-structure#entrypoints). + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Это базовый шаблон для регистрации типа компонента: + +```java +public static final ComponentType MY_COMPONENT_TYPE = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "my_component"), + ComponentType.builder().codec(null).build() +); +``` + +Здесь есть несколько вещей, на которые стоит обратить внимание. В первой и четвертой строках вы можете увидеть `?`. Он будет заменен типом значения вашего компонента. Мы скоро это заполним. + +Во-вторых, вы должны предоставить `Идентификатор`, содержащий предполагаемый идентификатор вашего компонента. Это пространство имен с идентификатором вашего мода. + +Наконец, у нас есть `ComponentType.Builder`, который создает фактический экземпляр `ComponentType` и регистрируется. Здесь содержится еще одна важная деталь, которую нам нужно будет обсудить: `Codec` вашего компонента. В настоящее время это поле пустое, но мы скоро его заполним. + +## Базовые компоненты данных {#basic-data-components} + +Базовые компоненты данных (например, `minecraft:damage`) состоят из одного значения данных, например `int`, `float`, `boolean` или `String`. + +В качестве примера давайте создадим значение `Integer`, которое будет отслеживать, сколько раз игрок щелкнул правой кнопкой мыши, удерживая наш предмет. Давайте обновим регистрацию нашего компонента следующим образом: + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Вы можете видеть, что теперь мы передаем `` в качестве нашего универсального типа, указывая, что этот компонент будет сохранен как одно значение `int`. В качестве нашего кодека мы используем предоставленный кодек `Codec.INT`. Для таких простых компонентов, как этот, можно обойтись использованием базовых кодеков, но для более сложных сценариев может потребоваться специальный кодек (об этом мы кратко поговорим позже). + +Если вы запустите игру, вы сможете ввести такую ​​команду: + +![/give command showing the custom component](/assets/develop/items/custom_component_0.png) + +При выполнении команды вы должны получить элемент, содержащий компонент. Однако в настоящее время мы не используем наш компонент для каких-либо полезных целей. Давайте начнем с прочтения значения компонента таким образом, чтобы мы могли его увидеть. + +## Значение компонента чтения {#reading-component-value} + +Давайте добавим новый элемент, который будет увеличивать счетчик каждый раз, когда по нему щелкают правой кнопкой мыши. Вам следует прочитать страницу [Взаимодействие с пользовательскими элементами](./custom-item-interactions), где описаны методы, которые мы будем использовать в этом руководстве. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Не забудьте, как обычно, зарегистрировать элемент в классе `ModItems`. + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings() +), "counter"); +``` + +Мы добавим код подсказки, чтобы отображать текущее значение количества кликов при наведении курсора на наш предмет в инвентаре. Мы можем использовать метод `get()` в нашем `ItemStack`, чтобы получить значение нашего компонента следующим образом: + +```java +int clickCount = stack.get(ModComponents.CLICK_COUNT_COMPONENT); +``` + +Это вернет текущее значение компонента как тип, который мы определили при регистрации нашего компонента. Затем мы можем использовать это значение для добавления записи всплывающей подсказки. Добавьте эту строку в метод `appendTooltip` в классе `CounterItem`: + +```java +public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + int count = stack.get(ModComponents.CLICK_COUNT_COMPONENT); + tooltip.add(Text.translatable("item.fabric-docs-reference.counter.info", count).formatted(Formatting.GOLD)); +} +``` + +Не забудьте обновить свой языковой файл (`/assets//lang/en_us.json`) и добавить в него следующие две строки: + +```json +{ + "item.fabric-docs-reference.counter": "Counter", + "item.fabric-docs-reference.counter.info": "Used %1$s times" +} +``` + +Запустите игру и выполните эту команду, чтобы получить новый предмет счетчик со значением 5. + +```mcfunction +/give @p fabric-docs-reference:counter[fabric-docs-reference:click_count=5] +``` + +При наведении курсора на этот предмет в инвентаре вы увидите количество, отображаемое во всплывающей подсказке! + +![Подсказка с надписью «Использовано 5 раз»](/assets/develop/items/custom_component_1.png) + +Однако если вы дадите себе новый предмет Counter _без_ пользовательского компонента, игра вылетит при наведении курсора на предмет в инвентаре. В отчете о сбое вы должны увидеть такую ​​ошибку: + +```log +java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "net.minecraft.item.ItemStack.get(net.minecraft.component.ComponentType)" is null + at com.example.docs.item.custom.CounterItem.appendTooltip(LightningStick.java:45) + at net.minecraft.item.ItemStack.getTooltip(ItemStack.java:767) +``` + +As expected, since the `ItemStack` doesn't currently contain an instance of our custom component, calling `stack.get()` with our component type will return `null`. + +Для решения этой проблемы мы можем использовать три решения. + +### Установка значения компонента по умолчанию {#setting-default-value} + +Когда вы регистрируете свой элемент и передаете объект `Item.Settings` в конструктор элемента, вы также можете предоставить список компонентов по умолчанию, которые применяются ко всем новым элементам. Если вернуться к нашему классу `ModItems`, где мы регистрируем `CounterItem`, мы можем добавить значение по умолчанию для нашего пользовательского компонента. Добавьте это, чтобы для новых элементов отображалось количество «0». + +@[code transcludeWith=::_13](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +При создании нового элемента он автоматически применит наш пользовательский компонент с заданным значением. + +:::warning +Используя команды, можно удалить компонент по умолчанию из `ItemStack`. Вам следует обратиться к следующим двум разделам, чтобы правильно обработать ситуацию, когда компонент отсутствует в вашем изделии. +::: + +### Чтение со значением по умолчанию {#reading-default-value} + +Кроме того, при чтении значения компонента мы можем использовать метод `getOrDefault()` нашего объекта `ItemStack`, чтобы вернуть указанное значение по умолчанию, если компонент отсутствует в стеке. Это защитит от любых ошибок, возникающих из-за отсутствия какого-либо компонента. Мы можем настроить код нашей подсказки следующим образом: + +```java +int clickCount = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); +``` + +Как видите, этот метод принимает два аргумента: тип нашего компонента, как и раньше, и значение по умолчанию, которое будет возвращаться, если компонент отсутствует. + +### Проверка существования компонента {#checking-if-component-exists} + +Вы также можете проверить наличие определенного компонента в `ItemStack`, используя метод `contains()`. Он принимает тип компонента в качестве аргумента и возвращает `true` или `false` в зависимости от того, содержит ли стек этот компонент. + +```java +boolean exists = stack.contains(ModComponents.CLICK_COUNT_COMPONENT); +``` + +### Исправление ошибки {#fixing-the-error} + +Мы выберем третий вариант. Поэтому наряду с добавлением значения компонента по умолчанию мы также проверим, присутствует ли компонент в стеке, и покажем подсказку только в том случае, если это так. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Запустите игру снова и наведите курсор на предмет без компонента. Вы должны увидеть надпись «Использовано 0 раз», и игра больше не будет вылетать. + +![Подсказка с сообщением «Использовано 0 раз»](/assets/develop/items/custom_component_2.png) + +Попробуйте создать свой счетчик, удалив наш пользовательский компонент. Для этого можно использовать следующую команду: + +```mcfunction +/give @p fabric-docs-reference:counter[!fabric-docs-reference:click_count] +``` + +При наведении курсора на этот элемент подсказка должна отсутствовать. + +![Встречный элемент без подсказки](/assets/develop/items/custom_component_7.png) + +## Обновление значения компонента {#setting-component-value} + +Теперь попробуем обновить значение нашего компонента. Мы собираемся увеличивать количество кликов каждый раз, когда используем наш элемент Counter. Чтобы изменить значение компонента в `ItemStack`, мы используем метод `set()` следующим образом: + +```java +stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Он принимает тип нашего компонента и значение, которое мы хотим ему присвоить. В данном случае это будет наше новое количество кликов. Этот метод также возвращает старое значение компонента (если оно присутствует), что может быть полезно в некоторых ситуациях. Например: + +```java +int oldValue = stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +Давайте настроим новый метод `use()` для считывания старого количества кликов, увеличения его на единицу, а затем установки обновленного количества кликов. + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +Теперь попробуйте запустить игру и щелкнуть правой кнопкой мыши, держа в руке предмет Counter. Если вы откроете свой инвентарь и снова посмотрите на предмет, вы увидите, что показатель использования увеличился пропорционально количеству кликов по нему. + +![Подсказка с надписью «Использовано 8 раз»](/assets/develop/items/custom_component_3.png) + +## Удаление значения компонента {#removing-component-value} + +Вы также можете удалить компонент из `ItemStack`, если он больше не нужен. Это делается с помощью метода `remove()`, который принимает тип вашего компонента. + +```java +stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +Этот метод также возвращает значение компонента до его удаления, поэтому его можно использовать следующим образом: + +```java +int oldCount = stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +## Расширенные компоненты данных {#advanced-data-components} + +Возможно, вам придется хранить несколько атрибутов в одном компоненте. В качестве простого примера компонент `minecraft:food` хранит несколько значений, связанных с едой, таких как `nutrition`, `saturation`, `eat_seconds` и другие. В этом руководстве мы будем называть их «композитными» компонентами. + +Для составных компонентов необходимо создать класс `record` для хранения данных. Это тип, который мы зарегистрируем в нашем типе компонента, и то, что мы будем читать и записывать при взаимодействии с `ItemStack`. Начнем с создания нового класса записи в пакете `component`, который мы создали ранее. + +```java +public record MyCustomComponent() { +} +``` + +Обратите внимание, что после имени класса стоят скобки. Здесь мы определяем список свойств, которые должен иметь наш компонент. Давайте добавим число с плавающей точкой и логическое значение с именами `температура` и `сожженный` соответственно. + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Поскольку мы определяем пользовательскую структуру данных, для нашего варианта использования не будет готового `Кодека`, как в случае с [базовым компонентом](#basic-data-components). Это значит, что нам придется создать собственный кодек. Давайте определим его в нашем классе записи, используя `RecordCodecBuilder`, на который мы сможем ссылаться после регистрации компонента. Более подробную информацию об использовании `RecordCodecBuilder` можно найти в [этом разделе страницы Кодеки](../codecs#merging-codecs-for-record-like-classes). + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +Вы можете видеть, что мы определяем список пользовательских полей на основе примитивных типов `Codec`. Однако мы также сообщаем ей, как называются наши поля, используя `fieldOf()`, а затем используем `forGetter()`, чтобы сообщить игре, какой атрибут нашей записи следует заполнить. + +Вы также можете определить необязательные поля, используя `optionalFieldOf()` и передав значение по умолчанию в качестве второго аргумента. Любые поля, не отмеченные как необязательные, будут обязательными при настройке компонента с помощью `/give`, поэтому обязательно отметьте все необязательные аргументы как таковые при создании кодека. + +Наконец, мы вызываем `apply()` и передаем конструктор нашей записи. Более подробную информацию о создании кодеков и более сложных вариантах использования можно найти на странице [Кодеки](../codecs). + +Регистрация составного компонента аналогична предыдущей. Мы просто передаем наш класс записи как универсальный тип, а наш пользовательский `Codec` — в метод `codec()`. + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +Теперь начинайте игру. Попробуйте применить компонент с помощью команды `/give`. Значения составных компонентов передаются как объект, заключенный в `{}`. Если вы поставите пустые фигурные скобки, вы увидите сообщение об ошибке, сообщающее, что требуемый ключ `temperature` отсутствует. + +![Дайте команду, показывающую отсутствующий ключ "температура"](/assets/develop/items/custom_component_4.png) + +Добавьте значение температуры к объекту, используя синтаксис `temperature:8.2`. При желании можно также передать значение для `burnt`, используя тот же синтаксис, но либо `true`, либо `false`. Теперь вы должны увидеть, что команда действительна и может предоставить вам элемент, содержащий компонент. + +![Верная команда give, показывающая оба свойства](/assets/develop/items/custom_component_5.png) + +### Получение, настройка и удаление дополнительных компонентов {#getting-setting-removing-advanced-comps} + +Использование компонента в коде такое же, как и раньше. Использование `stack.get()` вернет экземпляр вашего класса `record`, который затем можно использовать для чтения значений. Поскольку записи доступны только для чтения, вам потребуется создать новый экземпляр записи, чтобы обновить значения. + +```java +// read values of component +MyCustomComponent comp = stack.get(ModComponents.MY_CUSTOM_COMPONENT); +float temp = comp.temperature(); +boolean burnt = comp.burnt(); + +// set new component values +stack.set(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(8.4f, true)); + +// check for component +if (stack.contains(ModComponents.MY_CUSTOM_COMPONENT)) { + // do something +} + +// remove component +stack.remove(ModComponents.MY_CUSTOM_COMPONENT); +``` + +Вы также можете задать значение по умолчанию для составного компонента, передав объект компонента в `Item.Settings`. Например: + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings().component(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(0.0f, false)) +), "counter"); +``` + +Теперь вы можете хранить пользовательские данные в `ItemStack`. Используйте ответственно! + +![Элемент, показывающий подсказки для количества кликов, температуры и сожженного](/assets/develop/items/custom_component_6.png) diff --git a/versions/1.21/translated/ru_ru/develop/items/custom-item-groups.md b/versions/1.21/translated/ru_ru/develop/items/custom-item-groups.md new file mode 100644 index 000000000..0f898a132 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/custom-item-groups.md @@ -0,0 +1,38 @@ +--- +title: Собственные вкладки предметов +description: Вы узнаете как создавать собственные вкладки предметов и добавлять в них предметы. +authors: + - IMB11 +--- + +# Собственные вкладки предметов {#custom-item-groups} + +Вкладки предметов — это вкладки для отображения предметов в творческом инвентаре. Вы можете создать собственную вкладку предметов. Это будет полезно, если ваш мод добавляет много предметов, и вы хотите хранить их в одном месте, чтобы игрок мог легко получить к ним доступ. + +## Создание вкладки с предметами {#creating-the-item-group} + +Процесс создания необычайно прост. Просто создайте в классе с вашими предметами новое статическое неизменяемое поле для хранения новой вкладки предметов и ключа реестра для неё. После этого можно использовать событие вкладки с предметами как при добавлении предметов в ванильную вкладку с предметами: + +@[code transcludeWith=:::9](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::_12](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +
+ +Новая вкладка с предметами появится в творческом инвентаре. Однако, она не переведена — вам необходимо добавить ключ перевода в файл с переводами как при переводе вашего первого предмета. + +![Вкладка предметов без перевода в творческом инвентаре](/assets/develop/items/itemgroups_0.png) + +## Добавление ключа перевода {#adding-a-translation-key} + +Если при создании группы предметов вы передали`Text.translatable` в метод `displayName`, вам необходимо добавить перевод названия вкладки в свой файл перевода. + +```json +{ + "itemGroup.fabric_docs_reference": "Fabric Docs Reference" +} +``` + +Теперь у вкладки отображается правильное название: + +![Законченная вкладка с переводом и предметами](/assets/develop/items/itemgroups_1.png) diff --git a/versions/1.21/translated/ru_ru/develop/items/custom-item-interactions.md b/versions/1.21/translated/ru_ru/develop/items/custom-item-interactions.md new file mode 100644 index 000000000..4ddeeb327 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/custom-item-interactions.md @@ -0,0 +1,71 @@ +--- +title: Собственные интерактивные предметы +description: Вы научитесь создавать предметы, которые используют ванильные события. +authors: + - IMB11 +--- + +# Собственные интерактивные предметы {#custom-item-interactions} + +Базовые предметы могут зайти так далеко, что вы можете добавить предмет, который имеет интерактивность с миром при использовании. + +Есть несколько ключевых классов которые вы должны понять, прежде чем будете рассматривать события с ванильными предметами. + +## TypedActionResult {#typedactionresult} + +Для предметов более распространённым `TypedActionResult` является `ItemStacks` - этот класс говорит игре, что нужно заменять (или не заменять) после того, как событие произошло. + +Если в событие ничего не произошло, вам нужно будет использовать метод `TypedActionResult#pass(stack)`, где `stack` это текущий стек предметов. + +Вы можете получить текущий стек предметов, получая стек из руки игрока. Обычно события, требующие `TypedActionResult`, передают эту функцию методу события. + +```java +TypedActionResult.pass(user.getStackInHand(hand)) +``` + +Если вы передадите текущий стек, тогда ничего не изменится, независимо от того, объявите ли вы событие неудавшимся, прошедшим/проигнорируемым или успехом. + +Если вы хотите удалить текущий стек, вам следует передать пустой. То же самое сказать про уменьшение, вы извлекаете текущий стек и уменьшаете его на количество которое вы хотите: + +```java +ItemStack heldStack = user.getStackInHand(hand); +heldStack.decrement(1); +TypedActionResult.success(heldStack); +``` + +## ActionResult {#actionresult} + +Аналогичным образом, `ActionResult` говорит игре статус события, не смотря было ли оно пройдено/проигнорированно, неудачно или успешно. + +## Переопределяемые события {#overridable-events} + +К счастью, класс предмета имеет множество методам, которые можно переопределить, чтобы добавить дополнительную функциональность вашим предметам. + +:::info +Отличный пример использование этих событие вы можете найти на странице [Воспроизведение SoundEvents](../sounds/using-sounds), где событие `useOnBlock` воспроизводит звук когда игрок кликает правой кнопкой мыши по блоку. +::: + +| Метод | Информация | +| --------------- | ------------------------------------------------------------------------------------- | +| `postHit` | Вызывается когда игрок, ударяет сущность. | +| `postMine` | Вызывается когда игрок, ломает блок. | +| `inventoryTick` | Вызывается каждый тик когда предмет находится в инвентаре. | +| `onCraft` | Вызывается когда предмет, создаётся. | +| `useOnBlock` | Вызывается когда игрок кликает правой кнопкой мыши предметом на блок. | +| `use` | Вызывается когда игрок кликает правой кнопкой мыши предметом. | + +## Событие `use()`{#use-event} + +Допустим, что вы хотите сделать предмет, который вызывает молнию перед игроком, вам нужно будет создать отдельный класс. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Событие `use`, вероятно, самое полезное из всех, вы можете использовать это событие, чтобы призвать молнию, вы должны создать её перед игроками в 10 блоков от направления. + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Как обычно, вам необходимо зарегистрировать свой предмет, добавьте модель и текстуру. + +Как видите, молния должна появиться в 10 блоках перед вами, игроком. + + diff --git a/versions/1.21/translated/ru_ru/develop/items/custom-tools.md b/versions/1.21/translated/ru_ru/develop/items/custom-tools.md new file mode 100644 index 000000000..7d91b299b --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/custom-tools.md @@ -0,0 +1,118 @@ +--- +title: Оружие и инструменты +description: Узнайте, как создавать собственные инструменты и настраивать их свойства. +authors: + - IMB11 +--- + +# Инструменты {#tools} + +Инструменты необходимы для выживания и развития, позволяя игрокам собирать ресурсы, строить здания и защищаться. + +## Создание Материала Инструмента {#creating-a-tool-material} + +::: info +If you're creating multiple tool materials, consider using an `Enum` to store them. Vanilla does this in the `ToolMaterials` class, which stores all the tool materials that are used in the game. + +Этот класс также можно использовать для определения свойств материала вашего инструмента по отношению к классическим материалам инструмента. +::: + +"Вы можете создать материал для инструмента, создав новый класс, который его наследует — в этом примере я буду создавать инструменты «Guidite»: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +Материал инструмента сообщает игре следующую информацию: + +- ### Прочность - `getDurability()` {#durability} + + Сколько раз можно использовать инструмент, прежде чем он сломается. + + **Пример** + + @[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +- ### Скорость добычи - `getMiningSpeedMultiplier()` {#mining-speed} + + Если инструмент используется для разрушения блоков, с какой скоростью он должен их разрушать? + + Для справки: скорость добычи алмазного инструмента составляет 8,0F, а скорость добычи каменного инструмента — 4,0F. + + **Пример** + + @[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +- ### Урон от атаки - `getAttackDamage()` {#attack-damage} + + Сколько единиц урона должен наносить инструмент при использовании его в качестве оружия против другого существа? + + **Пример** + + @[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +- ### Обратный тег - `getMiningLevel()` {#inverse-tag} + + Обратный тег показывает, что инструмент _**не может**_ добывать. Например, использование тега `BlockTags.INCORRECT_FOR_WOODEN_TOOL` запрещает инструмент добывать определенные блоки: + + ```json + { + "values": [ + "#minecraft:needs_diamond_tool", + "#minecraft:needs_iron_tool", + "#minecraft:needs_stone_tool" + ] + } + ``` + + Это означает, что инструмент не может добывать блоки, для которых требуется алмазный, железный или каменный инструмент. + + **Пример** + + Мы воспользуемся тегом железного инструмента. Это не позволяет инструментам Guidite добывать блоки, для которых требуется инструмент прочнее железа. + + @[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + + Если вы хотите использовать пользовательский тег, вы можете использовать `TagKey.of(...)` для создания пользовательского ключа тега. + +- ### Зачарование - `getEnchantability()` {#enchantability} + + Насколько легко получить лучшие и более высокие уровни чар с помощью этого предмета? Для справки: зачаровываемость золота составляет 22, в то время как зачаровываемость незерита — 15. + + **Пример** + + @[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +- ### Ингредиент(ы) для восстановления - `getRepairIngredient()` {#repair-ingredient} + + Какой предмет или предметы используются для ремонта инструмента? + + **Пример** + + @[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +После того как вы создали материал для инструмента и настроили его по своему вкусу, вы можете создать его экземпляр для использования в конструкторах предметов инструмента. + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +## Создание инструментов {#creating-tool-items} + +Используя ту же вспомогательную функцию, что и в руководстве [Создание вашего первого элемента](./first-item), вы можете создавать свои инструменты: + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Не забудьте добавить их в группу предметов, если вы хотите получить к ним доступ из творческого инвентаря! + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Вам также придется добавить текстуру, перевод предмета и модель предмета. Однако для модели элемента вам следует использовать модель `item/handheld` в качестве родительской. + +В этом примере я буду использовать следующую модель и текстуру для предмета «Меч Guidite»: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json) + + + +--- + +Вот и все! Если вы зайдете в игру, вы увидите свой(и) инструмент(ы) на вкладке инструментов в меню творческого инвентаря. + +![Finished tools in inventory](/assets/develop/items/tools_1.png) diff --git a/versions/1.21/translated/ru_ru/develop/items/first-item.md b/versions/1.21/translated/ru_ru/develop/items/first-item.md new file mode 100644 index 000000000..7053a0008 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/first-item.md @@ -0,0 +1,151 @@ +--- +title: Создание вашего первого предмета +description: Узнайте, как зарегистрировать предмет, добавить текстуру, модель и название. +authors: + - IMB11 + - dicedpixels +--- + +# Создание вашего первого предмета{#creating-your-first-item} + +На этой странице вы познакомитесь с некоторыми ключевыми концепциями, касающимися предметов, а также с тем, как их регистрировать, задавать текстуры, моделировать и давать названия. + +Если вы не знали, то все в Майнкрафте хранится в реестрах, и предметы не стали исключением. + +## Подготовка класса вашего предмета {#preparing-your-items-class} + +Для упрощения регистрации предмета вы можете создать метод, принимающий экземпляр предмета и строковый идентификатор. + +Этот метод будет создавать предмет с данным идентификатором и регистрировать его с помощью реестра предметов игры. + +Вы можете поместить этот метод в класс под именем `ModItems` (или как вы его назовете). + +Mojang уже сделали это со своими предметами! Загляните в класс `Items` для вдохновения. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Регистрация предмета{#registering-an-item} + +Теперь вы можете зарегистрировать предмет, используя метод. + +Конструктор предмета принимает экземпляр класса `Items.Settings` в качестве параметра. Этот класс позволяет вам настраивать параметры предмета через различные методы. + +::: tip +If you want to change your item's stack size, you can use the `maxCount` method in the `Items.Settings`/`FabricItemSettings` class. + +Это не сработает, если вы пометили предмет как повреждаемый, потому что размер для повреждаемых предметов всегда равен 1, для предотвращения эксплойтов дублирования. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Однако, когда вы перейдете в игру, то увидите, что нашего предмета не существует! Это потому что вы инициализировали класс не статически. + +Для этого вы можете добавить в свой класс публичный статический метод инициализации и вызывать его из класса `ModInitializer`. В настоящее время этот метод не принимает никаких аргументов. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java) + +Вызов метода класса статически инициализирует его, если он не был ранее загружен — это означает, что оцениваются все `статические` поля. Вот для чего нужен этот фиктивный метод `initialize`. + +## Добавление предмета к группе предметов{#adding-the-item-to-an-item-group} + +:::info +Если вы хотите добавить предмет в собственную категорию предметов, загляните в [Пользовательские категории предметов](./custom-item-groups) для дополнительной информации. +::: + +Для примера мы добавим этот элемент в ингредиенты `ItemGroup`, вам нужно будет использовать события группы элементов Fabric API, а именно `ItemGroupEvents.modifyEntriesEvent` + +Это может быть сделано в методе `initialize` вашего класса. + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Запустив игру, вы можете увидеть, что наш предмет зарегистрирован и находится в категории предметов "ингредиенты": + +![Предмет в категории ингридиентов](/assets/develop/items/first_item_0.png) + +Однако, не хватает следующего: + +- Модель предмета +- Текстура +- Перевод(название) + +## Наименование предмета {#naming-the-item} + +Сейчас у предмета нет перевода, поэтому вам необходимо его добавить. Ключ перевода уже предоставлен Minecraft: `item.mod_id.suspicious_substance`. + +Создайте новый файл JSON: `src/main/resources/assets//lang/en_us.json` и введите ключ перевода, а также его значение: + +```json +{ + "item.mod_id.suspicious_substance": "Suspicious Substance" +} +``` + +Вы можете перезапустить игру либо скомпилировать ваш мод и нажать F3 + T для подтверждения изменений. + +## Добавление текстуры и модели{#adding-a-texture-and-model} + +Чтобы задать вашему предмету текстуру и модель, просто создайте изображение текстуры 16x16 для вашего предмета и сохраните его по адресу`assets//textures/item`. Назовите файл текстуры, так же как предмет, но c расширением `.png`. + +В качестве примера вы можете использовать этот пример текстуры для `suspicious_substance.png` + + + +При перезапуске/перезагрузке игры вы должны увидеть, что у предмета по-прежнему нет текстуры, это потому, что вам нужно будет добавить модель, использующую эту текстуру. + +Вы собираетесь создать простую модель «item/generated», которая принимает на входе только текстуру и ничего больше. + +Создайте модель JSON в папке `assets//models/item` с тем же именем, что и у элемента; `suspicious_substance.json` + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) + +### Разбор модели JSON {#breaking-down-the-model-json} + +- `parent`: Это родительская модель, от которой будет унаследована данная модель. В данном случае это модель `item/generated`. +- `textures`: Здесь вы определяете текстуры для модели. Ключ `layer0` — это текстура, которую будет использовать модель. + +Большинство элементов будут использовать модель `item/generated` в качестве родительской, поскольку это простая модель, которая просто отображает текстуру. + +Существуют альтернативы, такие как item/handheld, который используется для предметов, удерживаемых в руке игрока, например, для инструментов. + +Теперь ваш предмет в игре должен выглядеть так: + +![Item with correct model](/assets/develop/items/first_item_2.png) + +## Сделать предмет компостируемым или топливом {#making-the-item-compostable-or-a-fuel} + +API Fabric предоставляет различные реестры, которые можно использовать для добавления дополнительных свойств к вашему элементу. + +Например, если вы хотите сделать свой предмет компостируемым, то вы можете использовать `CompostableItemRegistry`: + +@[code transcludeWith=:::_10](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Также если вы хотите сделать ваш предмет топливом, вы можете использовать класс `FuelRegistry`: + +@[code transcludeWith=:::_11](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## Добавление рецепта создания {#adding-a-basic-crafting-recipe} + + + +Если вы хотите добавить рецепт создания вашего предмета, вам необходимо поместить JSON-файл рецепта в папку `data//recipe`. + +Для получения более подробной информации о формате рецепта ознакомьтесь со следующими ресурсами: + +- [Recipe JSON Generator](https://crafting.thedestruc7i0n.ca/ +- [Minecraft Wiki - Recipe JSON](https://minecraft.wiki/w/Recipe#JSON_Format) + +## Пользовательские подсказки {#custom-tooltips} + +Если вы хотите, чтобы у вашего элемента была настраиваемая подсказка, вам нужно будет создать класс, расширяющий `Item`, и переопределить метод `appendTooltip`. + +:::info +В этом примере используется класс `LightningStick`, созданный на странице [Взаимодействия пользовательских элементов](./custom-item-interactions). +::: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +Каждый вызов `add()` добавляет одну строку в подсказку. + +![Tooltip Showcase](/assets/develop/items/first_item_3.png) diff --git a/versions/1.21/translated/ru_ru/develop/items/food.md b/versions/1.21/translated/ru_ru/develop/items/food.md new file mode 100644 index 000000000..b9343a4bf --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/food.md @@ -0,0 +1,52 @@ +--- +title: Предметы еды +description: Узнайте, как добавить FoodComponent к предмету, чтобы сделать его съедобным, и как его настроить. +authors: + - IMB11 +--- + +# Предметы еды {#food-items} + +Еда — это ключевой аспект выживания в Minecraft, поэтому при создании съедобных предметов вам следует учитывать их использование с другими съедобными предметами. + +Если вы не создаете мод с очень мощными предметами, вам следует учесть: + +- Насколько сильное чувство голода добавляет или убирает ваш съедобный продукт. +- Какой эффект(ы) зелья оно дает? +- Доступно ли оно на ранней или конечной стадии игры? + +## Добавляем компонент еды {#adding-the-food-component} + +Чтобы добавить пищевой компонент к элементу, мы можем передать его экземпляру `Item.Settings`: + +```java +new Item.Settings().food(new FoodComponent.Builder().build()) +``` + +На данный момент это просто делает продукт съедобным и ничего более. + +Класс `FoodComponent.Builder` имеет множество методов, которые позволяют вам изменять то, что происходит, когда игрок съедает ваш предмет: + +| Метод | Описание | +| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `nutrition` | Устанавливает количество очков голода, которое восполнит ваш предмет. | +| `saturationModifier` | Устанавливает количество точек насыщенности, которые добавит ваш элемент. | +| `alwaysEdible` | Позволяет съесть ваш предмет независимо от уровня голода. | +| `snack` | Указывает, что ваш предмет — закуска. | +| `statusEffect` | Adds a status effect when you eat your item. Добавляет эффект статуса, когда вы съедаете свой предмет. | + +После того как вы изменили конструктор по своему вкусу, вы можете вызвать метод `build()`, чтобы получить `FoodComponent`. + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Подобно примеру на странице [Создание вашего первого элемента](./first-item), я буду использовать указанный выше компонент: + +@[code transcludeWith=:::poisonous_apple](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +Это делает предмет: + +- Всегда съедобным, может быть съеден независимо от уровня голода. +- «Закуска». +- Всегда дающим Отравление II на 6 секунд когда съеден. + + diff --git a/versions/1.21/translated/ru_ru/develop/items/potions.md b/versions/1.21/translated/ru_ru/develop/items/potions.md new file mode 100644 index 000000000..7b8c6db73 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/items/potions.md @@ -0,0 +1,50 @@ +--- +title: Зелья +description: Узнайте, как добавить собственное зелье для различных статусных эффектов. +authors: + - dicedpixels + - PandoricaVi + - Drakonkinst + - JaaiDead +--- + +# Зелья {#potions} + +Зелья — это расходные материалы, которые дают сущности определенный эффект. Игрок может варить зелья, используя Варочную Стойку, или получать их как предметы с помощью различных других игровых механик. + +## Пользовательские зелья {#custom-potions} + +Так же, как предметы и блоки, зелья необходимо регистрировать. + +### Создание зелья {#creating-the-potion} + +Начнем с объявления поля для хранения вашего экземпляра `Potion`. Мы будем напрямую использовать класс инициализатора для хранения этого. + +@[code lang=java transclude={18-27}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +Мы передаем экземпляр `StatusEffectInstance`, который принимает 3 параметра: + +- `RegistryEntry type` - Эффект. Здесь мы используем наш собственный эффект. В качестве альтернативы вы можете получить доступ к эффектам классического Minecraft + через класс `StatusEffects`. +- `int duration` - Длительность эффекта в игровых тиках. +- `int amplifier` - Усилитель эффекта. Например, Haste II будет иметь усилитель 1. + +:::info +Чтобы создать свой собственный эффект зелья, ознакомьтесь с руководством [Эффекты](../entities/effects). +::: + +### Регистрация зелья {#registering-the-potion} + +В нашем инициализаторе мы будем использовать событие `FabricBrewingRecipeRegistryBuilder.BUILD` для регистрации нашего зелья с помощью метода `BrewingRecipeRegistry.registerPotionRecipe`. + +@[code lang=java transclude={29-42}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +`registerPotionRecipe` принимает 3 параметра: + +- `RegistryEntry input` - Запись реестра для стартового зелья. Обычно это может быть бутылка с водой или мутное зелье. +- `Предмет предмета` - Предмет, являющийся основным ингредиентом зелья. +- `RegistryEntry output` - Результирующая запись реестра зелья. + +После регистрации вы сможете сварить зелье «Tater» из картофеля. + +![Эффект в инвентаре игрока](/assets/develop/tater-potion.png) diff --git a/versions/1.21/translated/ru_ru/develop/rendering/basic-concepts.md b/versions/1.21/translated/ru_ru/develop/rendering/basic-concepts.md new file mode 100644 index 000000000..4a51d5419 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/rendering/basic-concepts.md @@ -0,0 +1,162 @@ +--- +title: Основные концепции рендеринга +description: Изучите основные концепции рендеринга с использованием движка рендеринга Minecraft. +authors: + - IMB11 + - "0x3C50" +--- + +# Базовые концепции рендеринга {#basic-rendering-concepts} + +::: warning +Although Minecraft is built using OpenGL, as of version 1.17+ you cannot use legacy OpenGL methods to render your own things. Instead, you must use the new `BufferBuilder` system, which formats rendering data and uploads it to OpenGL to draw. + +Подводя итог, вам придется использовать систему рендеринга Minecraft или создать свою собственную, использующую `GL.glDrawElements()`. +::: + +На этой странице будут рассмотрены основы рендеринга с использованием новой системы, а также ключевые термины и концепции. + +Хотя большая часть рендеринга в Minecraft абстрагирована с помощью различных методов `DrawContext`, и вам, скорее всего, не придется касаться ничего из упомянутого здесь, все равно важно понимать основы того, как работает рендеринг. + +## `Tessellator` {#the-tessellator} + +`Tessellator` — это основной класс, используемый для рендеринга объектов в Minecraft. Это singleton, то есть в игре существует только один его экземпляр. Экземпляр можно получить с помощью `Tessellator.getInstance()`. + +## `BufferBuilder` {#the-bufferbuilder} + +`BufferBuilder` — это класс, используемый для форматирования и загрузки данных рендеринга в OpenGL. Он используется для создания буфера, который затем загружается в OpenGL для отрисовки. + +`Tessellator` используется для создания `BufferBuilder`, который используется для форматирования и загрузки данных рендеринга в OpenGL. + +### Инициализация `BufferBuilder` {#initializing-the-bufferbuilder} + +Прежде чем что-либо записать в `BufferBuilder`, его необходимо инициализировать. Это делается с помощью метода `Tessellator#begin(...)`, который принимает `VertexFormat` и режим отрисовки и возвращает `BufferBuilder`. + +#### Форматы вершин {#vertex-formats} + +`VertexFormat` определяет элементы, которые мы включаем в наш буфер данных, и описывает, как эти элементы должны передаваться в OpenGL. + +Доступны следующие элементы `VertexFormat`: + +| Элемент | Формат | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | +| `BLIT_SCREEN` | `{ position (3 floats: x, y and z), uv (2 floats), color (4 ubytes) }` | +| `POSITION_COLOR_TEXTURE_LIGHT_NORMAL` | `{ position, color, texture uv, texture light (2 shorts), texture normal (3 sbytes) }` | +| `POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL` | `{ position, color, texture uv, overlay (2 shorts), texture light, normal (3 sbytes) }` | +| `POSITION_TEXTURE_COLOR_LIGHT` | `{ position, texture uv, color, texture light }` | +| `POSITION` | `{ position }` | +| `POSITION_COLOR` | `{ position, color }` | +| `LINES` | `{ position, color, normal }` | +| `POSITION_COLOR_LIGHT` | `{ position, color, light }` | +| `POSITION_TEXTURE` | `{ position, uv }` | +| `POSITION_COLOR_TEXTURE` | `{ position, color, uv }` | +| `POSITION_TEXTURE_COLOR` | `{ position, uv, color }` | +| `POSITION_COLOR_TEXTURE_LIGHT` | `{ position, color, uv, light }` | +| `POSITION_TEXTURE_LIGHT_COLOR` | `{ position, uv, light, color }` | +| `POSITION_TEXTURE_COLOR_NORMAL` | `{ position, uv, color, normal }` | + +#### Режимы рисования {#draw-modes} + +Режим рисования определяет, как будут отображаться данные. Доступны следующие режимы рисования: + +| Режим рисования | Описание | +| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DrawMode.LINES` | Каждый элемент состоит из 2 вершин и представлен в виде одной линии. | +| `DrawMode.LINE_STRIP` | Для первого элемента требуется 2 вершины. Дополнительные элементы рисуются всего с одной новой вершиной, создавая непрерывную линию. | +| `DrawMode.DEBUG_LINES` | Аналогично `DrawMode.LINES`, но линия на экране всегда имеет ширину ровно в один пиксель. | +| `DrawMode.DEBUG_LINE_STRIP` | То же, что и `DrawMode.LINE_STRIP`, но линии всегда имеют ширину в один пиксель. | +| `DrawMode.TRIANGLES` | Каждый элемент состоит из 3 вершин, образующих треугольник. | +| `DrawMode.TRIANGLE_STRIP` | Начинается с 3 вершин первого треугольника. Каждая дополнительная вершина образует новый треугольник с двумя последними вершинами. | +| `DrawMode.TRIANGLE_FAN` | Начинается с 3 вершин первого треугольника. Каждая дополнительная вершина образует новый треугольник с первой вершиной и последней вершиной. | +| `DrawMode.QUADS` | Каждый элемент состоит из 4 вершин, образующих четырехугольник. | + +### Запись в `BufferBuilder` {#writing-to-the-bufferbuilder} + +После инициализации `BufferBuilder` вы можете записывать в него данные. + +`BufferBuilder` позволяет нам создавать наш буфер, вершина за вершиной. Чтобы добавить вершину, мы используем метод `buffer.vertex(matrix, float, float, float)`. Параметр `matrix` — это матрица преобразования, которую мы рассмотрим более подробно позже. Три параметра с плавающей точкой представляют собой координаты (x, y, z) положения вершины. + +Этот метод возвращает конструктор вершин, который мы можем использовать для указания дополнительной информации о вершине. При добавлении этой информации крайне важно соблюдать порядок, определенный в нашем `VertexFormat`. Если мы этого не сделаем, OpenGL может неправильно интерпретировать наши данные. После того как мы закончим построение вершины, просто продолжайте добавлять новые вершины и данные в буфер, пока не закончите. + +Также стоит понять концепцию отсечения (culling). Отсечение — это процесс удаления граней трехмерной фигуры, которые не видны с точки зрения наблюдателя. Если вершины грани указаны в неправильном порядке, грань может отображаться неправильно из-за отсечения. + +#### Что такое матрица трансформации? {#what-is-a-transformation-matrix} + +Матрица преобразования — это матрица размером 4x4, которая используется для преобразования вектора. В Minecraft матрица преобразования просто преобразует координаты, которые мы передаем, в вызов вершины. Преобразования позволяют масштабировать нашу модель, перемещать и вращать ее. + +Иногда ее называют матрицей позиций или матрицей моделей. + +Обычно его можно получить через класс `MatrixStack`, который можно получить через объект `DrawContext`: + +```java +drawContext.getMatrices().peek().getPositionMatrix(); +``` + +#### Рендеринг полосы треугольников {#rendering-a-triangle-strip} + +Проще объяснить, как писать в `BufferBuilder`, на практическом примере. Допустим, мы хотим что-то визуализировать, используя режим рисования `DrawMode.TRIANGLE_STRIP` и формат вершин `POSITION_COLOR`. + +Мы собираемся нарисовать вершины в следующих точках HUD (по порядку): + +```txt +(20, 20) +(5, 40) +(35, 40) +(20, 60) +``` + +Это должно дать нам прекрасный ромб — поскольку мы используем режим рисования `TRIANGLE_STRIP`, render выполнит следующие шаги: + +![Четыре шага, демонстрирующие размещение вершин на экране для формирования двух треугольников](/assets/develop/rendering/concepts-practical-example-draw-process.png) + +Поскольку в этом примере мы рисуем на HUD, мы будем использовать событие `HudRenderCallback`: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +В результате на HUD отображается следующее: + +![Конечный результат](/assets/develop/rendering/concepts-practical-example-final-result.png) + +:::tip +Попробуйте поиграться с цветами и положением вершин, чтобы посмотреть, что получится! Вы также можете попробовать использовать различные режимы рисования и форматы вершин. +::: + +## `MatrixStack` {#the-matrixstack} + +Узнав, как писать в `BufferBuilder`, вы, возможно, зададитесь вопросом, как преобразовать свою модель или даже анимировать ее. Вот тут-то и появляется класс `MatrixStack`. + +Класс `MatrixStack` имеет следующие методы: + +- `push()` — помещает новую матрицу в стек. +- `pop()` - Pops the top matrix off the stack. +- `pop()` - Извлекает верхнюю матрицу из стека. +- `translate(x, y, z)` — переводит верхнюю матрицу в стеке. +- `scale(x, y, z)` — масштабирует верхнюю матрицу в стеке. + +Вы также можете умножить верхнюю матрицу в стеке, используя кватернионы, о чем мы поговорим в следующем разделе. + +Используя наш пример выше, мы можем масштабировать наш алмаз вверх и вниз, используя `MatrixStack` и `tickDelta`, то есть время, прошедшее с момента последнего кадра. + +::: warning +You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. + +Обязательно выдвиньте стек матриц, прежде чем получить матрицу преобразования! +::: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +![Видео, демонстрирующее увеличение и уменьшение размера алмаза](/assets/develop/rendering/concepts-matrix-stack.webp) + +## Кватернионы (вращающиеся вещи) {#quaternions-rotating-things} + +Кватернионы — это способ представления вращений в трехмерном пространстве. Они используются для поворота верхней матрицы в `MatrixStack` с помощью метода `multiply(Quaternion, x, y, z)`. + +Крайне маловероятно, что вам когда-либо понадобится использовать класс Quaternion напрямую, поскольку Minecraft предоставляет различные готовые экземпляры Quaternion в своем служебном классе `RotationAxis`. + +Допустим, мы хотим повернуть наш алмаз вокруг оси z. Мы можем сделать это с помощью `MatrixStack` и метода `multiply(Quaternion, x, y, z)`. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +Результатом этого является следующее: + +![Видео, демонстрирующее вращение алмаза вокруг оси z](/assets/develop/rendering/concepts-quaternions.webp) diff --git a/versions/1.21/translated/ru_ru/develop/rendering/draw-context.md b/versions/1.21/translated/ru_ru/develop/rendering/draw-context.md new file mode 100644 index 000000000..1e1f8de48 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/rendering/draw-context.md @@ -0,0 +1,94 @@ +--- +title: Использование контекста рисования +description: Узнайте, как использовать класс DrawContext для визуализации различных фигур, текста и текстур. +authors: + - IMB11 +--- + +# Использование контекста рисования {#using-the-drawing-context} + +На этой странице предполагается, что вы ознакомились со страницей [Основные концепции рендеринга](./basic-concepts). + +Класс `DrawContext` является основным классом, используемым для рендеринга в игре. Он используется для рендеринга фигур, текста и текстур, а так же, как было показано ранее, для управления `MatrixStack` и использования `BufferBuilder`. + +## Рисование фигур {#drawing-shapes} + +Класс `DrawContext` можно использовать для простого рисования **квадратных** фигур. Если вы хотите нарисовать треугольники или любую другую неквадратную фигуру, вам понадобится `BufferBuilder`. + +### Рисование прямоугольников {#drawing-rectangles} + +Для рисования закрашенного прямоугольника можно использовать метод `DrawContext.fill(...)`. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Прямоугольник](/assets/develop/rendering/draw-context-rectangle.png) + +### Контуры рисования/границы {#drawing-outlines-borders} + +Допустим, мы хотим обвести только что нарисованный прямоугольник. Мы можем использовать метод `DrawContext.drawBorder(...)`, чтобы нарисовать контур. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Прямоугольник с рамкой](/assets/develop/rendering/draw-context-rectangle-border.png) + +### Рисование отдельных линий {#drawing-individual-lines} + +Для рисования линий мы можем использовать методы `DrawContext.drawHorizontalLine(...)` и `DrawContext.drawVerticalLine(...)`. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Линии](/assets/develop/rendering/draw-context-lines.png) + +## Менеджер ножниц {#the-scissor-manager} + +Класс `DrawContext` имеет встроенный менеджер ножниц. Это позволяет вам легко привязать визуализацию к определенной области. Это полезно для отображения таких вещей, как всплывающие подсказки или другие элементы, которые не должны отображаться за пределами определенной области. + +### Использование менеджера ножниц {#using-the-scissor-manager} + +:::tip +Области ножниц могут быть вложенными! Но убедитесь, что вы отключаете менеджер ножниц столько же раз, сколько и включали его. +::: + +Чтобы включить менеджер ножниц, просто используйте метод `DrawContext.enableScissor(...)`. Аналогично, чтобы отключить менеджер ножниц, используйте метод `DrawContext.disableScissor()`. + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Регион ножниц в действии](/assets/develop/rendering/draw-context-scissor.png) + +Как видите, даже несмотря на то, что мы говорим игре отрисовывать градиент по всему экрану, она отрисовывает его только в области ножниц. + +## Текстуры для рисования {#drawing-textures} + +Не существует единственно «правильного» способа отрисовки текстур на экране, поскольку метод `drawTexture(...)` имеет множество различных перегрузок. В этом разделе будут рассмотрены наиболее распространенные варианты использования. + +### Рисование всей текстуры {#drawing-an-entire-texture} + +Обычно рекомендуется использовать перегрузку, которая задает параметры `textureWidth` и `textureHeight`. Это связано с тем, что класс `DrawContext` примет эти значения, если вы их не предоставите, что иногда может быть неверным. + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Пример рисования всей текстуры](/assets/develop/rendering/draw-context-whole-texture.png) + +### Рисование части текстуры {#drawing-a-portion-of-a-texture} + +Вот тут-то и появляются `u` и `v`. Эти параметры определяют верхний левый угол текстуры для рисования, а параметры `regionWidth` и `regionHeight` определяют размер части текстуры для рисования. + +Давайте возьмем эту текстуру в качестве примера. + +![Текстура книги рецептов](/assets/develop/rendering/draw-context-recipe-book-background.png) + +Если мы хотим нарисовать только область, содержащую увеличительное стекло, мы можем использовать следующие значения `u`, `v`, `regionWidth` и `regionHeight`: + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Текстура области](/assets/develop/rendering/draw-context-region-texture.png) + +## Рисунок текста {#drawing-text} + +Класс `DrawContext` имеет различные интуитивно понятные методы визуализации текста — для краткости они здесь не будут рассматриваться. + +Допустим, мы хотим нарисовать на экране «Hello World». Для этого мы можем использовать метод `DrawContext.drawText(...)`. + +@[code lang=java transcludeWith=:::7](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![Рисование текста](/assets/develop/rendering/draw-context-text.png) diff --git a/versions/1.21/translated/ru_ru/develop/rendering/gui/custom-screens.md b/versions/1.21/translated/ru_ru/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..e19bd6ac4 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/rendering/gui/custom-screens.md @@ -0,0 +1,64 @@ +--- +title: Пользовательские экраны +description: Узнайте, как создавать собственные экраны для вашего мода. +authors: + - IMB11 +--- + +# Пользовательские экраны {#custom-screens} + +:::info +Эта страница относится к обычным экранам, а не к управляемым — эти экраны открываются игроком на клиенте, а не те, которыми управляет сервер. +::: + +Экраны по сути представляют собой графические интерфейсы, с которыми взаимодействует игрок, например, титульный экран, экран паузы и т. д. + +Вы можете создавать собственные экраны для отображения пользовательского контента, пользовательского меню настроек и многого другого. + +## Создание экрана {#creating-a-screen} + +Чтобы создать экран, вам необходимо расширить класс `Screen` и переопределить метод `init` (при желании вы также можете переопределить метод `render`), но обязательно вызовите его super метод, иначе он не отобразит фон, виджеты и т. д. + +Вам следует принять к сведению, что: + +- Виджеты не создаются в конструкторе, поскольку на тот момент экран еще не инициализирован, а некоторые переменные, такие как `width` и `height`, еще недоступны или неточны. +- Метод `init` вызывается при инициализации экрана, и это лучшее место для создания виджетов. + - Виджеты добавляются с помощью метода `addDrawableChild`, который принимает любой отрисовываемый виджет. +- Метод `render` вызывается в каждом кадре — из этого метода можно получить доступ к контексту отрисовки и положению мыши. + +В качестве примера мы можем создать простой экран с кнопкой и меткой над ней. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Пользовательский экран 1](/assets/develop/rendering/gui/custom-1-example.png) + +## Открытие экрана {#opening-the-screen} + +Вы можете открыть экран с помощью метода `setScreen` `MinecraftClient` — это можно сделать из многих мест, например, с помощью привязки клавиш, команды или обработчика пакетов клиента. + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## Закрытие экрана {#closing-the-screen} + +Если вы хотите закрыть экран, просто установите экран в значение `null`: + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +Если вы хотите проявить изюминку и вернуться к предыдущему экрану, вы можете передать текущий экран в конструктор `CustomScreen` и сохранить его в поле, а затем использовать его для возврата к предыдущему экрану при вызове метода `close`. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +Теперь при открытии пользовательского экрана вы можете передать текущий экран в качестве второго аргумента — тогда при вызове `CustomScreen#close` произойдет возврат к предыдущему экрану. + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/translated/ru_ru/develop/rendering/gui/custom-widgets.md b/versions/1.21/translated/ru_ru/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..9c0a69440 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,39 @@ +--- +title: Пользовательские виджеты +description: Узнайте, как создавать пользовательские виджеты для ваших экранов. +authors: + - IMB11 +--- + +# Пользовательские виджеты {#custom-widgets} + +Виджеты — это контейнеризированные компоненты рендеринга, которые можно добавить на экран, где игрок взаимодействует через различные события, например щелчки мыши или нажатия клавиш. + +## Создание виджета {#creating-a-widget} + +Существует несколько способов создания класса виджета, например, путем расширения `ClickableWidget`. Этот класс предоставляет множество полезных утилит, таких как управление шириной, высотой, положением и обработка событий. Он реализует интерфейсы `Drawable`, `Element`, `Narratable` и `Selectable`: + +- `Drawable` — для рендеринга — требуется для регистрации виджета на экране с помощью метода `addDrawableChild`. +- `Элемент` — для событий — требуется, если вы хотите обрабатывать такие события, как щелчки мыши, нажатия клавиш и т. д. +- `Narratable` — для доступности — требуется, чтобы сделать ваш виджет доступным для программ чтения с экрана и других инструментов обеспечения доступности. +- `Selectable` — для выбора — требуется, если вы хотите сделать виджет доступным для выбора с помощью клавиши Tab - это также способствует повышению доступности. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## Добавление виджета на экран {#adding-the-widget-to-the-screen} + +Как и все виджеты, его необходимо добавить на экран с помощью метода `addDrawableChild`, который предоставляется классом `Screen`. Обязательно сделайте это в методе `init`. + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![Пользовательский виджет на экране](/assets/develop/rendering/gui/custom-widget-example.png) + +## События виджета {#widget-events} + +Вы можете обрабатывать такие события, как щелчки мыши и нажатия клавиш, переопределяя методы `onMouseClicked`, `onMouseReleased`, `onKeyPressed` и другие. + +Например, вы можете заставить виджет менять цвет при наведении на него курсора, используя метод `isHovered()`, предоставляемый классом `ClickableWidget`: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![Пример события наведения](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/translated/ru_ru/develop/rendering/hud.md b/versions/1.21/translated/ru_ru/develop/rendering/hud.md new file mode 100644 index 000000000..7073c83ab --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/rendering/hud.md @@ -0,0 +1,30 @@ +--- +title: Рендеринг в HUD +description: Узнайте, как использовать событие HudRenderCallback для рендеринга в HUD. +authors: + - IMB11 +--- + +# Рендеринг в HUD {#rendering-in-the-hud} + +Мы уже кратко затронули тему рендеринга объектов в HUD на странице [Основные концепции рендеринга](./basic-concepts) и [Использование контекста рисования](./draw-context), поэтому на этой странице мы остановимся на событии `HudRenderCallback` и параметре `deltaTick`. + +## HudRenderCallback {#hudrendercallback} + +Событие `HudRenderCallback`, предоставляемое Fabric API, вызывается в каждом кадре и используется для рендеринга объектов в HUD. + +Чтобы зарегистрироваться на это событие, вы можете просто вызвать `HudRenderCallback.EVENT.register` и передать lambda, которое принимает `DrawContext` и `float` (deltaTick) в качестве параметров. + +Контекст отрисовки можно использовать для доступа к различным утилитам рендеринга, предоставляемым игрой, а также для доступа к стеку необработанных матриц. + +Вам следует посетить страницу [Контекст рисования](./draw-context), чтобы узнать больше о контексте рисования. + +### DeltaTick {#deltatick} + +`deltaTick` относится ко времени с момента последнего кадра в секундах. Это можно использовать для создания анимации и других временных эффектов. + +Например, предположим, что вы хотите изменять цвет с течением времени. Вы можете использовать `deltaTickManager`, чтобы получить deltaTick, и сохранять его с течением времени для преобразования цвета: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java) + +![Изменение цвета с течением времени](/assets/develop/rendering/hud-rendering-deltatick.webp) diff --git a/versions/1.21/translated/ru_ru/develop/rendering/particles/creating-particles.md b/versions/1.21/translated/ru_ru/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..1b6115ce4 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/rendering/particles/creating-particles.md @@ -0,0 +1,72 @@ +--- +title: Создание пользовательских частиц +description: Узнайте, как создать пользовательскую частицу с помощью Fabric API. +authors: + - Superkat32 +--- + +# Создание пользовательских частиц {#creating-custom-particles} + +Частицы — мощный инструмент. Они могут добавить атомосферность красивой сцене или добавить напряжения в битву с боссом. Давайте добавим еще один! + +## Регистрация пользовательской частицы {#register-a-custom-particle} + +Мы добавим новую блестящую частицу, которая будет имитировать движение конечной стержневой частицы. + +Сначала нам нужно зарегистрировать `ParticleType` в классе инициализатора вашего мода, используя идентификатор вашего мода. + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +«sparkle_particle» строчными буквами — это путь JSON к текстуре частицы. Позже вы создадите новый JSON-файл с таким же именем. + +## Регистрация на стороне клиента {#client-side-registration} + +После регистрации частицы в точке входа `ModInitializer` вам также необходимо зарегистрировать частицу в точке входа `ClientModInitializer`. + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +В этом примере мы регистрируем нашу частицу на стороне клиента. Затем мы придаем частице некоторое движение, используя фабрику частиц конечного стержня. Это означает, что наша частица будет двигаться точно так же, как частица конечного стержня. + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- Горячая клавиша IntelliJ: Ctrl+Alt+B +- Горячая клавиша Visual Studio Code: Ctrl+F12 + ::: + +## Создание JSON-файла и добавление текстур {#creating-a-json-file-and-adding-textures} + +Вам нужно будет создать 2 папки в папке `resources/assets//`. + +| Путь к папке | Обьяснение | +| -------------------- | --------------------------------------------------------------------------------------- | +| `/textures/particle` | Папка `particle` будет содержать все текстуры для всех ваших частиц. | +| `/particles` | Папка `particles` будет содержать все json-файлы для всех ваших частиц. | + +В этом примере у нас будет только одна текстура в `textures/particle` с названием "sparkle_particle_texture.png". + +Затем создайте новый JSON-файл в `particles` с тем же именем, что и путь JSON, который вы использовали при регистрации ParticleType. Для этого примера нам потребуется создать `sparkle_particle.json`. Этот файл важен, поскольку он сообщает Minecraft, какие текстуры должна использовать наша частица. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +:::tip +Вы можете добавить больше текстур в массив `textures`, чтобы создать анимацию частиц. Частица будет циклически проходить по текстурам в массиве, начиная с первой текстуры. +::: + +## Тестирование новой частицы {#testing-the-new-particle} + +После того как вы завершите работу над файлом JSON и сохраните ее, вы можете загрузить Minecraft и все протестировать! + +Проверить, все ли работает, можно, введя следующую команду: + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![Демонстрация частицы](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +:::info +При выполнении этой команды частица появится внутри игрока. Чтобы увидеть его, вам, скорее всего, придется идти задом наперед. +::: + +В качестве альтернативы вы также можете использовать командный блок, чтобы вызвать частицу с помощью той же команды. diff --git a/versions/1.21/translated/ru_ru/develop/sounds/custom.md b/versions/1.21/translated/ru_ru/develop/sounds/custom.md new file mode 100644 index 000000000..aef1f0b1b --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/sounds/custom.md @@ -0,0 +1,63 @@ +--- +title: Создание своих звуков +description: Вы научите добавлять и использовать новые звуки с реестром. +authors: + - JR1811 +--- + +# Создание своих звуков {#creating-custom-sounds} + +## Подготовка аудиофайла {#preparing-the-audio-file} + +Нужно отформатировать ваш аудиофайл определённым образом. OGG Vorbis - это открытый формат для мультимедийных данных, например аудио, и используется в качестве звуковых файлов Minecraft. Чтобы избежать проблем с тем, как Minecraft обрабатывает дистанцию, вашему аудио нужно иметь только один канал (Mono). + +Многие современные программы ЦЗРС (Цифровая звуковая рабочая станция) могут импортировать и экспортировать файлы этого формата. В следующем примере для приведения файла в правильный формат будет использован "[Audacity](https://www.audacityteam.org/)", или любая другая ЦЗРС программа. + +![Неподготовленный файл в Audacity](/assets/develop/sounds/custom_sounds_0.png) + +В этом примере звук [свисток](https://freesound.org/people/strongbot/sounds/568995/) был импортирован в Audacity. Обычно он сохраняется как файл `.wav` и имеет два аудио канала (Stereo). Отредактируйте звук по своему вкусу и удалите один из каналов, используя раскрывающийся элемент наверху "track head". + +![Разделение Стерео трека](/assets/develop/sounds/custom_sounds_1.png) + +![Удаление одного из каналов](/assets/develop/sounds/custom_sounds_2.png) + +Когда вы экспортируете или рендерите аудиофайл, выберите формат файла OGG. Некоторые ЦЗРС, например REAPER, могут поддерживать несколько форматов слоёв OGG. В этом случае OGG Vorbis должен работать нормально. + +![Экспорт как OGG файл](/assets/develop/sounds/custom_sounds_3.png) + +Также имейте в виду, что аудиофайлы могут значительно увеличить размер вашего мода. При необходимости сожмите звук, когда редактируйте и экспортируйте файл, чтобы свести размер файла к минимуму. + +## Загрузка аудиофайла {#loading-the-audio-file} + +Добавьте новую директорию `resources/assets//sounds` для звуков в вашем моду, и положите в неё экспортированный аудиофайл `metal_whistle.ogg`. + +Дальше создайте файл `resources/assets//sounds.json`, если он не существует и добавьте ваш звук в звуковые записи. + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json) + +Запись подписи предоставляет больше контекста для игрока. Название подписи используется в языковых файлах в директории `resources/assets//lang` и будет показываться, если включена настройка и звук воспроизводиться. + +## Регистрация своего звука {#registering-the-custom-sound} + +Чтобы добавить собственный звук в мод, зарегистрируете в классе SoundEvent, который имплементирует точку входа `ModInitializer`. + +```java +Registry.register(Registries.SOUND_EVENT, Identifier.of(MOD_ID, "metal_whistle"), + SoundEvent.of(Identifier.of(MOD_ID, "metal_whistle"))); +``` + +## Чистка беспорядка {#cleaning-up-the-mess} + +В зависимости насколько много записей реестра находится, это может превратиться в беспорядок. Чтобы обойти это, мы должны сделать использование нового класса помощника. + +Добавьте два новых метода для ранее созданного класса помощника. Первый регистрирует все звуки и используется для инициализации этого класса на первом месте. После этого вы можете добавить в новый статический класс `SoundEvent` нужные переменные. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java) + +`ModInitializer` имплементируют точки входа которые нужны классу, чтобы имплементировать весь реестр с собственными SoundEvents. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java) + +## Используйте собственные SoundEvent'ы {#using-the-custom-soundevent} + +Используйте класс помощник для доступа к собственному SoundEvent. Просмотрите страницу [Воспроизводящиеся SoundEvent'ы](./using-sounds), чтобы научиться как воспроизводить звуки. diff --git a/versions/1.21/translated/ru_ru/develop/sounds/using-sounds.md b/versions/1.21/translated/ru_ru/develop/sounds/using-sounds.md new file mode 100644 index 000000000..f04a50b5c --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/sounds/using-sounds.md @@ -0,0 +1,34 @@ +--- +title: Воспроизведение SoundEvents +description: Научитесь воспроизводить звуковые события. +authors: + - JR1811 +--- + +# Воспроизведение SoundEvents {#playing-sounds} + +Minecraft имеет большой выбор звуков которые вы можете воспроизвести. Просмотрите класс `SoundEvents`, чтобы увидеть все ванильные звуки события, предоставленные Mojang. + +## Воспроизведение звуков в вашем моде {#using-sounds} + +Обязательно вызовите метод `playSound()` на логической стороне сервера когда воспроизводятся звуки! + +Например, методы `useOnEntity()` и `useOnBlock()` для собственного интерактивного предмета используются для воспроизведения "поставлен медный блок" и звук мародёра. + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java) + +Метод`playSound()` используется вместе с объектом `LivingEntity`. Необходимо указать только SoundEvent, громкость и высоту тона. Вы также можете использовать метод `playSound()` из экземпляра мира, чтобы получить более высокий уровень контроля. + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CustomSoundItem.java) + +### SoundEvent и SoundCategory {#soundevent-and-soundcategory} + +SoundEvent определяет, какой звук будет воспроизводиться. Вы также можете [зарегистрировать собственные SoundEvents](./custom), чтобы включить собственный звук. + +В настройках Minecraft есть несколько ползунков звука. Перечисление `SoundCategory` используется для определения того, какой ползунок будет регулировать громкость звука. + +### Громкость и высота {#volume-and-pitch} + +Параметр громкости может немного вводить в заблуждение. В диапазоне «0,0f - 1,0f» можно изменять фактическую громкость звука. Если число превысит это значение, будет использоваться громкость `1.0f`, и будет регулироваться только расстояние, на котором слышен ваш звук. Расстояние между блоками можно приблизительно рассчитать по формуле «звук \* 16». + +Параметр высоты тона увеличивает или уменьшает значение высоты тона, а также изменяет длительность звука. В диапазоне «(0,5f - 1,0f)» высота тона и скорость уменьшаются, тогда как большие числа увеличивают высоту тона и скорость. Числа ниже «0,5f» сохранят значение высоты тона «0,5f». diff --git a/versions/1.21/translated/ru_ru/develop/text-and-translations.md b/versions/1.21/translated/ru_ru/develop/text-and-translations.md new file mode 100644 index 000000000..44ccaa236 --- /dev/null +++ b/versions/1.21/translated/ru_ru/develop/text-and-translations.md @@ -0,0 +1,106 @@ +--- +title: Текст и переводы +description: Подробная документация по работе Minecraft с форматированным текстом и переводами. +authors: + - IMB11 +--- + +# Текст и переводы {#text-and-translations} + +Всякий раз, когда Minecraft отображает текст в игре, он, в большинстве случаев, определяется с помощью объекта "Text". +Этот пользовательский тип используется вместо `String` для обеспечения более сложного форматирования, +включая цвета, выделение жирным шрифтом, обфускации и событий нажатия (click). Они также обеспечивают легкий доступ +к системе перевода, упрощая локализацию любых элементов интерфейса на +разные языки. + +Если вы раньше работали с пакетами данных (датапаками) или функциями, вы можете увидеть параллели с +текстовым форматом json, используемым для отображения названий, книг, табличек и другого. Как вы, возможно, догадываетесь, это на самом деле json-представление объекта `Text`, и его можно +преобразовать в `Text.Serializer` и обратно с помощью Text.Serializer\`. + +При создании мода, предпочтительнее создавать свои `Text` объекты непосредственно в коде, используя перевод, когда это возможно. + +## Текстовые литералы {#text-literals} + +Самый простой способ создать объект `Text` это использовать литерал. По сути это строка которая будет отображена как есть, без форматирования по умолчанию. + +Они создаются с помощью методов `Text.of` и `Text.literal`, которые действуют немного по-разному. `Text.of` принимает значения `null` в себя и возвращает экземпляр класса `Text`. `Text.literal` же наоборот не сможет принять значение null, и вернёт`MutableText` являющийся наследуемым классом от `Text`, который можно легко стилизовать и конкатенировать. Подробнее об этом будет сказано позже. + +```java +Text literal = Text.of("Hello, world!"); +MutableText mutable = Text.literal("Hello, world!"); +// Keep in mind that a MutableText can be used as a Text, making this valid: +Text mutableAsText = mutable; +``` + +## Переводимый Текст {#translatable-text} + +Когда вы хотите предоставить несколько переводов для одной и той же строчки текста, вы можете использовать метод `Text.translatable` для ссылки на ключ перевода в любом языковом файле. Если ключ не существует, ключ перевода конвертируется в литерал. + +```java +Text translatable = Text.translatable("my_mod.text.hello"); + +// Similarly to literals, translatable text can be easily made mutable. +MutableText mutable = Text.translatable("my_mod.text.bye"); +``` + +Файл языка, `en_us.json`, выглядит как то так: + +```json +{ + "my_mod.text.hello": "Hello!", + "my_mod.text.bye": "Goodbye :(" +} +``` + +## Сериализация Текста {#serializing-text} + + + +Как было упомянуто выше, вы можете сериализовать текст в JSON используя текстовый кодек. Для большей информации об кодеках, посмотрите страницу [Codec](./codecs). + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +В результате получается JSON, который можно использовать в датапаках, командах и других местах которые принимают JSON формат текста вместо буквального или переводимого текста. + +## Десериализация Текста {#deserializing-text} + +Кроме того, чтобы десериализовать текстовый объект в реальный класс `Text`, опять же, используйте кодек. + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +## Форматирование Текста {#formatting-text} + +Вы можете быть знакомы со стандартом форматирования в Minecraft: + +Вы можете применить эти форматирования с помощью перечисления `Formatting` в классе `MutableText`: + +```java +MutableText result = Text.literal("Hello World!") + .formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE); +``` + + + + + + + + + + + + + + + + + + + + + + + + + +
ЦветНазваниеКод в чатеКод для MOTDHEX-код
Чёрный (black)§0\u00A70#000000
Тёмно-синий (dark_blue)§1\u00A71#0000AA
Тёмно-зелёный (dark_green)§2\u00A72#00AA00
Тёмно-голубой (dark_aqua)§3\u00A73#00AAAA
Тёмно-красный (dark_red)§4\u00A74#AA0000
Тёмно-фиолетовый (dark_purple)§5\u00A75#AA00AA
Золотой (gold)§6\u00A76#FFAA00
Серый (gray)§7\u00A77#AAAAAA
Тёмно-серый (dark_gray)§8\u00A78#555555
Синий (blue)§9\u00A79#5555FF
Зелёный (green)§a\u00A7a#55FF55
Голубой (aqua)§b\u00A7b#55FFFF
Красный (red)§c\u00A7c#FF5555
Фиолетовый (light_purple)§d\u00A7d#FF55FF
Жёлтый (yellow)§e\u00A7e#FFFF55
Белый (white)§f\u00A7f#FFFFFF
Сброс форматирования§r
Жирный§l
Зачёркнутый§m
Подчёркнутый§n
Курсив§o
Зашифрованный§k
diff --git a/versions/1.21/translated/ru_ru/index.md b/versions/1.21/translated/ru_ru/index.md new file mode 100644 index 000000000..be8c72f4a --- /dev/null +++ b/versions/1.21/translated/ru_ru/index.md @@ -0,0 +1,21 @@ +--- +title: Документация Fabric +description: Официальная курируемая документация по Fabric, инструментарию для разработки модов для Minecraft. +layout: home +hero: + name: Документация Fabric + tagline: Официальная курируемая документация по Fabric, инструментарию для разработки модов для Minecraft. +features: + - title: Руководства для игроков + icon: 📚 + details: Вы игрок, желающий играть с модами, работающими на Fabric? Наши руководства для игроков освещают все необходимые темы. Эти руководства расскажут, как скачать, установить и устранять неполадки с модами для Fabric. + link: /ru_ru/players/ + linkText: Подробнее + - title: Руководства для разработчиков + icon: 🛠️ + details: "Наш подбор руководств для разработчиков, написанных сообществом, охватывает широкий спектр тем: от настройки среды разработки до более продвинутых тем, таких как отрисовка и сетевое взаимодействие." + link: /ru_ru/develop/ + linkText: Приступить к прочтению +--- + +Если вы хотите внести свой вклад в документацию Fabric, вы можете найти её исходный код на [GitHub](https://github.com/FabricMC/fabric-docs) и ознакомиться с соответствующим [руководством по внесению вклада](./contributing). diff --git a/versions/1.21/translated/ru_ru/players/faq.md b/versions/1.21/translated/ru_ru/players/faq.md new file mode 100644 index 000000000..536d2c81b --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Часто задаваемые вопросы для игроков +description: Ответы на часто задаваемые вопросы касательно Fabric, поступающие от игроков и администраторов серверов. +--- + +# Часто задаваемые вопросы {#faq} + +Есть множество вопросов, которые часто задают, поэтому мы составили их список здесь. + +## Какие версии Minecraft поддерживает Fabric? {#what-minecraft-versions-does-fabric-support} + +Официально Fabric поддерживает все версии Minecraft, начиная со снапшотов `18w43b` и выше, а также релизные версии `1.14` и выше. + +## Где я могу скачать опубликованные моды для Fabric? {#where-can-i-download-published-fabric-mods} + +:::info +Всегда убеждайтесь в том, что моды загружены из надёжного источника. Ознакомьтесь с руководством по [поиску надёжных модов](./finding-mods) для получения дополнительной информации. +::: + +Большинство авторов публикуют свои моды на [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) и [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4), однако некоторые могут размещать их на своих личных сайтах или на других платформах, таких как репозитории GitHub. + +## Где я могу найти готовые сборки модов для Fabric? {#where-can-i-find-premade-fabric-modpacks} + +Вы можете найти готовые сборки модов для Fabric на различных платформах, таких как: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/ru_ru/players/finding-mods.md b/versions/1.21/translated/ru_ru/players/finding-mods.md new file mode 100644 index 000000000..b0e8ed5e5 --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Поиск безопасных модификаций +description: Гайд о том, как найти моды для Fabric, используя надежные источники. +authors: + - IMB11 +--- + +# Поиск безопасных модов {#finding-mods} + +Во-первых, доверие субъективно, и вы всегда должны руководствоваться своим собственным мнением при загрузке модов. Тем не менее есть некоторые вещи, которые вы можете сделать, чтобы найти заслуживающие доверия моды. + +## 1. Используйте безопасные источники {#trustworthy-source} + +Большинство авторов публикуют свои моды на [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) и [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\\&gameVersionTypeId=4). + +Эти сайты проверяют, являются ли моды тем, за что они себя выдают, и что они не содержат вредоносного кода. Вы также можете сообщить о вредоносных модах на этих сайтах, и они примут меры относительно быстро. + +## 2. Посоветуйтесь с другими! {#with-others} + +Если вы загружаете мод из источника, который не безопасен, вам следует посоветоваться с другими людьми, чтобы узнать, загружали ли они мод ранее из того места, откуда загружаете вы, и не возникали ли у них какие-либо проблемы с ним. + +Если у вас есть вопросы, вы можете задать их [в дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#player-support`. + +## 3. Избегайте вредоносных сайтов! {#avoid-malware} + +:::info +Вредоносные сайты могут быть очевидны не для всех. Если вы не уверены, вам следует спросить мнения других или вообще избегать других сайтов и полагаться только на надежные источники, такие как Modrinth и CurseForge. +::: + +Есть много сайтов, которые утверждают, что у них есть моды для Minecraft, но на самом деле это просто вредоносные сайты. Вам следует избегать этих сайтов любой ценой. + +Вы можете использовать антивирусы и сайты, такие как [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) или [VirusTotal](https://www.virustotal.com/) для проверки загруженных модов. Однако не стоит полностью полагаться на эти методы, поскольку иногда они могут быть некорректными. + +Опять же, если у вас есть сомнения, вы можете спросить мнения людей [в дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#player-support`. diff --git a/versions/1.21/translated/ru_ru/players/index.md b/versions/1.21/translated/ru_ru/players/index.md new file mode 100644 index 000000000..e1fb02e7c --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/index.md @@ -0,0 +1,12 @@ +--- +title: Руководства для игроков +description: Собрание руководств для игроков и администраторов серверов по установке и использованию Fabric. +--- + +# Руководства для игроков {#player-guides} + +Этот раздел документации Fabric предназначен для игроков и администраторов серверов, желающих узнать, как устанавливать, использовать и устранять неполадки с Fabric. + +Список всех доступных руководств есть на боковой панели. + +Если у вас возникнут какие-либо проблемы, пожалуйста, сообщите о них на GitHub или попросите помощи на [сервере Fabric в Discord](https://discord.gg/v6v4pMv) на каналах `#player-support` или `#server-admin-support` (на английском языке). diff --git a/versions/1.21/translated/ru_ru/players/installing-fabric.md b/versions/1.21/translated/ru_ru/players/installing-fabric.md new file mode 100644 index 000000000..123c40a5e --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/installing-fabric.md @@ -0,0 +1,55 @@ +--- +title: Установка Fabric +description: Пошаговая инструкция по установке Fabric. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Установка Fabric {#installing-fabric} + +В этом гайде мы расскажем вам об установке Fabric на официальный лаунчер Minecraft. + +Для сторонних лаунчеров вам следует ознакомиться с их документацией. + +## 1. Загрузка установщика Fabric {#1-download-the-fabric-installer} + +Вы можете загрузить установщик Fabric с [сайта Fabric](https://fabricmc.net/use/). + +Если вы используете Windows, скачайте версию `.exe` (`Download For Windows`), потому что для неё не требуется Java в вашей системе. Вместо этого он использует версию Java из официального лаунчера. + +Для macOS и Linux вам потребуется установить версию `.jar`. Иногда вам необходимо установить Java перед выполнением этого шага. + +## 2. Запуск установщика Fabric {#2-run-the-fabric-installer} + +:::warning +Перед установкой закройте Minecraft и лаунчер. +::: + +:::details Информация для пользователей macOS + +На macOS вам может потребоваться щелкнуть правой кнопкой мыши на файл `.jar` и нажать `Открыть`, чтобы запустить его. + +![Контекстное меню установщика Fabric на MacOS](/assets/players/installing-fabric/macos-downloads.png) + +Когда вас спросят: "Вы уверены, что хотите это открыть?", нажмите `Открыть` ещё раз. +::: + +Как только вы откроете установщик, вы должны увидеть экран, похожий на этот: + +![Установщик Fabric с подсвеченным "Install"](/assets/players/installing-fabric/installer-screen.png) + +Чтобы установить Fabric, просто выберите свою версию игры из списка и нажмите `Установить`. + +**Убедитесь, что установлен флажок 'Создать профиль'.** + +## 3. Готово! {#3-you-re-done} + +Как только установка завершится, вы можете открыть лаунчер Minecraft, выбрать профиль Fabric из списка в левом нижнем углу и нажать Играть! + +![Лаунчер Minecraft с выбранным профилем Fabric](/assets/players/installing-fabric/launcher-screen.png) + +Теперь, когда вы установили Fabric, вы можете добавлять моды в свою игру! Смотрите гайд [Поиск безопасных модов](./finding-mods) для большей информации. + +Если вы столкнулись с какими-либо проблемами, попросите помощи в [дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#player-support`. diff --git a/versions/1.21/translated/ru_ru/players/installing-java/linux.md b/versions/1.21/translated/ru_ru/players/installing-java/linux.md new file mode 100644 index 000000000..81f851a15 --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Установка Java на Linux +description: Пошаговая инструкция по установке Java на Linux. +authors: + - IMB11 +--- + +# Установка Java на Linux {#installing-java-on-linux} + +Это руководство поможет вам установить Java 21 на Linux. + +## 1. Проверьте, не установлена ли Java {#1-check-if-java-is-already-installed} + +Откройте терминал, впишите `java -version` и нажмите Enter. + +![Терминал с введённой командой "java -version"](/assets/players/installing-java/linux-java-version.png) + +:::warning +Для использования Minecraft 1.21 вам потребуется установить как минимум Java 21. Если эта команда отображает версию ниже 21, вам необходимо обновить существующую установку Java. +::: + +## 2. Загрузка и установка Java 21 {#2-downloading-and-installing-java} + +Мы рекомендуем использовать OpenJDK 21, который доступен для большинства дистрибутивов Linux. + +### Arch Linux {#arch-linux} + +:::info +Для дополнительной информации об установке Java в Arch Linux смотрите [википедию Arch Linux](https://wiki.archlinux.org/title/Java_\\\(Русский\\\)). +::: + +Вы можете установить последнюю версию JRE из официальных репозиториев: + +```sh +sudo pacman -S jre-openjdk +``` + +Если вы используете сервер без необходимости в графическом интерфейсе, вы можете вместо этого установить `headless` версию: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +Если вы планируете разрабатывать моды, вместо этого вам понадобится JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu {#debian-ubuntu} + +Вы можете установить Java 21 с помощью `apt`, выполнив следующие команды: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora {#fedora} + +Вы можете установить Java 21 с помощью `dnf`, выполнив следующие команды: + +```sh +sudo dnf install java-21-openjdk +``` + +Если вам не нужен графический интерфейс, вы можете вместо этого установить `headless` версию: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +Если вы планируете разрабатывать моды, вместо этого вам понадобится JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Другие дистрибутивы Linux {#other-linux-distributions} + +Если вашего дистрибутива нет в списке выше, вы можете загрузить последнюю версию JRE с [Adoptium](https://adoptium.net/temurin/) + +Вам следует обратиться к альтернативному гайду для вашего дистрибутива, если вы планируете разрабатывать моды. + +## 3. Проверьте, установлена ​​ли Java 21 {#3-verify-that-java-is-installed} + +После завершения установки вы можете проверить, установлена ​​ли Java 21, открыв терминал и введя `java -version`. + +Если команда будет выполнена успешно, вы увидите что-то вроде показанного ранее, где отображается версия Java: + +![Терминал с введённой командой "java -version"](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/ru_ru/players/installing-java/windows.md b/versions/1.21/translated/ru_ru/players/installing-java/windows.md new file mode 100644 index 000000000..0bb4f9a8c --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Установка Java на Windows +description: Пошаговая инструкция по установке Java на Windows. +authors: + - IMB11 +--- + +# Установка Java на Windows {#installing-java-on-windows} + +Это руководство поможет вам установить Java 21 на Windows. + +Это руководство понадобится вам, если вы хотите использовать установщик на основе `.jar` Fabric'а, или если вы используете `.jar` сервера Minecraft. + +## 1. Проверьте наличие уже установленной Java {#1-check-if-java-is-already-installed} + +Чтобы проверить, что Java уже установлена, вам нужно сначала открыть командную строку. + +Вы можете сделать это, нажав Win + R и написав `cmd.exe` в появившемся окне. + +![Окно "Выполнить" с введённым "cmd.exe"](/assets/players/installing-java/windows-run-dialog.png) + +После того как вы открыли командную строку, впишите `java -version` и нажмите Enter. + +Если команда выполнена успешно, вы увидите что-то вроде этого. Если выдало ошибку, то переходите к следующему шагу. + +![Командная строка с введённой командой "java -version"](/assets/players/installing-java/windows-java-version.png) + +:::warning +Чтобы использовать Minecraft 1.21, вам необходимо установить Java 21 и выше. Если эта команда отображает любую версию ниже 21, вам придётся обновить Java. +::: + +## 2. Загрузите установщик Java 21 {#2-download-the-java-installer} + +Чтобы установить Java 21, вам необходимо загрузить загрузчик из [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21). + +Вам нужно скачать версию `Windows Installer (.msi)`: + +![Adoptium c выделенным Windows Installer (.msi)](/assets/players/installing-java/windows-download-java.png) + +Вам нужно выбрать `x86`, если у вас 32-битная система, или `x64`, если у вас 64-битная операционная система. + +Большинство современных компьютеров имеют 64-битную операционную систему. Если вы не уверены, используйте 64-битный установщик. + +## 3. Запустите установщик! {#3-run-the-installer} + +Следуйте указаниям программы установки, чтобы установить Java 21. Когда вы доходите до этой страницы, вы должны выбрать "Entire feature will be installed on local hard drive" для следующих функций: + +- `Set JAVA_HOME environment variable` - будет добавлено в PATH. +- `JavaSoft (Oracle) registry keys` + +![Установщик Java 21 c выделенными "Set JAVA\_HOME variable" и "JavaSoft (Oracle) registry keys"](/assets/players/installing-java/windows-wizard-screenshot.png) + +После этого нажмите на `Next` и продолжите установку. + +## 4. Убедитесь, что Java 21 установлена {#4-verify-that-java-is-installed} + +После завершения установки, вы можете проверить что Java 21 установлена открытием командного запроса заново и ввести `java -version`. + +Если команда будет выполнена успешно, вы увидите что-то вроде показанного ранее, где отображается версия Java: + +![Командная строка с введённой командой "java -version"](/assets/players/installing-java/windows-java-version.png) + +--- + +Если вы столкнулись с какими-либо проблемами, попросите помощи в [дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#player-support`. diff --git a/versions/1.21/translated/ru_ru/players/installing-mods.md b/versions/1.21/translated/ru_ru/players/installing-mods.md new file mode 100644 index 000000000..d9ebf67de --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Установка модов +description: Пошаговая инструкция по установке модов для Fabric. +authors: + - IMB11 +--- + +# Установка модов {#installing-mods} + +В этом гайде мы расскажем вам об установке модов для Fabric на официальный лаунчер Minecraft. + +Для сторонних лаунчеров вам следует ознакомиться с их документацией. + +## 1. Загрузка модов {#1-download-the-mod} + +:::warning +Вы должны загружать моды только из источников, которым вы доверяете. Смотрите гайд [Поиск безопасных модов](./finding-mods) для большей информации. +::: + +Для большинства модов также требуется Fabric API, который можно загрузить с [Modrinth](https://modrinth.com/mod/fabric-api) или [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +При загрузке модов убедитесь, что: + +- Они работают с той версией Minecraft, на которой вы хотите играть. Например, мод, работающий на версии 1.20, может не работать на версии 1.20.2. +- Они предназначены для Fabric, а не для другого загрузчика модов. +- Кроме того, они предназначены для правильной версии Minecraft (Java Edition). + +## 2. Перемещение мода в папку `mods` {#2-move-the-mod-to-the-mods-folder} + +Папку mods можно найти в следующих местах для каждой операционной системы. + +Обычно вы можете вставить эти пути в адресную строку проводника, чтобы быстро перейти к нужной папке. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Как только вы найдете папку `mods`, вы можете переместить в нее `.jar` файл мода. + +![Установленный мод в папке модов](/assets/players/installing-mods.png) + +## 3. Готово! {#3-you-re-done} + +Как только вы переместите мод в папку `mods`, вы можете открыть лаунчер Minecraft, выбрать профиль Fabric из списка в левом нижнем углу и нажать Играть! + +![Лаунчер Minecraft с выбранным профилем Fabric](/assets/players/installing-fabric/launcher-screen.png) + +## Поиск неисправностей {#troubleshooting} + +Если вы столкнулись с какими-либо проблемами, попросите помощи в [дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#player-support`. + +Вы также можете попытаться устранить проблему самостоятельно, ознакомившись со страницами, посвященными устранению неполадок: + +- [Краш-репорты](./troubleshooting/crash-reports) +- [Загрузка логов](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/ru_ru/players/troubleshooting/crash-reports.md b/versions/1.21/translated/ru_ru/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..1e35ee60b --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: Отчёты о сбоях +description: Узнайте, что можно делать с отчётами о сбоях и как их читать. +authors: + - IMB11 +--- + +# Отчёты о сбоях {#crash-reports} + +:::tip +Если у вас возникли какие-либо трудности с поиском причины краша, вы можете обратиться за помощью в [дискорд Fabric](https://discord.gg/v6v4pMv) в каналах `#player-support` или `#server-admin-support`. +::: + +Краш-репорты являются очень важной частью устранения проблем с вашей игрой или сервером. Они содержат много информации о краше и могут помочь вам найти причину краша. + +## Нахождение краш-репортов {#finding-crash-reports} + +Краш-репорты находятся в папке `crash-reports` в папке вашей игры. Если у вас сервер, то они хранятся в папке `crash-reports` в папке сервера. + +Для сторонних лаунчеров вам следует посмотреть в их документацию, чтобы найти краш-репорты. + +Краш-репорты можно найти по этим путям: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Чтение краш-репортов {#reading-crash-reports} + +Краш-репорты очень большие, их чтение может быть непонятным. Однако они содержат много информации о краше и могут помочь вам найти причину краша. + +Для этого гайда, мы используем [этот краш-репорт в качестве примера](/assets/players/crash-report-example.txt). + +:::details Показ краш-репорта + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Секция краш-репортов {#crash-report-sections} + +Краш-репорты состоят из нескольких разделов, разделённых заголовками: + +- `---- Minecraft Crash Report ----`, краткое описание краша. Этот раздел содержит основную ошибку, вызвавшую краш, время возникновения и трассировку стека. Это главный раздел краш-репорта, так как трассировка стека обычно содержит мод, который вызывает краш. +- `-- Last Reload --`, этот раздел на самом деле бесполезен, если только краш не произошёл во время перезагрузки ресурсов (F3+T). Этот раздел содержит время последней перезагрузки и трассировки стеков любых ошибок, возникших в процессе перезагрузки. Эти ошибки обычно происходят из-за ресурс-паков, и их можно игнорировать, если только они не вызывают проблем с игрой. +- `-- System Details --`, этот раздел содержит информацию о вашем компьютере, такую как операционная система, версия Java и объем памяти, выделенный для игры. Этот раздел полезен для определения того, используете ли вы правильную версию Java и выделили ли вы игре достаточно памяти. + - В этом разделе Fabric добавит строку `Fabric Mods:` со списком всех установленных модов. Этот раздел полезен для определения конфликтов между модами. + +### Подробный отчёт краш-репорте {#breaking-down-the-crash-report} + +Теперь, когда мы знаем, что представляет собой каждый раздел, мы можем начать разбирать краш-репорт и находить причину краша. + +Используя файл выше, мы можем проанализировать краш-репорт и найти причину краша, включая моды, которые вызвали сбой. + +Трассировка стека в разделе `---- Minecraft Crash Report ----` является наиболее важной в данном случае, поскольку она содержит основную ошибку, вызвавшую краш. + +:::details Показать ошибку + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +Учитывая количество модов, упомянутых в стеке, может быть трудно указать на конкретную причину, но первое, что нужно сделать, это найти мод, который вызвал сбой. + +В данном случае мод, вызвавший сбой, называется `snownee`, поскольку это первый мод, упомянутый в трассировке стека. + +Однако, учитывая количество упомянутых модов, это может означать, что между модами проблемы с совместимостью, и мод, вызвавший краш, может быть не тем модом, который виноват. В этом случае лучше всего сообщить о краше автору мода и позволить ему изучить краш. + +## Краш миксинов {#mixin-crashes} + +:::info +Миксины - это способ для модов модифицировать игру без необходимости изменять исходный код игры. Они используются многими модами и являются очень мощным инструментом для разработчиков модов. +::: + +Когда происходит краш миксина, в трассировке стека обычно упоминается миксин и класс, который он модифицирует. + +Метод миксина будет содержать `modid$handlerName` в трассировке стека, где `modid` - айди мода, а `handlerName` - название обработчика миксина. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +Вы можете использовать эту информацию, чтобы найти мод, вызвавший краш, и сообщить о нём автору мода. + +## Что делать с краш-репортами? {#what-to-do-with-crash-reports} + +Лучшее, что можно сделать с краш-репортами - это загрузить их на сайт для текстов, а затем отправить ссылку автору мода либо в раздел с проблемами мода, либо через какую-либо форму связи (дискорд и т.д.). + +Это позволит автору мода изучить краш, потенциально воспроизвести его и решить проблему, которая его вызвала. + +Распространенными сайтами для текстов, которые часто используются для краш-репортов, являются: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/ru_ru/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/ru_ru/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..930153c68 --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Загрузка логов +description: Как загрузить логи для устранения проблем. +authors: + - IMB11 +--- + +# Загрузка логов {#uploading-logs} + +При устранении проблем часто бывает необходимо предоставить логи, которые помогут определить причину проблемы. + +## Почему я должен загружать журналы? {#why-should-i-upload-logs} + +Загрузка логов позволяет другим людям в устранении проблем гораздо быстрее, чем просто вставка логов в сообщение в чате или на форуме. Это также позволяет вам делиться своими логами с другими людьми без необходимости копировать и вставлять их. + +Некоторые сайты для текстов также предоставляют подсветку синтаксиса для логов, что облегчает их чтение, а также они могут подвергать цензуре конфиденциальную информацию, например, системную информацию или ваш ник. + +## Краш-репорты {#crash-reports} + +Краш-репорты генерируются автоматически при краше игры. Они содержат только информацию о краше, а не фактические логи игры. Они находятся в папке `crash-reports` в папке игры. + +Дополнительные сведения о краш-репортах смотрите [в гайде о краш-репортах](./crash-reports). + +## Нахождение логов {#locating-logs} + +Этот гайд относится к официальному лаунчеру (или же "ванильный лаунчер"). Для сторонних лаунчеров вам следует ознакомиться с их документацией. + +Логи находятся в папке `logs` в папке игры, которую можно найти в следующих местах, в зависимости от вашей операционной системы: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +Файл с последними логами называется `latest.log`, предыдущие логи называются по шаблону `гггг-мм-дд_номер.log.gz`. + +## Загрузка логов {#uploading-logs-online} + +Логи могут быть загружены в различные сервисы, такие как: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/ru_ru/players/updating-fabric.md b/versions/1.21/translated/ru_ru/players/updating-fabric.md new file mode 100644 index 000000000..4ddefec80 --- /dev/null +++ b/versions/1.21/translated/ru_ru/players/updating-fabric.md @@ -0,0 +1,43 @@ +--- +title: Обновление Fabric +description: Пошаговая инструкция по обновлению Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Обновление Fabric {#updating-fabric} + +В этом гайде мы расскажем вам об обновлении Fabric на официальном лаунчере Minecraft. + +Для сторонних лаунчеров вам следует ознакомиться с их документацией. + +Обновление Fabric - это процесс, очень похожий на установку Fabric, поэтому части этого гайда будут такими же, как и в гайде [Установка Fabric](./installing-fabric). + +## Почему я должен обновлять загрузчик Fabric? {#why-should-i-update-fabric-loader} + +Для работы с новыми модами может потребоваться более новая версия загрузчика Fabric, поэтому важно поддерживать её в актуальном состоянии, чтобы вы могли использовать последние версии модов. + + + + + +Чтобы обновить Fabric, просто убедитесь в правильности версии игры и загрузчика, а затем нажмите `Установить`. + +:::warning ВАЖНО +Обязательно снимите флажок `Создать профиль` при установке, иначе появится новый профиль, который в данном случае нам не нужен. +::: + +## 3. Откройте профиль в лаунчере Minecraft {#3-open-the-profile-in-the-minecraft-launcher} + +Как только установка завершится, вы можете открыть лаунчер Minecraft и перейти во вкладку `Установки`. Вам следует зайти в профиль Fabric и открыть экран редактирования. + +Замените версию загрузчика на новую, которую вы только что установили, и нажмите `Сохранить`. + +![Обновление версии загрузчика Fabric в лаунчере Minecraft](/assets/players/updating-fabric.png) + +## 4. Готово! {#4-you-re-done} + +Как только вы выполните все действия, вы можете вернуться в главную вкладку, выбрать профиль Fabric из списка в левом нижнем углу и нажать Играть! + +Если вы столкнулись с какими-либо проблемами, попросите помощи в [дискорде Fabric](https://discord.gg/v6v4pMv) в канале `#player-support`. diff --git a/versions/1.21/translated/ru_ru/sidebar_translations.json b/versions/1.21/translated/ru_ru/sidebar_translations.json new file mode 100644 index 000000000..e0fdccd20 --- /dev/null +++ b/versions/1.21/translated/ru_ru/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "Руководства для игроков", + "players.faq": "Часто задаваемые вопросы", + "players.installingJava": "Установка Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Установка Fabric", + "players.findingMods": "Поиск безопасных модов", + "players.installingMods": "Установка модов", + "players.troubleshooting": "Устранение неполадок", + "players.troubleshooting.uploadingLogs": "Загрузка журналов", + "players.troubleshooting.crashReports": "Сообщения о сбоях", + "players.updatingFabric": "Обновление Fabric", + "develop.title": "Руководства для разработчиков", + "develop.gettingStarted": "Начало работы", + "develop.gettingStarted.introduction": "Введение в Fabric и создание модов", + "develop.gettingStarted.devEnvSetup": "Настройка среды разработки", + "develop.gettingStarted.creatingProject": "Создание проекта", + "develop.gettingStarted.projectStructure": "Структура проекта", + "develop.gettingStarted.launchGame": "Запуск игры", + "develop.gettingStarted.solvingProblems": "Простое решение проблем", + "develop.items": "Предметы", + "develop.items.first-item": "Создание вашего первого предмета", + "develop.items.food": "Еда", + "develop.items.custom-armor": "Собственная броня", + "develop.items.custom-tools": "Собственные инструменты", + "develop.items.custom-item-groups": "Собственные вкладки с предметами", + "develop.items.custom-item-interactions": "Собственная интерактивность с предметами", + "develop.items.potions": "Зелья", + "develop.items.custom-data-components": "Пользовательские компоненты данных", + "develop.blocks": "Блоки", + "develop.blocks.first-block": "Создание вашего первого блока", + "develop.blocks.blockstates": "Состояние блоков", + "develop.entities": "Сущности", + "develop.entities.effects": "Эффекты состояния", + "develop.entities.damage-types": "Типы урона", + "develop.commands": "Команды", + "develop.commands.basics": "Создание команд", + "develop.commands.arguments": "Аргументы команд", + "develop.commands.suggestions": "Подсказки к командам", + "develop.rendering": "Отрисовка", + "develop.rendering.basicConcepts": "Основные концепции отрисовки", + "develop.rendering.drawContext": "Использование Drawing Context", + "develop.rendering.hud": "Отрисовка в HUD", + "develop.rendering.gui": "Интерфейсы и экраны", + "develop.rendering.gui.customScreens": "Собственные экраны", + "develop.rendering.gui.customWidgets": "Собственные виджеты", + "develop.rendering.particles": "Частицы", + "develop.rendering.particles.creatingParticles": "Создание своих частиц", + "develop.misc": "Прочие страницы", + "develop.misc.codecs": "Кодеки", + "develop.misc.events": "События", + "develop.misc.text-and-translations": "Текст и переводы", + "develop.misc.ideTipsAndTricks": "Советы и Трюки по IDE", + "develop.misc.automatic-testing": "Автоматическое тестирование", + "develop.sounds": "Звуки", + "develop.sounds.using-sounds": "Воспроизведение SoundEvents", + "develop.sounds.custom": "Создание своих звуков" +} diff --git a/versions/1.21/translated/ru_ru/website_translations.json b/versions/1.21/translated/ru_ru/website_translations.json new file mode 100644 index 000000000..ef166dce5 --- /dev/null +++ b/versions/1.21/translated/ru_ru/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "Авторы страницы", + "authors.nogithub": "%s (не на GitHub)", + "banner": "Документация Fabric всё ещё пишется. Сообщайте о недочётах на %s или в %s.", + "description": "Полная документация Fabric, набор инструментов моддинга для Minecraft.", + "download": "Скачать %s", + "footer.next": "Следующая страница", + "footer.prev": "Предыдущая страница", + "github_edit": "Править эту страницу на GitHub", + "lang_switcher": "Изменить язык", + "last_updated": "Последнее обновление", + "mode_dark": "Сменить на тёмную тему", + "mode_light": "Сменить на светлую тему", + "mode_switcher": "Внешний вид", + "nav.contribute": "Внести вклад", + "nav.contribute.api": "Fabric API", + "nav.download": "Скачать", + "nav.home": "Главная", + "outline": "На этой странице", + "return_to_top": "Вернуться наверх", + "search.back": "Закрыть поиск", + "search.button": "Поиск", + "search.display_details": "Отобразить подробный список", + "search.footer.close": "закрыть", + "search.footer.close.key": "Escape", + "search.footer.down.key": "Стрелка вниз", + "search.footer.navigate": "навигация", + "search.footer.up.key": "Стрелка вверх", + "search.footer.select": "выбрать", + "search.footer.select.key": "Ввод", + "search.no_results": "Нет результатов", + "search.reset": "Сбросить поиск", + "sidebar_menu": "Меню", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Документация Fabric", + "version.reminder": "Страница написана для версии игры:", + "version.switcher": "Сменить Версию", + "404.code": "404", + "404.crowdin_link": "Перевести на Crowdin", + "404.crowdin_link.label": "Открыть редактор Crowdin", + "404.english_link": "Читать на английском", + "404.english_link.label": "Открыть Английскую версию", + "404.link": "Вернуться на главную", + "404.link.label": "Перейти на домашнюю страницу", + "404.quote": "Эта страница пыталась поплавать в лаве", + "404.title": "Страница не найдена" +} diff --git a/versions/1.21/translated/tr_tr/develop/index.md b/versions/1.21/translated/tr_tr/develop/index.md new file mode 100644 index 000000000..d1b7fb00d --- /dev/null +++ b/versions/1.21/translated/tr_tr/develop/index.md @@ -0,0 +1,12 @@ +--- +title: Geliştirici Rehberleri +description: Topluluk tarafından yazılmış geliştirici rehberlerimiz, development ortamını hazırlamaktan render ve network gibi daha karmaşık konulara kadar giden pek çok konuyu içerir. +--- + +# Geliştirici Rehberleri + +Topluluk tarafından yazılmış geliştirici rehberlerimiz, development ortamını hazırlamaktan render ve network gibi daha karmaşık konulara kadar giden pek çok konuyu içerir. + +Okunabilir bütün geliştirici rehberlerine kenar çubuğundan gözatabilirsiniz. Eğer daha özel bir şey arıyorsan üstteki arama çubuğuna istediğin şeyi yazıp bulabilirsin. + +Eğer Fabric Documentation'a yardım etmek istersen, kaynak kodu ve ilgili [katkıda bulunma kılavuzu](../contributing)nu [GitHub](https://github.com/FabricMC/fabric-docs)'da bulabilirsin diff --git a/versions/1.21/translated/uk_ua/contributing.md b/versions/1.21/translated/uk_ua/contributing.md new file mode 100644 index 000000000..8eb4dce3c --- /dev/null +++ b/versions/1.21/translated/uk_ua/contributing.md @@ -0,0 +1,253 @@ +--- +title: Інструкції щодо внеску +description: Інструкції щодо додавання до документації Fabric. +--- + +# Інструкції щодо внеску {#contributing} + +Ця сторінка використовує [VitePress](https://vitepress.dev/) для створення статичного HTML з різних файлів Markdown. Ви повинні ознайомитися з розширеннями Markdown, які підтримує VitePress [тут](https://vitepress.dev/guide/markdown#features). + +Ви можете зробити свій внесок у розвиток цієї сторінки трьома способами: + +- [Переклад документації](#translating-documentation) +- [Додатковий вміст](#contributing-content) +- [Додатковий каркас](#contributing-framework) + +Усі внески мають відповідати нашим [правилам стилю](#style-guidelines). + +## Переклад документації {#translating-documentation} + +Якщо ви хочете перекласти документацію вашою мовою, ви можете зробити це на [сторінці Fabric Crowdin](https://crowdin.com/project/fabricmc). + + + +## new-content Додатковий вміст {#contributing-content} + +Внесок вмісту є основним способом внеску в документацію Fabric. + +Усі внески вмісту проходять наступні етапи, кожен із яких пов’язаний із міткою: + +1. locally Підготуйте свої зміни та проведіть PR +2. stage:expansion: вказівки щодо розширення, якщо це необхідно +3. stage:verification: Перевірка вмісту +4. stage:cleanup: Граматика, Лінтування... +5. <0>stage:ready: готовий до об’єднання! + +Весь вміст має відповідати нашим [правилам стилю](#style-guidelines). + +### 1. Підготуйте свої зміни {#1-prepare-your-changes} + +Ця сторінка є відкритим кодом і розроблений у сховищі GitHub, що означає, що ми покладаємося на потік GitHub: + +1. [Розгалуження сховища GitHub](https://github.com/FabricMC/fabric-docs/fork) +2. Створіть нову гілку у вашому розгалуженні +3. Внесіть зміни в цю гілку +4. Відкрийте запит на зміни у вихідному репозиторію + +Ви можете прочитати більше про потік GitHub [тут](https://docs.github.com/en/get-started/using-github/github-flow). + +Ви можете вносити зміни за допомогою вебінтерфейсу користувача на GitHub або розробляти та переглядати сторінку локально. + +#### Клонування вашого розгалуження + +Якщо ви хочете розробляти локально, вам потрібно буде встановити [Git](https://git-scm.com/). + +Після цього клонуйте своє розгалуження репозиторію за допомогою: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### Встановлення залежностей {#install-dependencies} + +Якщо ви хочете переглянути свої зміни локально, вам потрібно буде встановити [Node.js 18+](https://nodejs.org/en/). + +Після цього переконайтеся, що встановили всі залежності за допомогою: + +```sh +npm install +``` + +#### Запуск сервера розробки {#run-the-development-server} + +Це дозволить вам переглянути ваші зміни локально на `localhost:5173` і автоматично перезавантажить сторінку, коли ви внесете зміни. + +```sh +npm run dev +``` + +Тепер ви можете відкривати та переглядати сторінку у браузері, відвідавши `http://localhost:5173`. + +#### Створення сторінки {#building-the-website} + +Це скомпілює всі файли Markdown у статичні файли HTML і розмістить їх у `.vitepress/dist`: + +```sh +npm run build +``` + +#### Попередній перегляд створеної сторінки {#previewing-the-built-website} + +Попередній перегляд створеної сторінки {#previewing-the-built-website}. + +```sh +npm run preview +``` + +#### Відкриття запиту на зміни {#opening-a-pull-request} + +Після того, як ви задоволені своїми змінами, ви можете `push` свої зміни: + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +Потім перейдіть за посиланням у виводі `git push`, щоб відкрити запит на зміни. + +### 2. stage:expansion Рекомендації щодо розширення, якщо це необхідно {#2-guidance-for-expansion-if-needed} + +Якщо команда документації вважає, що ви можете розширити свій запит на зміну, член команди додасть мітку <0>stage:expansion до вашого запиту разом із коментарем, у якому пояснюється, що, на їхню думку, ви можете розширити. Якщо ви згодні з пропозицією, ви можете розширити свій запит на отримання. + +Якщо ви не хочете розширювати свій запит на зміни, але ви раді, щоб хтось інший розширив його пізніше, вам слід створити проблему на [сторінці проблем](https://github.com/FabricMC/ fabric-docs/issues) і поясніть, що, на вашу думку, можна розширити. Потім команда документації додасть мітку <0>help-wanted до вашого запиту. + +### 3. <0>stage:verification Перевірка вмісту {#3-content-verification} + +Це найважливіший етап, оскільки він гарантує, що вміст є точним і відповідає посібнику зі стилю документації Fabric. + +На цьому етапі необхідно відповісти на наступні питання: + +- Чи весь вміст правильний? +- Чи весь вміст актуальний? +- Чи охоплює вміст усі випадки, наприклад різні операційні системи? + +### 4. <0>stage:cleanup Очищення {#4-cleanup} + +На цьому етапі відбувається наступне: + +- Виправлення будь-яких граматичних проблем за допомогою [LanguageTool](https://languagetool.org/) +- Лінтування всіх файлів Markdown за допомогою [`markdownlint`](https://github.com/DavidAnson/markdownlint) +- Форматування всього коду Java за допомогою [Checkstyle](https://checkstyle.sourceforge.io/) +- Інші різноманітні виправлення або покращення + +## framework Додатковий каркас {#contributing-framework} + +Каркас стосується внутрішньої структури сторінки, будь-які запити на зміни, які змінюють каркас сторінки, позначатимуться міткою <0>framework. + +Ви дійсно повинні робити каркас запиту на зміни лише після консультації з командою документації на [Fabric Discord](https://discord.gg/v6v4pMv) або через проблему. + +:::info +Зміна файлів бічної панелі та налаштування навігаційної панелі не вважається каркасом запитом на зміни. +::: + +## Правила стилю {#style-guidelines} + +Якщо ви в чомусь не впевнені, ви можете запитати в [Fabric Discord](https://discord.gg/v6v4pMv) або через GitHub Discussions. + +### Напишіть оригінал американською англійською {#write-the-original-in-american-english} + +Вся оригінальна документація написана англійською мовою з дотриманням американських правил граматики. + +### Додайте дані до Frontmatter {#add-data-to-the-frontmatter} + +Кожна сторінка повинна мати `description` і `title` на передній частині. + +Не забувайте також додати своє ім’я користувача GitHub до `authors` у передній частині файлу Markdown! Таким чином ми можемо надати вам належне згадування. + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### Додайте прив’язки до заголовків {#add-anchors-to-headings} + +Кожен заголовок повинен мати прив’язку, яка використовується для посилання на цей заголовок: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +Прив'язка повинна використовувати малі літери, цифри та тире. + +### Розмістіть код у моді `/reference` {#place-code-within-the-reference-mod} + +Якщо ви створюєте або змінюєте сторінки, що містять код, розмістіть код у відповідному місці в посилання моду (розташованому в теці`/reference` сховища). Потім скористайтеся [функцією фрагмента коду, запропонованою VitePress](https://vitepress.dev/guide/markdown#import-code-snippets), щоб вставити код. + +Наприклад, щоб виділити рядки 15-21 файлу `FabricDocsReference.java` з посилання моду: + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +Якщо вам потрібен більший діапазон контролю, ви можете скористатися [функцією перемикання з `markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + +Наприклад, це дозволить вставити розділи файлу вище, позначені теґом `#entrypoint`: + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### Створіть бічну панель для кожного нового розділу {#create-a-sidebar-for-each-new-section} + +Якщо ви створюєте новий розділ, вам слід створити нову бічну панель у теці `.vitepress/sidebars` й додати її до файлу `i18n.mts`. + +Якщо вам потрібна допомога з цим, запитайте на каналі `#docs` [Fabric Discord](https://discord.gg/v6v4pMv). + +### Додайте нові сторінки до відповідних бічних панелей {#add-new-pages-to-the-relevant-sidebars} + +Створюючи нову сторінку, ви повинні додати її до відповідної бічної панелі в теці `.vitepress/sidebars`. + +Знову ж таки, якщо вам потрібна допомога, запитайте у Fabric Discord на каналі `#docs`. + +### Розмістіть медіа в `/assets` {#place-media-in-assets} + +Будь-які зображення слід розміщувати у відповідному місці в теці `/public/assets`. + +### Використовуйте відносні посилання! {#use-relative-links} + +Це пов’язано з наявною системою керування версіями, яка попередньо оброблятиме посилання для додавання версії. Якщо ви використовуєте абсолютні посилання, номер версії не буде додано до посилання. + +Ви також не повинні додавати розширення файлу до посилання. + +Наприклад, щоб зробити посилання на сторінку, знайдену в `/players/index.md` зі сторінки `/develop/index.md`, вам потрібно буде зробити наступне: + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/uk_ua/develop/blocks/block-entities.md b/versions/1.21/translated/uk_ua/develop/blocks/block-entities.md new file mode 100644 index 000000000..bd970045b --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/blocks/block-entities.md @@ -0,0 +1,112 @@ +--- +title: Блоки-сутності +description: Навчіться створювати блоки-сутності. +authors: + - natri0 +--- + +# Блоки-сутності {#block-entities} + +Блоки-сутності — це спосіб зберігати додаткові дані для блоку, які не є частиною стану блоку: вміст інвентарю, спеціальна назва тощо. +Minecraft використовує блоки-сутності для блоків, як-от скрині, печі й командні блоки. + +Як приклад, ми створимо блок, який підраховує, скільки разів було натиснуто ПКМ. + +## Створення блоку-сутність {#creating-the-block-entity} + +Щоб змусити Minecraft розпізнавати та завантажувати нові блоки-сутності, нам потрібно створити тип блоку-сутності Це робиться шляхом розширення класу `BlockEntity` і реєстрації його в новому класі `ModBlockEntities`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Реєстрація `BlockEntity` дає `BlockEntityType`, подібний до `COUNTER_BLOCK_ENTITY`, який ми використовували вище: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/entity/ModBlockEntities.java) + +:::tip +Зверніть увагу, що конструктор `CounterBlockEntity` приймає два параметри, а конструктор `BlockEntity` приймає три: `BlockEntityType`, `BlockPos` і `BlockState`. +Якби ми не жорстко закодували `BlockEntityType`, клас `ModBlockEntities` не компілювався б! Це тому, що `BlockEntityFactory`, який є функціональним інтерфейсом, описує функцію, яка приймає лише два параметри, як і наш конструктор. +::: + +## Створення блоку {#creating-the-block} + +Далі, щоб фактично використовувати блок-сутність нам потрібен блок, який реалізує `BlockEntityProvider`. Нумо створімо один і назвемо його `CounterBlock`. + +:::tip +Є два способи підійти до цього: + +- створити блок, який розширює `BlockWithEntity`, і реалізувати метод `createBlockEntity` (_і_ метод `getRenderType`, оскільки `BlockWithEntity` робить його невидимим за замовчуванням) +- створити блок, який сам по собі реалізує `BlockEntityProvider` і замінити метод `createBlockEntity` + +У цьому прикладі ми використаємо перший підхід, оскільки `BlockWithEntity` також надає кілька крутих штук. +::: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Використання `BlockWithEntity` як батьківського класу означає, що нам також потрібно реалізувати метод `createCodec`, який досить простий. + +На відміну від блоків, які є одинарними, нова блок-сутність створюється для кожного екземпляра блоку. Це робиться за допомогою методу `createBlockEntity`, який приймає позицію та `BlockState` і повертає `BlockEntity` або `null`, якщо його не має бути. + +Не забудьте зареєструвати блок у класі `ModBlocks`, як у посібнику [Створення вашого першого блоку](../blocks/first-block): + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +## Використання блоку-сутності {#using-the-block-entity} + +Тепер, коли у нас є блок-сутність, ми можемо використовувати його для збереження кількості натискань ПКМ по блоку. Ми зробимо це, додавши поле `clicks` до класу `CounterBlockEntity`: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Метод `markDirty`, який використовується в `incrementClicks`, повідомляє грі, що дані цієї сутності було оновлено; це буде корисно, коли ми додамо методи серіалізації лічильника та завантаження його назад із файлу збереження. + +Далі нам потрібно збільшувати це поле кожного разу, коли по блоку натискають ПКМ. Це робиться шляхом перевизначення методу `onUse` в класі `CounterBlock`: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +Оскільки `BlockEntity` не передається в метод, ми використовуємо `world.getBlockEntity(pos)`, і якщо `BlockEntity` недійсний, повертаємося з методу. + +![Повідомлення «Ви натиснули блок у шосте» на екрані після натискання ПКМ](/assets/develop/blocks/block_entities_1.png) + +## Збереження і завантаження даних {#saving-loading} + +Тепер, коли у нас є функціональний блок, ми повинні зробити так, щоб лічильник не обнулявся між перезавантаженнями гри. Це робиться шляхом серіалізації в NBT під час збереження гри та десеріалізації під час завантаження. + +Серіалізація виконується за допомогою методу `writeNbt`: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Тут ми додаємо поля, які слід зберегти в переданому `NbtCompound`: у випадку блоку лічильника це поле `clicks`. + +Читання відбувається подібно, але замість збереження в `NbtCompound` ви отримуєте значення, які ви зберегли раніше, і зберігаєте їх у полях BlockEntity: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Тепер, якщо ми збережемо та перезавантажимо гру, блок лічильника має продовжуватися з того місця, на якому він зупинився під час збереження. + +## Тикери {#tickers} + +Інтерфейс `BlockEntityProvider` також визначає метод під назвою `getTicker`, який можна використовувати для запуску коду кожного тика для кожного екземпляра блоку. Ми можемо реалізувати це, створивши статичний метод, який використовуватиметься як `BlockEntityTicker`: + +Метод `getTicker` також має перевірити, чи переданий `BlockEntityType` збігається з тим, який ми використовуємо, і якщо це так, повертати функцію, яка буде викликатися кожного такту. На щастя, є допоміжна функція, яка виконує перевірку в `BlockWithEntity`: + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/CounterBlock.java) + +`CounterBlockEntity::tick` — це посилання на статичний метод `tick`, який ми повинні створити в класі `CounterBlockEntity`. Структурувати його таким чином не обов’язково, але це гарна практика, щоб код був чистим і організованим. + +Скажімо, ми хочемо зробити так, щоб лічильник можна було збільшувати лише один раз кожні 10 тактів (2 рази на секунду). Ми можемо зробити це, додавши поле `ticksSinceLast` до класу `CounterBlockEntity` і збільшуючи його кожного такту: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +Не забудьте серіалізувати та десеріалізувати це поле! + +Тепер ми можемо використовувати `ticksSinceLast`, щоб перевірити, чи можна збільшити лічильник у `incrementClicks`: + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/block/entity/custom/CounterBlockEntity.java) + +:::tip +Якщо блок-сутність не працює, спробуйте перевірити реєстраційний код! Він має передати блоки, дійсні для цієї сутності, у `BlockEntityType.Builder`, інакше він видасть попередження на консолі: + +```text +[13:27:55] [Server thread/WARN] (Minecraft) Block entity fabric-docs-reference:counter @ BlockPos{x=-29, y=125, z=18} state Block{fabric-docs-reference:counter_block} invalid for ticking: +``` + +::: diff --git a/versions/1.21/translated/uk_ua/develop/blocks/block-entity-renderer.md b/versions/1.21/translated/uk_ua/develop/blocks/block-entity-renderer.md new file mode 100644 index 000000000..aa6d8830c --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/blocks/block-entity-renderer.md @@ -0,0 +1,99 @@ +--- +title: Промальовування блоку-сутності +description: Дізнайтеся, як покращити промальовування за допомогою промальовування блоку-сутності. +authors: + - natri0 +--- + +# Промальовування блоку-сутності {#block-entity-renderers} + +Іноді використання формату моделі Minecraft недостатньо. Якщо вам потрібно додати до нього динамічне промальовування, вам потрібно буде використовувати `BlockEntityRenderer`. + +Наприклад, нумо зробимо так, щоб блок лічильника зі [статті про блокові-сутностей](../blocks/block-entities) показував кількість натискань у зверху. + +## Створення BlockEntityRenderer {#creating-a-blockentityrenderer} + +Для початку, нам треба створити `BlockEntityRenderer` для `CounterBlockEntity`. + +Створюючи `BlockEntityRenderer` для `CounterBlockEntity`, важливо помістити клас у відповідний вихідний набір, наприклад `src/client/`, якщо ваш проєкт використовує розділені вихідні набори для клієнта та сервера. Доступ до пов’язаних із промальовуванням класів безпосередньо у вихідному наборі `src/main/` небезпечний, оскільки ці класи можуть бути завантажені на сервер. + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +Новий клас має конструктор із `BlockEntityRendererFactory.Context` як параметр. У `Context` є кілька корисних штук промальовування, наприклад `ItemRenderer` або `TextRenderer`. +Крім того, включивши такий конструктор, стає можливим використовувати конструктор як сам функціональний інтерфейс `BlockEntityRendererFactory`: + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/FabricDocsBlockEntityRenderer.java) + +Додайте точку входу до файлу `fabric.mod.json`, щоб зареєструвати промальовування. + +`BlockEntityRendererFactory` — це реєстр, який зіставляє кожен `BlockEntityType` зі спеціальним кодом відтворення на відповідний `BlockEntityRenderer`. + +## Малювання на блоках {#drawing-on-blocks} + +Тепер, коли у нас є промальовування, ми можемо малювати. Метод `render` викликається кожним кадром, і саме в ньому відбувається магія промальовування. + +### Пересування {#moving-around} + +По-перше, нам потрібно змістити та повернути текст так, щоб він знаходився вище блоку. + +:::info +Як випливає з назви, `MatrixStack` є _стосом_, що означає, що ви можете надсилати та витягувати перетворення. +Гарне емпіричне правило полягає в тому, щоб додати новий блок на початку методу `render` і відкрити його в кінці, щоб промальовування одного блоку не впливав на інші. + +Більше інформації про `MatrixStack` можна знайти в [статті про базові концепції промальовування](../rendering/basic-concepts). +::: + +Щоб полегшити розуміння необхідних перекладів і поворотів, візуалізуємо їх. На цьому зображенні зелений блок – це місце, де буде намальовано текст, за замовчуванням у найдальшій нижній лівій точці блоку: + +![Позиція промальовування за замовчуванням](/assets/develop/blocks/block_entity_renderer_1.png) + +Отже, спочатку нам потрібно перемістити текст наполовину блоку по осях X і Z, а потім перемістити його вгору до верхньої частини блоку по осі Y: + +![Зелений блок у верхній центральній точці](/assets/develop/blocks/block_entity_renderer_2.png) + +Це робиться за допомогою одного виклику `translate`: + +```java +matrices.translate(0.5, 1, 0.5); +``` + +Ось і _переклад_ зроблено, _обертання_ і _масштаб_ залишаються + +За замовчуванням текст малюється на площині X-Y, тому нам потрібно повернути його на 90 градусів навколо осі X, щоб він був спрямований вгору на площині X-Z: + +![Зелений блок у верхній центральній точці, спрямований догори] (/assets/develop/blocks/block_entity_renderer_3.png) + +`MatrixStack` не має функції `rotate`, натомість нам потрібно використовувати `multiply` і `RotationAxis.POSITIVE_X`: + +```java +matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); +``` + +Тепер текст у правильному положенні, але він завеликий. `BlockEntityRenderer` промальовує весь блок на куб `[-0.5, 0.5]`, тоді як `TextRenderer` використовує координати Y `[0, 9]`. Таким чином, нам потрібно зменшити його в 18 разів: + +```java +matrices.scale(1/18f, 1/18f, 1/18f); +``` + +Тепер усе перетворення виглядає так: + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +### Малювання тексту {#drawing-text} + +Як згадувалося раніше, `Context`, переданий у конструктор нашого промальовування, має `TextRenderer`, який ми можемо використовувати для малювання тексту. Для цього прикладу ми збережемо його в полі. + +`TextRenderer` має методи для вимірювання тексту (`getWidth`), що корисно для центрування, і для його малювання (`draw`). + +@[code transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/blockentity/CounterBlockEntityRenderer.java) + +Метод `draw` приймає багато параметрів, але найважливіші з них: + +- `Text` (або `String`) для малювання; +- його координати `x` і `y`; +- значення 'кольору' RGB; +- `Matrix4f`, що описує, як його слід трансформувати (щоб отримати один із `MatrixStack`, ми можемо використати `.peek().getPositionMatrix()`, щоб отримати `Matrix4f` для самого верхнього запису). + +І після всієї цієї роботи ось результат: + +![Блок лічильника з числом зверху](/assets/develop/blocks/block_entity_renderer_4.png) diff --git a/versions/1.21/translated/uk_ua/develop/blocks/blockstates.md b/versions/1.21/translated/uk_ua/develop/blocks/blockstates.md new file mode 100644 index 000000000..25755f573 --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/blocks/blockstates.md @@ -0,0 +1,127 @@ +--- +title: Стан блоку +description: Дізнайтеся, чому стан блоку це чудовий спосіб додати візуальну функціональність для ваших блоків. +authors: + - IMB11 +--- + +# Стан блоку {#block-states} + +Стан блоку — це частина даних, що прикріплюється до окремого блоку у світі Minecraft та містить інформацію про блок у вигляді властивостей. Ось кілька прикладів властивостей, які в стандартній версії гри зберігаються в станах блоків: + +- Обертання: Зазвичай використовується для колод та інших природних блоків. +- Активний: Широко використовується у пристроях з редстоуном і блоках, таких як піч або коптильня. +- Вік: Використовується в посівах, траві, саджанцях, ламінарії тощо. + +Ви, напевно, розумієте чому вони корисні - вони уникають необхідності зберігати дані NBT дані у блоковій сутності - зменшуючи розмір світу, та запобігаючи проблемам із TPS! + +Визначення станів блоку знаходиться у теці `assets//blockstates`. + +## Наприклад: Блок колонна {#pillar-block} + + + +Minecraft має деякі користувальницькі класи, які дозволять вам швидко створити певні типи блоків - в цьому прикладі розглядається створення блоку з властивістю `axios` шляхом створення блоку "Condensed Oak Log". + +Ванільний клас `PillarBlock` дозволяє розміщувати блок по осях X, Y або Z. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Блоки колон мають дві текстури, верхню та бічну - вони використовують модель `block/cube_column`. + +Як і зазвичай, з усіма текстурами блоків, текстури можна знайти в `assets//textures/block` + +Текстури + +Оскільки стовпчик має два положення, горизонтальне та вертикальне, нам потрібно буде створити два окремих файли моделі: + +- `condensed_oak_log_horizontal.json`, який розширює модель `block/cube_column_horizontal`. +- `condensed_oak_log.json`, який розширює модель `block/cube_column`. + +Приклад файлу `condensed_oak_log_horizontal.json`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +Щоб детальніше ознайомитися з усіма модифікаторами, доступними у файлах стану блоку, перегляньте сторінку [Вікі Minecraft — Моделі (Стани блоків)](https://minecraft.wiki/w/Tutorials/Models#Block_states). +::: + +Далі, ми повинні створити файл стану блоку У файлі blockstate відбувається магія — стовпові блоки мають три осі, тому ми використовуватимемо спеціальні моделі для таких ситуацій: + +- `axis=x` – коли блок розміщено вздовж осі X, ми повертатимемо модель у позитивному напрямку X. +- `axis=y` – коли блок розміщено вздовж осі Y, ми будемо використовувати звичайну вертикальну модель. +- `axis=z` – коли блок розміщується вздовж осі Z, ми повертаємо модель у позитивний X. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +Як завжди, вам потрібно буде створити переклад для свого блоку та модель предмета, яка є батьками будь-якої з двох моделей. + +![Приклад блоку стовпа у грі](/assets/develop/blocks/blockstates_1.png) + +## Власні стани блоків {#custom-block-states} + +Спеціальні стани блоку чудові, якщо ваш блок має унікальні властивості - іноді ви можете виявити, що ваш блок може повторно використовувати ванілльні властивості. + +У цьому прикладі буде створено унікальну логічну властивість під назвою `activated` - коли гравець натискає ПКМ по блоку, він змінюватиме значення `activated=false` на `activated=true`, відповідно змінюючи свою текстуру. + +### Створення властивості {#creating-the-property} + +По-перше, вам потрібно буде створити саму властивість — оскільки це логічне значення, ми використаємо метод `BooleanProperty.of`. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Далі ми маємо додати властивість до менеджера стану блоку в методі appendProperties. Щоб отримати доступ до конструктора, вам потрібно змінити метод: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +Ви також повинні встановити стан за замовчуванням для властивості `activated` у конструкторі вашого спеціального блоку. + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +Не забудьте зареєструвати свій блок, використовуючи спеціальний клас замість `Block`! +::: + +### Використання властивості {#using-the-property} + +У цьому прикладі змінюється логічна властивість `activated`, коли гравець взаємодіє з блоком. Для цього ми можемо замінити метод `onUse`: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### Візуалізація власності {#visualizing-the-property} + +Перед створенням файлу стану блоку вам потрібно буде надати текстури як для активованого, так і для деактивованого станів блоку, а також для моделі блоку. + +Текстури + +Використовуйте свої знання про моделі блоків, щоб створити дві моделі для блоку: одну для активованого стану та одну для деактивованого стану. Зробивши це, ви можете розпочати створення файлу стану блоку. + +Оскільки ви створили нову властивість, вам потрібно буде оновити файл стану блоку для врахування цієї властивості. + +Якщо у вас є кілька властивостей у блоці, вам потрібно врахувати всі можливі комбінації. Наприклад, `activated` і `axis` призведе до 6 комбінацій (два можливі значення для `activated` і три можливі значення для `axis`). + +Оскільки цей блок має лише два можливі варіанти, оскільки він має лише одну властивість («активовано»), стан блоку JSON виглядатиме приблизно так: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +Оскільки прикладом блоку є лампа, нам також потрібно змусити її випромінювати світло, коли властивість `activated` має значення true. Це можна зробити через налаштування блоку, передані конструктору під час реєстрації блоку. + +Ви можете використовувати метод `luminance`, щоб установити рівень світла, випромінюваного блоком, ми можемо створити статичний метод у класі `PrismarineLampBlock`, щоб повернути рівень освітлення на основі властивості `activated`, і передати його як посилання на метод до методу `luminance`: + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +Коли ви все завершите, кінцевий результат має виглядати приблизно так: + + diff --git a/versions/1.21/translated/uk_ua/develop/blocks/first-block.md b/versions/1.21/translated/uk_ua/develop/blocks/first-block.md new file mode 100644 index 000000000..7f17a95e3 --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/blocks/first-block.md @@ -0,0 +1,170 @@ +--- +title: Створення вашого першого блоку +description: Навчіться як створювати власні блоки в Minecraft. +authors: + - IMB11 + - xEobardThawne + - its-miroma +--- + +# Створення вашого першого блоку {#creating-your-first-block} + +Блоки є будівельними блоками Minecraft (без каламбуру) - як і все інше в Minecraft, вони зберігаються в реєстрах. + +## Підготовка вашого класу блоків {#preparing-your-blocks-class} + +Якщо ви завершили сторінку [Створення свого першого предмета](../items/first-item), цей процес здасться вам дуже знайомим – вам потрібно буде створити метод, який реєструє ваш блок і його блок-предмет. + +Вам слід помістити цей метод у клас під назвою `ModBlocks` (або як ви хочете його назвати). + +Mojang робить щось надзвичайно подібне з ванілльними блоками; ви можете звернутися до класу `Blocks`, щоб побачити, як вони це роблять. + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Як і з предметами, вам потрібно переконатися, що клас завантажено, щоб усі статичні поля, що містять екземпляри вашого блоку, були ініціалізовані. + +Ви можете зробити це, створивши фіктивний метод `initialize`, який можна викликати в [ініціалізаторі мода](./getting-started/project-structure#entrypoints), щоб запустити статичну ініціалізацію. + +:::info +Якщо ви не знаєте, що таке статична ініціалізація, то це процес ініціалізації статичних полів у класі. Це робиться, коли клас завантажується JVM, і робиться до створення будь-яких екземплярів класу. +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## Створення та реєстрація вашого блоку {#creating-and-registering-your-block} + +Подібно до предметів, блоки приймають у своєму конструкторі клас `Blocks.Settings`, який визначає властивості блоку, такі як його звукові ефекти та рівень видобутку. + +Ми не будемо розглядати всі варіанти тут — ви можете самостійно переглянути клас, щоб побачити різні варіанти, які мають бути зрозумілими. + +Для прикладу ми створимо простий блок, який має властивості бруду, але є іншим матеріалом. + +:::tip +Ви також можете використовувати `AbstractBlock.Settings.copy(AbstractBlock block)`, щоб скопіювати налаштування блоку що існує, у цьому випадку ми могли б використати `Blocks.DIRT`, щоб скопіювати налаштування dirt, але для прикладу ми скористаємося конструктором. +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +Щоб автоматично створити блок-предмет ми можемо передати `true` параметру `shouldRegisterItem` методу `register`, який ми створили на попередньому кроці. + +### Додавання вашого блоку до групи предметів {#adding-your-block-to-an-item-group} + +Оскільки `BlockItem` створюється та реєструється автоматично, щоб додати його до групи предметів, ви повинні використати метод `Block.asItem()`, щоб отримати примірник `BlockItem`. + +У цьому прикладі ми використаємо спеціальну групу предметів, створену на сторінці [Групи власних предметів](../items/custom-item-groups). + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +Тепер ви повинні помітити, що ваш блок знаходиться у творчому інвентарі, і його можна розмістити у світі! + +![Блоки у світі без відповідної моделі чи текстури](/assets/develop/blocks/first_block_0.png) + +Однак є кілька проблем: блок-предмет не має назви, і блок не має текстури, моделі блоку чи моделі предмета. + +## Додання перекладу для блока {#adding-block-translations} + +Щоб додати переклад, ви повинні створити ключ перекладу у своєму файлі перекладу - `assets//lang/en_us.json`, це англійська, для української створіть `uk_ua.json`. + +Minecraft використовуватиме цей переклад у творчому інвентарі та інших місцях, де показано його назву, наприклад у повідомленнях команд. + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +Ви можете перезапустити гру або створити свій мод і натиснути F3+T, щоб застосувати зміни, і ви побачите, що блок має назву у творчому інвентарі та інших місцях наприклад екран статистики. + +## Моделі й текстури {#models-and-textures} + +Усі текстури блоків можна знайти в теці `assets//textures/block` - приклад текстури для блоку «Condensed Dirt» можна використовувати безплатно. + +<0>Текстура + +Щоб текстура промальовувалася в грі, ви повинні створити модель блоку і предмета, які можна знайти у відповідних місцях для блоку «Condensed Dirt»: + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +Модель предмета досить проста, вона може просто використовувати модель блоку як батьківську, оскільки більшість моделей блоку підтримують відтворення в інтерфейсах: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +Однак у нашому випадку модель блоку має бути батьківською для моделі `block/cube_all`: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +Коли ви завантажуєте гру, ви можете помітити, що текстури все ще немає. Це тому, що вам потрібно додати визначення стану блоку. + +## Створення визначення стану блоку {#creating-the-block-state-definition} + +Визначення стану блоку використовується для вказівки грі, яку модель промальовувати на основі поточного стану блоку. + +Для прикладу блоку, який не має складного стану блока, у визначенні потрібен лише один запис. + +Цей файл має міститися в папці `assets/mod_id/blockstates`, а його назва має збігатися з ідентифікатором блоку, який використовується під час реєстрації вашого блоку в класі `ModBlocks`. Наприклад, якщо ID блоку `condensed_dirt`, файл повинен мати назву `condensed_dirt.json`. + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +Стани блоку справді складні, тому вони розглядаються на наступній сторінці: [Блокові стани](./blockstates) + +Перезапустіть гру або перезавантажте за допомогою F3+T, щоб застосувати зміни – ви зможете побачити блокову текстуру в інвентарі та фізично у світі: + +![Блок у світі з відповідною текстурою та моделлю](/assets/develop/blocks/first_block_4.png) + +## Додання здобичі для блоку {#adding-block-drops} + +Під час розбивання блоку під час виживання ви можете побачити, що блок не падає — можливо, вам потрібна ця функція, однак, щоб ваш блок випадав як предмет під час ламання, ви повинні застосувати його таблицю здобичі — файл таблиці здобичі слід розмістити в теку `data//loot_table/blocks/`. + +:::info +Щоб краще зрозуміти таблиці здобичі, ви можете звернутися до сторінки [Minecraft Wiki - Таблиці здобичі](https://minecraft.wiki/w/Loot_table). +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +Ця таблиця здобичі забезпечує випадіння одного предмета з блоку, коли блок ламаний або підірваний вибухом. + +## Рекомендований інструмент {#recommending-a-harvesting-tool} + +Ви також можете захотіти, щоб ваш блок можна було збирати лише певним інструментом - наприклад, ви можете зробити свій блок, що ламається швидше за допомогою лопати. + +Усі теґи інструментів слід розміщувати в теці `data/minecraft/tags/block/mineable/`, де назва файлу залежить від типу використовуваного інструменту, одного з наступного: + +- `hoe.json` +- `axe.json` +- `pickaxe.json` +- `shovel.json` + +Вміст файлу досить простий - це список предметів, які потрібно додати в теґ. + +Цей приклад додає блок «Condensed Dirt» до теґу `shovel`. + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +Якщо ви бажаєте, щоб для видобутку блоку був потрібен інструмент, додайте `.requiresTool()` до налаштувань блоку, а також додайте відповідний теґ видобутку. + +## Рівень копання {#mining-levels} + +Подібним чином теґ рівня майнінгу можна знайти в теці `data/minecraft/tags/block/` й відповідає такому формату: + +- `needs_stone_tool.json` - потребує як мінімум кам'яні інструменти +- `needs_iron_tool.json` - потребує як мінімум залізні інструменти +- `needs_diamond_tool.json` - потребує як мінімум діамантові інструменти. + +Файл має той самий формат, що й файл інструменту збору врожаю – список предметів, які потрібно додати до теґу. + +## Додаткові уточнення {#extra-notes} + +Якщо ви додаєте кілька блоків до свого моду, ви можете розглянути можливість використання [генерації даних](https://fabricmc.net/wiki/tutorial:datagen_setup), щоб автоматизувати процес створення моделей блоків і предметів, визначень станів блоків, і таблиці здобичі. diff --git a/versions/1.21/translated/uk_ua/develop/commands/arguments.md b/versions/1.21/translated/uk_ua/develop/commands/arguments.md new file mode 100644 index 000000000..c8e410f80 --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/commands/arguments.md @@ -0,0 +1,66 @@ +--- +title: Аргументи команд +description: Дізнайтеся, як створювати команди зі складними аргументами. +--- + +# Аргументи команди {#command-arguments} + +Аргументи використовуються в більшості команд. Іноді вони можуть бути необов’язковими, тобто якщо ви не надасте аргумент, команда також буде виконана. Один вузол може мати кілька типів аргументів, але майте на увазі, що існує можливість двозначність, якої слід уникати. + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +У цьому випадку після тексту команди `/command_with_arg` слід ввести ціле число. Наприклад, якщо ви +запустіть `/command_with_arg 3`, ви отримаєте повідомлення зворотного зв'язку: + +> Викликається /command_with_arg зі значенням = 3 + +Якщо ввести `/command_with_arg` без аргументів, команду неможливо правильно проаналізувати. + +Потім ми додаємо необов'язковий другий аргумент: + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Зараз ви можете написати одне або два цілих числа. Якщо ви надаєте одне число - відповідь з одним значенням буде надрукована. Якщо ви надаєте два чиста - відповідь з двома значеннями буде надрукована. + +Ви можете вважати непотрібним вказувати подібні виконання двічі. Таким чином, ми можемо створити метод, який буде використовуватися в +обидва виконання. + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Власні типи аргументу {#custom-argument-types} + +Якщо в грі не має потрібного типу аргументу, ви можете створити свій власний. Для цього вам потрібно створити клас, який успадковує інтерфейс `ArgumentType<0>`, де `T` є типом аргументу. + +Вам потрібно буде реалізувати метод `parse`, який аналізуватиме вхідний рядок у потрібний тип. + +Наприклад, ви можете створити тип аргументу, який аналізує `BlockPos` із рядка в такому форматі: `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Реєстрація спеціальних типів аргументів {#registering-custom-argument-types} + +:::warning +Вам потрібно зареєструвати тип спеціального аргументу як на сервері, так і на клієнті, інакше команда не працюватиме! +::: + +Ви можете зареєструвати власний тип аргументу в методі `onInitialize` вашого [ініціалізатора мода](./getting-started/project-structure#entrypoints) за допомогою класу `ArgumentTypeRegistry`: + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Використання спеціальних типів аргументів {#using-custom-argument-types} + +Ми можемо використовувати наш власний тип аргументу в команді, передавши його екземпляр у метод `.argument` у конструкторі команд. + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Виконуючи команду, ми можемо перевірити, чи працює тип аргументу: + +![Недійсний аргумент](/assets/develop/commands/custom-arguments_valid.png) + +![Дійсний аргумент](/assets/develop/commands/custom-arguments_valid.png) + +![Результат команди](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/uk_ua/develop/commands/suggestions.md b/versions/1.21/translated/uk_ua/develop/commands/suggestions.md new file mode 100644 index 000000000..fea41241d --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/commands/suggestions.md @@ -0,0 +1,49 @@ +--- +title: Пропозиції команд +description: Дізнайтеся як пропонувати користувачам можливі значення аргументу команди. +authors: + - IMB11 +--- + +# Пропозиції команд {#command-suggestions} + +Minecraft має потужну систему пропозицій команд, що використовується у багатьох місцях, таких як команда `/give`. Ця система дозволяє пропонувати гравцю значення аргументу, які вони можуть вибрати, що є гарним засобом створення більш зручних та ергономічних команд. + +## Постачальники пропозицій {#suggestion-providers} + +Клас `SuggestionProvider` використовується для створення списку пропозицій, які будуть надіслані гравцю. Постачальник пропозицій - це функція, що приймає об'єкти `CommandContext` та `SuggestionBuilder`, та повертає об'єкт `Suggestions`. `SuggestionProvider` повертає об'єкт `CompletableFuture` тому, що пропозиції можуть бути не доступні відразу. + +## Використання постачальників пропозицій {#using-suggestion-providers} + +Для використання постачальника пропозицій треба викликати метод `suggests` в об'єкта `ArgumentBuilder`. Цей метод приймає об'єкт `SuggestionProvider` та повертає свій `ArgumentBuilder` з доданим постачальником пропозицій. + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Вбудовані постачальники пропозицій {#built-in-suggestion-providers} + +Minecraft надає декілька вбудованих постачальників пропозицій: + +| Постачальник | Опис | +| ----------------------------------------- | -------------------------------------------------------------- | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | Пропонує всі істоти, що можуть бути викликані. | +| `SuggestionProviders.AVAILABLE_SOUNDS` | Пропонує всі звуки, що можуть бути зіграні. | +| `LootCommand.SUGGESTION_PROVIDER` | Пропонує всі доступні таблиці здобичі. | +| `SuggestionProviders.ALL_BIOMES` | Пропонує всі доступні біоми. | + +## Створити власний постачальник пропозицій {#creating-a-custom-suggestion-provider} + +Якщо вбудовані постачальники пропозицій не підходять, ви можете створити свій постачальник. Для цього треба створити клас, який реалізує інтерфейс `SuggestionProvider` і перевизначає метод `getSuggestions`. + +Для цього прикладу ми зробимо постачальник, який пропонує імена гравців на сервері. + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +Щоб скористатися цим постачальником, треба просто передати його об'єкт у метод `.suggests` у `ArgumentBuilder`. + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Звісно, що постачальники пропозицій можуть бути складнішими, оскільки вони також можуть зчитувати контекст команди та надавати пропозиції на основі її стану - наприклад, аргументи, що вже були надані. + +Це може також зчитувати інвентар гравця та пропонувати предмети, або сутностей, які неподалік від гравця. diff --git a/versions/1.21/translated/uk_ua/develop/index.md b/versions/1.21/translated/uk_ua/develop/index.md new file mode 100644 index 000000000..d54c588b3 --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/index.md @@ -0,0 +1,14 @@ +--- +title: Посібник для розробників +description: Наші посібники для розробників, написані спільнотою, охоплюють все - від налаштування середовища розробки до просунутих тем, таких як промальовування та робота мережі. +--- + +# Посібник для розробників {#developer-guides} + +Написані спільнотою, ці посібники охоплюють широкий спектр тем, від налаштування середовища розробки до більш просунутих областей, таких як промальовування і робота мережі. + +Перевірте бічну панель, щоб знайти список усіх доступних посібників. Якщо ви шукаєте щось конкретне, рядок пошуку вгорі сторінки - ваш найкращий друг. + +Пам’ятайте: повністю робочий мод з усім кодом для цієї документації доступний у теці[`/reference` на GitHub](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21). + +Якщо ви хочете зробити свій внесок у документацію Fabric, ви можете знайти вихідний код на [GitHub](https://github.com/FabricMC/fabric-docs), а також відповідні [правила внеску](../contributing). diff --git a/versions/1.21/translated/uk_ua/develop/text-and-translations.md b/versions/1.21/translated/uk_ua/develop/text-and-translations.md new file mode 100644 index 000000000..cc5544339 --- /dev/null +++ b/versions/1.21/translated/uk_ua/develop/text-and-translations.md @@ -0,0 +1,143 @@ +--- +title: Текст і переклади +description: Повна документація щодо роботи Minecraft з форматованим текстом і перекладами. +authors: + - IMB11 + - LordEnder-Kitty +--- + +# Текст і переклади {#text-and-translations} + +Щоразу, коли Minecraft промальовує текст у грі, він, ймовірно, визначається за допомогою об’єкта `Text`. +Цей власний тип використовується замість `String` для більш розширеного форматування, +включаючи кольори, жирний, зашифрований і події натискання. Вони також забезпечують легкий доступ +до системи перекладу, що полегшує переклад будь-якого елемента інтерфейсу +різними мовами. + +Якщо ви раніше працювали з пакетами даних або функціями, ви можете побачити паралелі з текстовим форматом +json, який використовується для показу імен, книг та табличок, і не тільки. Як ти +мабуть, можна здогадатися, це просто представлення json об’єкта `Text`, і його можна +конвертувати в і з використанням `Text.Serializer`. + +Коли створюєте мод, зазвичай краще створювати об’єкти `Текст` безпосередньо +у коді, використовуючи переклади, коли це можливо. + +## Текстові літерали {#text-literals} + +Найпростіший спосіб створити об’єкт `Текст` — створити літерал. Це просто рядок +який промальовуватиме як є, за замовчуванням без жодного форматування. + +Вони створюються за допомогою методів `Text.of` або `Text.literal`, які обидва діють трохи +інакше. `Text.of` приймає нульові значення як вхідні дані та повертає екземпляр `Text`. На відміну від цього, `Text.literal` не має мати значення null, але повертає `MutableText`, +це підклас `Text`, який можна легко стилізувати та об'єднувати. Детальніше про +це пізніше. + +```java +Text literal = Text.of("Hello, world!"); +MutableText mutable = Text.literal("Hello, world!"); +// Keep in mind that a MutableText can be used as a Text, making this valid: +Text mutableAsText = mutable; +``` + +## Можливість перекладати {#translatable-text} + +Якщо ви хочете надати кілька перекладів для одного рядка тексту, ви можете використовувати метод `Text.translatable` для посилання на ключ перекладу в будь-якому мовному файлі. Якщо ключ не існує, ключ перекладу перетворюється на літерал. + +```java +Text translatable = Text.translatable("my_mod.text.hello"); + +// Similarly to literals, translatable text can be easily made mutable. +MutableText mutable = Text.translatable("my_mod.text.bye"); +``` + +Мовний файл `en_us.json`(для української треба `uk_ua.json`) виглядає так: + +```json +{ + "my_mod.text.hello": "Hello!", + "my_mod.text.bye": "Goodbye :(" +} +``` + +Якщо ви хочете мати можливість використовувати змінні в перекладі, подібно до того, як повідомлення про смерть дозволяють використовувати залучених гравців і предмети в перекладі, ви можете додати зазначені змінні як параметри. Ви можете додати скільки завгодно параметрів. + +```java +Text translatable = Text.translatable("my_mod.text.hello", player.getDisplayName()); +``` + +Ви можете посилатися на ці змінні в перекладі так: + +```json +{ + "my_mod.text.hello": "%1$s said hello!" +} +``` + +У грі %1\$s буде замінено іменем гравця, якого ви згадали в коді. Використання `player.getDisplayName()` зробить так, що додаткова інформація про сутність з’явиться у спливаючій підказці під час наведення вказівника мишки на ім’я в повідомленні чату, на відміну від використання `player.getName()`, який все одно отримає назву; однак він не відображатиме додаткових деталей. Подібне можна зробити з itemStacks, використовуючи `stack.toHoverableText()`. + +Щодо того, що взагалі означає %1\$s, все, що вам справді потрібно знати, це те, що число відповідає змінній, яку ви намагаєтеся використати. Припустімо, у вас є три змінні, які ви використовуєте. + +```java +Text translatable = Text.translatable("my_mod.text.whack.item", victim.getDisplayName(), attacker.getDisplayName(), itemStack.toHoverableText()); +``` + +Якщо ви хочете вказати, хто в нашому випадку є зловмисником, ви б використовували %2\$s, оскільки це друга змінна, яку ми передали. Так само %3\$s посилається на itemStack. Переклад із такою кількістю додаткових параметрів може виглядати так: + +```json +{ + "my_mod.text.whack.item": "%1$s was whacked by %2$s using %3$s" +} +``` + +## Серіалізація тексту {#serializing-text} + + + +Як згадувалося раніше, ви можете серіалізувати текст у JSON за допомогою текстового кодека. Додаткову інформацію про кодеки див. на сторінці [Codec](./codecs). + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +Це створює JSON, який можна використовувати в пакетах даних, командах та інших місцях, які приймають формат тексту JSON замість літерального або перекладаного тексту. + +## Десеріалізація тексту {#deserializing-text} + +Крім того, щоб десеріалізувати текстовий об’єкт JSON у фактичний клас `Text`, знову скористайтеся кодеком. + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +## Форматування тексту {#formatting-text} + +Ви можете бути знайомі зі стандартами форматування Minecraft: + +Ви можете застосувати ці форматування за допомогою переліку `Formatting` у класі `MutableText`: + +```java +MutableText result = Text.literal("Hello World!") + .formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE); +``` + + + + + + + + + + + + + + + + + + + + + + + + + +
КолірНазваЧат-кодКод MOTDHex код
Чорний (black)§0\u00A70#000000
Темно-синій (dark_blue)§1\u00A71#0000AA
Темно-зелений (dark_green)§2\u00A72#00AA00
Темно-водянистий (dark_aqua)§3\u00A73#00AAAA
Багряний (dark_red)§4\u00A74#AA0000
Темно-фіолетовий (dark_purple)§5\u00A75#AA00AA
Золотий (gold)§6\u00A76#FFAA00
Сірий (gray)§7\u00A77#AAAAAA
Темно-сірий (dark_gray)§8\u00A78#555555
Синій (blue)§9\u00A79#5555FF
Зелений (green)§a\u00A7a#55FF55
Водянистий (aqua)§b\u00A7b#55FFFF
Червоний (red)§c\u00A7c#FF5555
Світло-фіолетовий (light_purple)§d\u00A7d#FF55FF
Жовтий (yellow)§e\u00A7e#FFFF55
Білий (white)§f\u00A7f#FFFFFF
Скидання форматування§r
Жирний§l
Зачеркнутий§m
Підкреслений§n
<0>Курсив§o
Зашифрований§k
diff --git a/versions/1.21/translated/uk_ua/index.md b/versions/1.21/translated/uk_ua/index.md new file mode 100644 index 000000000..5d4fa9b71 --- /dev/null +++ b/versions/1.21/translated/uk_ua/index.md @@ -0,0 +1,21 @@ +--- +title: Документація Fabric +description: Офіційна документація для Fabric, інструментарію модифікацій для Minecraft. +layout: home +hero: + name: Документація Fabric + tagline: Офіційна документація для Fabric, інструментарію модифікацій для Minecraft. +features: + - title: Посібник для гравців + icon: 📚 + details: Ви гравець що хоче використовувати моди для Fabric? Наш посібник для гравців допоможе вам. Цей посібник допоможе вам в завантаженні, використовувати та виправляти неполадки модів Fabric. + link: /uk_ua/players/ + linkText: Читати більше + - title: Посібник для розробників + icon: 🛠️ + details: Наші посібники для розробників, написані спільнотою, охоплюють все - від налаштування середовища розробки до просунутих тем, таких як промальовування та робота мережі. + link: /uk_ua/develop/ + linkText: Розпочати +--- + +Якщо ви хочете зробити свій внесок у документацію Fabric, ви можете знайти вихідний код на [GitHub](https://github.com/FabricMC/fabric-docs), а також відповідні [правила внеску](./contributing). diff --git a/versions/1.21/translated/uk_ua/players/faq.md b/versions/1.21/translated/uk_ua/players/faq.md new file mode 100644 index 000000000..a7b8676ba --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/faq.md @@ -0,0 +1,29 @@ +--- +title: Поширені питання +description: Поширені запитання для гравців і адміністраторів серверів, пов’язані з Fabric. +--- + +# Часті запитання {#faq} + +Є багато запитань, які часто задають, тому ми склали їх список тут. + +## Які версії Minecraft підтримує Fabric? {#what-minecraft-versions-does-fabric-support} + +Офіційно Fabric підтримує всі версії Minecraft, починаючи зі знімку `18w43b` і вище, а також релізів `1.14` і вище. + +## Де я можу завантажити опубліковані моди Fabric? {#where-can-i-download-published-fabric-mods} + +:::info +Ви завжди маєте перевіряти чи моди з надійного джерела. Перегляньте посібник [пошуку надійних модів](./finding-mods), щоб дізнатися більше. +::: + +Більшість авторів публікують свої моди на [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) та [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4) сторінки або інші платформи, такі як репозиторії GitHub. + +## Де я можу знайти готові збірки модів для Fabric? {#where-can-i-find-premade-fabric-modpacks} + +Ви можете знайти готові збірки модів для Fabric на платформах, таких як: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/uk_ua/players/finding-mods.md b/versions/1.21/translated/uk_ua/players/finding-mods.md new file mode 100644 index 000000000..0c384eed8 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: Пошук надійних модів +description: Інструкція із пошуку модів Fabric за допомогою надійних джерел. +authors: + - IMB11 +--- + +# Пошук надійних модів {#finding-mods} + +По-перше, довіра суб’єктивна, і ви завжди повинні керуватися власним судженням, завантажуючи моди. Однак є деякі речі, які ви можете зробити, щоб допомогти вам знайти надійні моди. + +## 1. Використовуйте джерело, яке заслуговує довіри {#trustworthy- + +Більшість авторів публікують свої моди на [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) та [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4). + +Ці сторінки перевіряють, чи моди є такими, якими вони є, і що вони не містять шкідливого коду. Ви також можете повідомити про шкідливі моди на цих сторінках, і вони відносно швидко вживуть заходів. + +## 2. Зверніться до інших! {#with-others} + +Якщо ви завантажуєте мод з джерела, яке, як відомо, не заслуговує довіри, вам слід перевірити в інших, чи завантажували вони моди раніше з того місця, звідки ви завантажуєте, і чи виникали у них проблеми з цим. + +Якщо ви сумніваєтесь, ви завжди можете запитати в [Discord Fabric](https://discord.gg/v6v4pMv) в каналі `#player-support`. + +## 3. Уникайте поширених сторінок зі шкідливим програмним забезпеченням! {#avoid-malware} + +:::info +Подібні сайти можуть бути не очевидними для всіх. Якщо ви не впевнені, ви можете запитати думки інших або покладатися лише на перевірені джерела, такі як Modrinth та Curseforge. +::: + +Існує багато сторінок, які стверджують, що мають моди для Minecraft, але насправді це лише сайти з вірусами. Вам слід оминати подібні сторінки. + +Ви можете використовувати антивіруси або сторінки, такі як [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) або [VirusTotal](https://www.virustotal.com/) щоб перевіряти завантажені моди. Але не покладайтеся повністю на них, тому що вони не завжди коректні. + +Знову ж таки, якщо ви сумніваєтеся, ви можете запитати в [Discord Fabric](https://discord.gg/v6v4pMv) в каналі `#player-support`. diff --git a/versions/1.21/translated/uk_ua/players/index.md b/versions/1.21/translated/uk_ua/players/index.md new file mode 100644 index 000000000..85dfa1a75 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/index.md @@ -0,0 +1,12 @@ +--- +title: Посібники для гравців +description: Посібник по встановленню та використанню Fabric для гравців та адміністраторів серверів. +--- + +# Посібники для гравців {#player-guides} + +Ця секція документації Fabric присвячена гравцям та адміністраторам серверів які хочуть навчитися встановлювати, використовувати та виправляти неполадки Fabric. + +Перегляньте список усіх доступних інструкцій на бічній панелі. + +Якщо у вас виникли проблеми, повідомте про них [на GitHub](https://github.com/FabricMC/fabric-docs) або зверніться по допомогу в [Discord Fabric](https://discord.gg/v6v4pMv) у канали `#player-support` або `#server-admin-support`. diff --git a/versions/1.21/translated/uk_ua/players/installing-fabric.md b/versions/1.21/translated/uk_ua/players/installing-fabric.md new file mode 100644 index 000000000..1634942ae --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/installing-fabric.md @@ -0,0 +1,59 @@ +--- +title: Встановлення Fabric +description: Покрокова інструкція зі встановлення Fabric. +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# Встановлення Fabric {#installing-fabric} + + + +Цей посібник стосується лише офіційного запускача Minecraft. Для запускачів сторонніх розробників слід ознайомитися з їх документацією. + +## 1. Завантажте встановлювач Fabric {#1-download-the-fabric-installer} + +Ви можете завантажити встановлювач Fabric зі [сторінки Fabric](https://fabricmc.net/use/). + +Якщо ви користуєтеся Windows, завантажте версію `.exe` (`Download For Windows`), оскільки для цього не потрібно встановлювати Java у вашій системі. Натомість він використовує Java, яка постачається з офіційним запускачем. + +Для macOS та Linux вам слід завантажити `jar` версію. Іноді перед цим кроком потрібно встановити Java. + +## 2. Запустіть встановлювач Fabric {#2-run-the-fabric-installer} + +:::warning +Перш ніж запустити встановлювач, закрийте Minecraft і запускач Minecraft. +::: + +:::details Інформація для користувачів MacOS + +У macOS вам може знадобитися натиснути ПКМ по файлу `.jar` у каталозі завантажень і натиснути `Відкрити`, щоб запустити його. + +![Контекстне меню MacOS у Fabric Installer](/assets/players/installing-fabric/macos-downloads.png) + +Коли вас запитають «Ви впевнені, що хочете відкрити?», знову натисніть `Відкрити`. +::: + +Відкривши встановлювач, ви повинні побачити такий екран: + +![Встановлювач Fabric із виділеним «встановити»](/assets/players/installing-fabric/installer-screen.png) + + + +Щоб установити Fabric, просто виберіть свою версію гри зі спадного меню та натисніть «встановити». + +:::warning ВАЖЛИВО +Переконайтеся, що позначено «Створити профіль». +::: + +## 3. Готово! {#3-you-re-done} + +Після завершення встановлення ви можете відкрити запускач Minecraft і вибрати профіль Fabric зі спадного списку в нижньому лівому куті та натиснути грати! + +![Запускач Minecraft з вибраним профілем Fabric](/assets/players/installing-fabric/launcher-screen.png) + +Тепер, коли ви встановили Fabric, ви можете додавати моди у свою гру! Перегляньте посібник [пошуку надійних модів](./finding-mods), щоб дізнатися більше. + +Якщо під час виконання цього посібника у вас виникнуть проблеми, ви можете звернутися за допомогою до [Fabric Discord](https://discord.gg/v6v4pMv) на каналі `#player-support`. diff --git a/versions/1.21/translated/uk_ua/players/installing-java/linux.md b/versions/1.21/translated/uk_ua/players/installing-java/linux.md new file mode 100644 index 000000000..026072e67 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: Встановлення Java у Linux +description: Покрокова інструкція щодо встановлення Java у Linux. +authors: + - IMB11 +--- + +# Встановлення Java у Linux {#installing-java-on-linux} + +Цей посібник допоможе вам встановити Java 21 на Linux. + +## 1. Перевірте, чи Java вже встановлено {#1-check-if-java-is-already-installed} + +Відкрийте термінал, введіть `java -version` і натисніть <0>Enter. + +![Термінал із введеним "java -version"](/assets/players/installing-java/linux-java-version.png) + +:::warning +Щоб використовувати Minecraft 1.21, вам знадобиться встановити принаймні Java 21. Якщо ця команда показує будь-яку версію, нижчу за 21, вам потрібно буде оновити встановлювач Java. +::: + +## 2. Завантажити встановлювач Java 21 {#2-downloading-and-installing-java} + +Ми рекомендуємо використовувати OpenJDK 21, який доступний для більшості дистрибутивів Linux. + +### Arch Linux {#arch-linux} + +:::info +Щоб отримати додаткові відомості про встановлення Java на Arch Linux, перегляньте [Arch Linux Wiki](https://wiki.archlinux.org/title/Java). +::: + +Ви можете встановити останню версію JRE з офіційних репозиторіїв: + +```sh +sudo pacman -S jre-openjdk +``` + +Якщо ви працюєте на сервері без графічного інтерфейсу, замість цього можна встановити версію headless: + +```sh +sudo pacman -S jre-openjdk-headles +``` + +Якщо ви плануєте розробляти моди, замість цього вам знадобиться JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu {#debian-ubuntu} + +You can install Java 21 using `apt` with the following commands: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora {#fedora} + +Ви можете встановити Java 21 за допомогою `dnf` за допомогою таких команд: + +```sh +sudo dnf install java-21-openjdk +``` + +Якщо вам не потрібен графічний інтерфейс, ви можете замість нього встановити версію headless: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +Якщо ви плануєте розробляти моди, замість цього вам знадобиться JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### Інші дистрибутиви Linux {#other-linux-distributions} + +Якщо вашого дистрибутиву немає в списку вище, ви можете завантажити останню версію JRE з [Adoptium](https://adoptium.net/temurin/) + +Вам слід звернутися до альтернативного посібника для вашого дистрибутиву, якщо ви плануєте розробляти моди. + +## 3. Перевірте, чи встановлено Java 21 {#3-verify-that-java-is-installed} + +Перевірте, чи встановлено Java 21 {#3-verify-that-java-is-installed}. + +Якщо команда виконана успішно, ви побачите щось подібне до показаного раніше, де показана версія Java: + +![Термінал із введеним "java -version"](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/uk_ua/players/installing-java/windows.md b/versions/1.21/translated/uk_ua/players/installing-java/windows.md new file mode 100644 index 000000000..090d82c56 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: Встановлення Java у Windows +description: Покрокова інструкція щодо встановлення Java на Windows. +authors: + - IMB11 +--- + +# Встановлення Java у Windows {#installing-java-on-windows} + +Інструкція по тому як встановити Java 21 у Windows. + +Запускач Minecraft постачається з власною інсталяцією Java, тому цей розділ актуальний, лише якщо ви хочете використовувати встановлювач на основі Fabric `.jar` або якщо ви хочете використовувати сервер Minecraft `.jar`. + +## 1. Перевірте, чи Java уже встановлено {#1-check-if-java-is-already-installed} + +Щоб перевірити, чи Java вже встановлено, потрібно спочатку відкрити командний рядок. + +Ви можете зробити це, натиснувши <0>Win <0>R і ввівши `cmd.exe` у поле, що з’явиться. + +![Діалогове вікно запуску Windows із "cmd.exe" на панелі запуску](/assets/players/installing-java/windows-run-dialog.png) + +Відкривши командний рядок, введіть `java -version` і натисніть <0>Enter. + +Якщо команда виконана успішно, ви побачите щось подібне. Якщо команда не вдалася, перейдіть до наступного кроку. + +![Командний рядок із введеним "java -version"](/assets/players/installing-java/windows-java-version.png) + +:::warning +Щоб використовувати Minecraft 1.21, вам знадобиться встановити принаймні Java 21. Якщо ця команда показує будь-яку версію, нижчу за 21, вам потрібно буде оновити встановлювач Java. +::: + +## 2. Завантажити завантажувач Java 21 {#2-download-the-java-installer} + +Щоб установити Java 21, вам потрібно буде завантажити програму встановлення з [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21). + +Ви захочете завантажити версію `Windows Installer (.msi)`: + +![Сторінка завантаження Adoptium із виділеним встановлювачем Windows (.msi)](/assets/players/installing-java/windows-download-java.png) + +Вам слід вибрати «x86», якщо у вас 32-розрядна операційна система, або «x64», якщо у вас 64-розрядна операційна система. + +Більшість сучасних комп’ютерів матиме 64-розрядну операційну систему. Якщо ви не впевнені, спробуйте скористатися 64-розрядним завантаженням. + +## 3. Запустіть встановлювач! {#3-run-the-installer} + +Виконайте кроки встановлювача, щоб встановити Java 21. Коли ви перейдете на цю сторінку, ви повинні встановити такі функції на «Уся функція буде встановлена ​​на локальному жорсткому диску»: + +- `Установити змінну середовища JAVA_HOME` - її буде додано до вашого ШЛЯХУ. +- `JavaSoft (Oracle) registry keys` + +![Встановлювач Java 21 із виділеними параметрами «Встановити змінну JAVA\_HOME» і «ключами реєстру JavaSoft (Oracle)»](/assets/players/installing-java/windows-wizard-screenshot.png) + +Зробивши це, ви можете натиснути `Next` і продовжити встановлення. + +## 4. Перевірте, чи встановлено Java 21 {#4-verify-that-java-is-installed} + +Після завершення встановлення ви можете переконатися, що Java 21 встановлено, знову відкривши командний рядок і ввівши `java -version`. + +Якщо команда виконана успішно, ви побачите щось подібне до показаного раніше, де показана версія Java: + +![Командний рядок із введеним "java -version"](/assets/players/installing-java/windows-java-version.png) + +--- + +Якщо у вас виникнуть проблеми, не соромтеся звертатися по допомогу до [Fabric Discord](https://discord.gg/v6v4pMv) на каналі #player-support. diff --git a/versions/1.21/translated/uk_ua/players/installing-mods.md b/versions/1.21/translated/uk_ua/players/installing-mods.md new file mode 100644 index 000000000..ea6ae7bb4 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Встановлення модів +description: Покрокова інструкція по установці модів для Fabric. +authors: + - IMB11 +--- + +# Установлення модів {#installing-mods} + +Ця інструкція допоможе вам встановити моди для Fabric якщо ви використовуєте запускач Minecraft. + +Для запускачів сторонніх розробників слід ознайомитися з їх документацією. + +## 1. Завантаження мода {#1-download-the-mod} + +:::warning +Ви повинні завантажувати моди тільки з джерел, яким ви довіряєте. Додаткову інформацію про пошук модів див. у посібнику [пошуку надійних модів](./finding-mods). +::: + +Більшість модів також потребує Fabric API, що може бути завантажено з [Modrinth](https://modrinth.com/mod/fabric-api) або [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api). + +При завантаженні модів переконайтеся, що: + +- Вони працюють з версією Minecraft, на якій ви хочете грати. Наприклад, мод що працює на версії 1.20, може не працювати на версії 1.20.2. +- Вони призначені для Fabric, а не для іншого завантажувача модів. +- Вони призначені для правильної версії Minecraft (Java Edition). + +## 2. Перемістіть мод до теки `mods` {#2-move-the-mod-to-the-mods-folder} + +Теку mods можна знайти в наступних місцях для кожної операційної системи. + +Зазвичай ви можете вставити ці шляхи в адресний рядок провідника файлів, щоб швидко перейти до теки. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Коли ви знайдете теку `mods`, ви можете перемістити туди файли `.jar` мода. + +![Встановлені моди в теці mods](/assets/players/installing-mods.png) + +## 3. Готово! {#3-you-re-done} + +Після встановлення модів в теку `mods` ви можете відкрити запускач Minecraft і вибрати профіль Fabric зі спадного списку в нижньому лівому куті та натиснути грати! + +![Запускач Minecraft з вибраним профілем Fabric](/assets/players/installing-fabric/launcher-screen.png) + +## Усунення несправностей {#troubleshooting} + +Якщо під час виконання цієї інструкції у вас виникнуть проблеми, ви можете звернутися за допомогою в [Discord Fabric](https://discord.gg/v6v4pMv) в каналі `#player-support`. + +Ви також можете спробувати розв'язувати проблему самостійно, прочитавши сторінки усунення несправностей: + +- [Звіти про збої](./troubleshooting/crash-reports) +- [Завантаження журналів](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/uk_ua/players/troubleshooting/crash-reports.md b/versions/1.21/translated/uk_ua/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..4d1ba6834 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: Звіти про збої +description: Дізнайтеся, що робити зі звітами про збої та як їх читати. +authors: + - IMB11 +--- + +# Звіти про збої {#crash-reports} + +:::tip +Якщо у вас виникли труднощі з пошуком причини збою, ви можете звернутися за допомогою до [Discord Fabric](https://discord.gg/v6v4pMv) в каналах `#player-support` або `#server-admin-support`. +::: + +Звіти про збої є дуже важливою частиною усунення проблем із грою чи сервером. Вони містять багато інформації про збій і можуть допомогти вам знайти причину збою. + +## Пошук звітів про збої {#finding-crash-reports} + +Звіти про збої зберігаються в теці `crash-reports` у каталозі гри. Якщо ви використовуєте сервер, вони зберігаються в теці `crash-reports` у каталозі сервера. + +Для неофіційних запускачів слід ознайомитися з їх документацією пошуку звітів. + +Звіти про збої можна знайти в таких місцях: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## Читання звітів про збої {#reading-crash-reports} + +Звіти про збої величезні, і читати їх може бути дуже заплутано і нудно. Однак вони містять багато інформації про збій і можуть допомогти вам знайти причину збою. + +Для цього посібника ми будемо використовувати [цей звіт про збої](/assets/players/crash-report-example.txt). + +:::details Показати звіт про збої + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### Розділи звіту про збої {#crash-report-sections} + +Звіти про збої складаються з кількох розділів, кожен розділений заголовком: + +- `---- Minecraft Crash Report ----`, резюме доповіді. Цей розділ міститиме основну помилку, яка спричинила збій, час її виникнення та відповідне трасування стосу. Це найважливіший розділ звіту про збій, оскільки трасування стосу зазвичай може містити посилання на мод, який спричинив збій. +- `-- Last Reload --`, цей розділ не дуже корисний, якщо збій не стався під час перезавантаження ресурсів (F3 T). Цей розділ міститиме час останнього перезавантаження та відповідне трасування стосу будь-яких помилок, які виникли під час процесу перезавантаження. Ці помилки зазвичай викликані пакетами ресурсів, і їх можна ігнорувати, якщо вони не спричиняють проблеми з грою. +- `-- System Details --`, цей розділ містить інформацію про вашу систему, таку як операційна система, версія Java та обсяг пам'яті, виділеної для гри. Цей розділ корисний, щоб визначити, чи ви використовуєте правильну версію Java і чи виділили ви достатньо пам’яті для гри. + - У цьому розділі Fabric містить спеціальний рядок «Fabric Mods:», а потім список усіх модів, які ви встановили. Цей розділ корисний для визначення того, чи могли виникнути конфлікти між модами. + +### Розбір звіту про збої {#breaking-down-the-crash-report} + +Тепер, коли ми знаємо, що таке кожен розділ звіту про збій, ми можемо почати розбирати звіт про збій і знайти причину збою. + +Використовуючи наведений вище приклад, ми можемо проаналізувати звіт про збій і знайти причину збою, включно з модами, які спричинили збій. + +Трасування стосу в розділі `---- Minecraft Crash Report ----` є найважливішим у цьому випадку, оскільки воно містить основну помилку, яка спричинила збій. + +:::details Показати помилку + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +Через кількість модів, згаданих у трасуванні стосу, може бути важко вказати пальцем, але перше, що потрібно зробити, це знайти мод, який спричинив збій. + +У цьому випадку модом, який спричинив збій, є `snownee`, оскільки це перший мод, згаданий у трасуванні стосу. + +Однак, враховуючи кількість згаданих модів, це може означати, що існують певні проблеми сумісності між модами, і мод, який спричинив збій, може бути не тим модом, який є несправним. У цьому випадку найкраще повідомити про збій автору мода, і нехай вони розслідують збій. + +## Збій міксинів {#mixin-crashes} + +:::info +Міксини — це спосіб модифікувати гру без необхідності змінювати вихідний код гри. Вони використовуються багатьма модами та є дуже потужним інструментом для розробників модів. +::: + +Коли міксин виходить з ладу, він зазвичай згадує міксин у трасуванні стосу та клас, який міксин модифікує. + +Міксини методів міститимуть `modid$handlerName` у трасуванні стека, де `modid` — це ідентифікатор мода, а `handlerName` — це ім’я обробника міксину. + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +Ви можете використовувати цю інформацію, щоб знайти мод, який спричинив збій, і повідомити про збій автору моду. + +## Що робити зі звітами про збої {#what-to-do-with-crash-reports} + +Найкраще, що можна зробити зі звітами про збої, це завантажити їх на сторінку для вставлення, а потім поділитися посиланням з автором моду, або на його трекерах проблем, або через будь-яку форму зв’язку (Discord тощо). + +Це дозволить автору моду дослідити збій, потенційно відтворити його та розв'язувати проблему, яка його спричинила. + +Поширені сторінки вставки, які часто використовуються для звітів про збої: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/uk_ua/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/uk_ua/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..fd16590a6 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: Вивантаження звітів +description: Як вивантажити звіти для усунення несправностей. +authors: + - IMB11 +--- + +# Вивантаження журналів {#uploading-logs} + +Під час усунення проблем часто необхідно надати журнали, щоб допомогти визначити причину проблеми. + +## Чому я повинен завантажувати журнали? {#why-should-i-upload-logs} + +Завантаження журналів дозволяє іншим допомогти вам розв'язувати ваші проблеми набагато швидше, ніж просто вставляти журнали в чат або повідомлення на форумі. Це також дозволяє вам ділитися своїми журналами з іншими без необхідності копіювати та вставляти їх. + +Деякі сторінки вставлення також надають підсвічування синтаксису для журналів, що полегшує їх читання, і може цензурувати конфіденційну інформацію, таку як ваше ім’я користувача або інформацію про систему. + +## Звіти про збої {#crash-reports} + +Звіти про збої створюються автоматично, коли гра виходить з ладу. Вони містять лише інформацію про збої, а не журнали гри. Вони знаходяться в теці `crash-reports` в каталозі гри. + +Додаткову інформацію про звіти про збої див. у [звіти про збої](./crash-reports). + +## Пошук журналів {#locating-logs} + +У цьому посібнику описано офіційний запускач Minecraft (зазвичай відомий як «ванілльний запускач») — для програм запуску сторонніх розробників слід ознайомитися з їх документацією. + +Журнали знаходяться в теці `logs` в каталозі гри, каталог гри можна знайти в таких місцях залежно від вашої операційної системи: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +Останній журнал називається `latest.log`, а попередні журнали використовують шаблон іменування `yyyy-mm-dd_number.log.gz`. + +## Завантаження журналів онлайн {#uploading-logs-online} + +Звіти можуть бути вивантажені на різноманітні сервіси, таких як: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/uk_ua/players/updating-fabric.md b/versions/1.21/translated/uk_ua/players/updating-fabric.md new file mode 100644 index 000000000..2b2dc0682 --- /dev/null +++ b/versions/1.21/translated/uk_ua/players/updating-fabric.md @@ -0,0 +1,41 @@ +--- +title: Оновлення Fabric +description: Покрокова інструкція з оновлення Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Оновлення Fabric {#updating-fabric} + +Ця інструкція допоможе вам оновити Fabric для офіційного запускача Minecraft. + +Для програм запуску сторонніх розробників слід ознайомитися з їх документацією. + +Процес оновлення Fabric дуже схожий на процес встановлення Fabric, тому частини цього посібника будуть такими самими, як і посібник [Встановлення Fabric](./installing-fabric). + +## Чому я повинен оновлювати Fabric Loader? {#why-should-i-update-fabric-loader} + +Нові моди можуть потребувати новішу версію Fabric Loader для роботи, тому важливо мати актуальну версію, щоб мати можливість використовувати найновіші моди. + + + +Щоб оновити Fabric, просто переконайтеся, що версія гри та версія завантажувача правильні, а потім натисніть «Встановити». + +:::warning ВАЖЛИВО +Під час запуску встановлювача обов’язково зніміть прапорець «Створити профіль», інакше буде створено новий профіль, який у цьому випадку нам не потрібен. +::: + +## 3. Відкрийте профіль у запускачі Minecraft {#3-open-the-profile-in-the-minecraft-launcher} + +Після завершення встановлення ви можете відкрити запускач Minecraft і перейти у вкладку «Встановлення». Ви повинні перейти до свого профілю Fabric і відкрити екран редагування. + +Замініть версію новою версією Fabric Loader, яку ви щойно встановили, і натисніть «Зберегти». + +![Оновлення версії Fabric Loader у програмі запуску Minecraft](/assets/players/updating-fabric.png) + +## 4. Готово! {#4-you-re-done} + +Виконавши кроки, ви можете повернутися на вкладку `Play`, вибрати профіль Fabric зі спадного меню в нижньому лівому куті та натиснути кнопку грати! + +Якщо під час виконання цього посібника у вас виникнуть проблеми, ви можете звернутися за допомогою до [Fabric Discord](https://discord.gg/v6v4pMv) на каналі `#player-support`. diff --git a/versions/1.21/translated/uk_ua/sidebar_translations.json b/versions/1.21/translated/uk_ua/sidebar_translations.json new file mode 100644 index 000000000..a3def895f --- /dev/null +++ b/versions/1.21/translated/uk_ua/sidebar_translations.json @@ -0,0 +1,71 @@ +{ + "players.title": "Посібник для гравців", + "players.faq": "Поширені питання", + "players.installingJava": "Встановлення Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Встановлення Fabric", + "players.findingMods": "Пошук надійних модів", + "players.installingMods": "Встановлення модів", + "players.troubleshooting": "Усунення проблем", + "players.troubleshooting.uploadingLogs": "Поширення логів", + "players.troubleshooting.crashReports": "Звіти про збої", + "players.updatingFabric": "Оновлення Fabric", + "develop.title": "Посібник для розробників", + "develop.gettingStarted": "Перші кроки", + "develop.gettingStarted.introduction": "Знайомство з Fabric та створенням модів", + "develop.gettingStarted.devEnvSetup": "Налаштовування середовища розробки", + "develop.gettingStarted.creatingProject": "Створення проєкту", + "develop.gettingStarted.projectStructure": "Структура проєкту", + "develop.gettingStarted.launchGame": "Запуск гри", + "develop.gettingStarted.solvingProblems": "Базове розв'язування задач", + "develop.items": "Предмети", + "develop.items.first-item": "Створення ваших перших предметів", + "develop.items.food": "Їжа", + "develop.items.custom-armor": "Власні обладунки", + "develop.items.custom-tools": "Власні інструменти", + "develop.items.custom-item-groups": "Власні групи предметів", + "develop.items.custom-item-interactions": "Власні інтерактивні предмети", + "develop.items.custom-enchantment-effects": "Власні ефекти зачарувань", + "develop.items.potions": "Зілля", + "develop.items.custom-data-components": "Власні компоненти даних", + "develop.blocks": "Блоки", + "develop.blocks.first-block": "Створення ваших перших блоків", + "develop.blocks.blockstates": "Стани блоку", + "develop.blocks.block-entities": "Блоки-сутності", + "develop.blocks.block-entity-renderer": "Промальовування блоків-сутностей", + "develop.entities": "Істоти", + "develop.entities.effects": "Ефекти", + "develop.entities.damage-types": "Типи ушкоджень", + "develop.commands": "Команди", + "develop.commands.basics": "Створення команд", + "develop.commands.arguments": "Аргументи", + "develop.commands.suggestions": "Пропозиції", + "develop.dataGeneration": "Генерація даних", + "develop.dataGeneration.setup": "Налаштування генерації даних", + "develop.dataGeneration.tags": "Генерація теґів", + "develop.dataGeneration.translations": "Генерація перекладу", + "develop.dataGeneration.advancements": "Генерація досягнень", + "develop.dataGeneration.recipes": "Генерація рецептів", + "develop.dataGeneration.lootTables": "Генерація таблиць здобичі", + "develop.rendering": "Промальовування", + "develop.rendering.basicConcepts": "Базові концепції промальовування", + "develop.rendering.drawContext": "Використання DrawContext", + "develop.rendering.hud": "Промальовування інтерфейсу гри", + "develop.rendering.gui": "Графічні інтерфейси та екрани", + "develop.rendering.gui.customScreens": "Власні екрани", + "develop.rendering.gui.customWidgets": "Власні віджети", + "develop.rendering.particles": "Частинки", + "develop.rendering.particles.creatingParticles": "Створення власних частинок", + "develop.misc": "Інші сторінки", + "develop.misc.codecs": "Кодеки", + "develop.misc.events": "Події", + "develop.misc.text-and-translations": "Текст і переклади", + "develop.misc.ideTipsAndTricks": "Поради та підказки IDE", + "develop.misc.automatic-testing": "Автотестування", + "develop.sounds": "Звуки", + "develop.sounds.using-sounds": "Відтворення звуків", + "develop.sounds.custom": "Створення власних звуків", + "develop.sounds.dynamic-sounds": "Динамічні звуки" +} diff --git a/versions/1.21/translated/uk_ua/website_translations.json b/versions/1.21/translated/uk_ua/website_translations.json new file mode 100644 index 000000000..fe93a1e73 --- /dev/null +++ b/versions/1.21/translated/uk_ua/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "Автори сторінок", + "authors.nogithub": "%s (не на GitHub)", + "banner": "Fabric документація знаходиться в процесі розробки. Повідомляйте про проблеми на %s або на %s.", + "description": "Повна документація для Fabric, інструментарію для створення модів Minecraft.", + "download": "Завантажити %s", + "footer.next": "Наступна сторінка", + "footer.prev": "Попередня сторінка", + "github_edit": "Редагуйте цю сторінку на GitHub", + "lang_switcher": "Змінити мову", + "last_updated": "Останнє оновлення", + "mode_dark": "Встановити темну тему", + "mode_light": "Встановити світлу тему", + "mode_switcher": "Зовнішній вигляд", + "nav.contribute": "Зробити внесок", + "nav.contribute.api": "Fabric API", + "nav.download": "Завантажити", + "nav.home": "Головна", + "outline": "На цій сторінці", + "return_to_top": "Повернутися нагору", + "search.back": "Закрити пошук", + "search.button": "Пошук", + "search.display_details": "Показати детальний список", + "search.footer.close": "закрити", + "search.footer.close.key": "Вихід", + "search.footer.down.key": "Стрілка вниз", + "search.footer.navigate": "навігація", + "search.footer.up.key": "Стрілка вгору", + "search.footer.select": "вибрати", + "search.footer.select.key": "Ввід", + "search.no_results": "Немає результатів для", + "search.reset": "Скинути пошук", + "sidebar_menu": "Меню", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Документація Fabric", + "version.reminder": "Ця сторінка написана для версії:", + "version.switcher": "Змінити версію", + "404.code": "404", + "404.crowdin_link": "Локалізуйте на Crowdin", + "404.crowdin_link.label": "Відкрити редактор Crowdin", + "404.english_link": "Читати англійською", + "404.english_link.label": "Відкрити Англійську версію", + "404.link": "На головну", + "404.link.label": "Перейти на домашню сторінку", + "404.quote": "Ця сторінка намагалася плавати лаві", + "404.title": "Сторінку не знайдено" +} diff --git a/versions/1.21/translated/vi_vn/contributing.md b/versions/1.21/translated/vi_vn/contributing.md new file mode 100644 index 000000000..a787ceed0 --- /dev/null +++ b/versions/1.21/translated/vi_vn/contributing.md @@ -0,0 +1,176 @@ +# Tài Liệu Hướng Dẫn Cách Đóng Góp Fabric + +Trang này sử dụng [VitePress](https://vitepress.dev/) để tạo văn bản HTML tĩnh từ nhiều tệp markdown khác nhau. Bạn nên làm quen với những tiện ích markdown mà VitePress hỗ trợ tại [đây](https://vitepress.dev/guide/markdown#features). + +## Mục Lục + +- [Tài Liệu Hướng Dẫn Cách Đóng Góp Fabric](#tài-liệu-hướng-dẫn-cách-đóng-góp-fabric) + - [Cách Đóng Góp](#cách-đóng-góp) + - [Đóng Góp Framework](#đóng-góp-framework) + - [Đóng Góp Nội Dung](#đóng-góp-nội-dung) + - [Phong Cách Ghi Tài Liệu](#phong-cách-ghi-tài-liệu) + - [Hướng Dẫn Mở Rộng](#hướng-dẫn-mở-rộng) + - [Xác Minh Nội Dung](#xác-minh-nội-dung) + - [Làm Gọn](#làm-gọn) + +## Cách Đóng Góp + +Chúng tôi khuyên bạn nên tạo một nhánh mới trên bản fork của kho lưu trữ cho mỗi lần tạo pull request. Điều này sẽ giúp bạn dễ quản lý khi thực hiện nhiều pull request cùng một lúc. + +**Nếu bạn muốn xem trước những thay đổi bạn tạo trên máy nội bộ của bạn, bạn cần phải cài đặt [Node.js 18+](https://nodejs.org/en/)** + +Trước khi chạy bất kì lệnh nào, hãy đảm bảo chạy lệnh `npm install` để cài đầy đủ các gói hỗ trợ. + +**Chạy máy chủ phát triển nội bộ:** + +Điều này sẽ cho phép bạn xem trước các thay đổi bạn đã làm trên thiết bị của bạn tại địa chỉ `localhost:3000` và sẽ tự động tải lại trang khi bạn thực hiện các thay đổi. + +```sh +npm run dev +``` + +**Xây dựng trang web:** + +Lệnh dưới đây sẽ biên dịch toàn bộ tập tin markdown thành những tệp HTML tĩnh và đặt chúng trong `.vitepress/dist` + +```sh +npm run build +``` + +**Xem trước trang web đã tạo:** + +Lệnh dưới sẽ khởi động một máy chủ nội bộ trên cổng 3000 để hiển thị nội dụng được tìm thấy ở `.vitepress/dist` + +```sh +npm run preview +``` + +## Đóng Góp Framework + +Framework ám chỉ cấu trúc bên trong của một trang web, bất kì pull request nào chỉnh sử framework của trang web nên được đánh dấu với nhãn `framework`. + +Bạn thật sự chỉ nên tạo các pull request về framework sau khi tham khảo ý kiến của đội ngũ biên soạn tài liệu trong [Discord Fabric](https://discord.gg/v6v4pMv) hoặc thông qua trang issue. + +**Chú ý: Việc chỉnh sửa các tập tin thanh bên và thanh định hướng không được tính là một pull request của framework.** + +## Đóng Góp Nội Dung + +Đóng góp nội dung là cách chính để đóng góp vào Tài liệu Fabric. + +Tất cả các nội dung nên theo phong cách ghi tài liệu của chúng tôi. + +### Phong Cách Ghi Tài Liệu + +Tất cả các trang trên trang web bộ tài liệu Fabric nên thống nhất về một phong cách ghi. Nếu bạn không chắc điều gì, bạn có thể hỏi tại [Discord Fabric](https://discord.gg/v6v4pMv) hoặc thông qua mục Discussions của Github. + +Quy định về phong cách như sau: + +1. Tất cả trang phải có tiêu đề và dòng mô tả theo định dạng frontmatter. + + ```md + --- + title: Đây là tiêu đề của trang + description: Đây là dòng mô tả của trang + authors: + - TênNgườiDùngGithub + --- + + # ... + ``` + +2. Nếu bạn muốn tạo hoặc chỉnh sửa đoạn mã của trang, hãy đặt đoạn mã ở một vị trí thích hợp ở trong bản mod có liên quan (được đặt ở thư mục `/reference` của kho lưu trữ). Sau đó, sử dụng [tính năng tạo định nghĩa cho mã được cung cấp bởi VitePress](https://vitepress.dev/guide/markdown#import-code-snippets) để nhúng mã, hoặc nếu bạn cần nhiều sự kiểm soát hơn, bạn có thể sử dụng tính năng transclude từ [`markdown-it-vuepress-code-snippet-enhanced`](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced). + + **Ví dụ:** + + ```md + <<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21 java} + ``` + + Điều này sẽ nhúng mã từ dòng 15 đến 21 của tệp `FabricDocsReference.java` trong tập tin mod có liên quan. + + Kết quả sau khi tạo định nghĩa cho mã sẽ như này: + + ```java + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + LOGGER.info("Hello Fabric world!"); + } + ``` + + **Ví Dụ Về Transclude:** + + ```md + @[code transcludeWith=#test_transclude](@/reference/.../blah.java) + ``` + + Mã trên sẽ nhúng phần được chọn của `blah.java` mà đã được đánh dấu với nhãn `#test_transclude`. + + Ví dụ: + + ```java + public final String test = "Bye World!" + + // #test_transclude + public void test() { + System.out.println("Hello World!"); + } + // #test_transclude + ``` + + Chỉ có phần mã ở giữa nhãn `#test_transclude` mới được nhúng. + + ```java + public void test() { + System.out.println("Hello World!"); + } + ``` + +3. Chúng tôi tuân theo ngữ pháp tiếng Anh. Mặc dù bạn cũng có thể sử dụng công cụ [LanguageTool](https://languagetool.org/) để kiểm tra ngữ pháp khi viết, nhưng đừng quá căng thẳng về điều đó. Đội ngũ biên soạn của chúng tôi sẽ luôn xem xét và sửa lại chúng trong bước làm gọn. Tuy vậy, bạn nên dành gia một chút thời gian kiểm tra từ đầu và điều đó giúp chúng tôi tiết kiệm thêm thời gian. + +4. Nếu bạn đang tạo một mục mới, bạn nên tạo thêm một thanh bên mới trong thư mục `.vitepress/sidebars` và thêm nó trong tệp `config.mts`. Nếu bạn cần sự hỗ trợ để làm điều này, vui lòng hỏi trong kênh `#wiki` ở [Discord Fabric](https://discord.gg/v6v4pMv). + +5. Khi tạo một trang mới, bạn nên thêm nó vào thanh bên nằm ở thư mục `.vitepress/sidebars`. Một lần nữa, nếu bạn cần sự trợ giúp, hãy hỏi ở kênh `#wiki` trong Discord Fabric. + +6. Tât cả hình ảnh nên được đặt ở thư mục `/assets` phù hợp. + +7. ⚠️ **Khi liên kết các trang khác, hãy sử dụng liên kết tương đối.** ⚠️ + + Điều này là do hệ thống lập phiên bản tại chỗ, sẽ xử lý các liên kết để thêm phiên bản trước. Nếu bạn sử dụng liên kết tuyệt đối, số phiên bản sẽ không được thêm vào liên kết. + + Ví dụ, đối với trang ở thư mục `/players`, để liên kết trang `installing-fabric` được tạo ở `/players/installing-fabric.md`, bạn sẽ phải làm như sau: + + ```md + [Đây là liên kết dẫn đến trang khác](./installing-fabric) + ``` + + Bạn **KHÔNG ĐƯỢC** làm như sau: + + ```md + [Đây là liên kết dẫn đến trang khác](/players/installing-fabric) + ``` + +Tất cả sự đóng góp nội dung sẽ lần lượt đi qua ba bước: + +1. Hướng dẫn mở rộng (nếu có thể) +2. Xác Minh Nội Dung +3. Làm gọn (ngữ pháp, ...) + +### Hướng Dẫn Mở Rộng + +Nếu đội ngũ biên soạn nghĩ rằng bạn có thể mở rộng thêm trong pull request của bạn, một thành viên của đội ngũ sẽ thêm nhãn `expansion` cho pull request của bạn cùng với một bình luận giải thích những thứ mà bạn có thể mở rộng thêm nữa. Nếu bạn đồng ý sự đề xuất này, bạn có thể mở rộng thêm pull request của bạn. + +**Cũng đừng cảm thấy quá áp lực khi mở rộng thêm pull request của bạn.** Nếu bạn không muốn mở rộng thêm, bạn có thể yêu cầu xoá nhãn `expansion`. + +Nếu bạn không muốn mở rộng thêm pull request của bạn, nhưng bạn sẵn sàng cho người khác làm điều đó vào lúc sau, điều tốt nhất là hãy tạo một issue trong [trang Issues](https://github.com/FabricMC/fabric-docs/issues) và giải thích những gì mà bạn nghĩ có thể mở rộng thêm. + +### Xác Minh Nội Dung + +Tất cả pull requests mà thêm nội dung đều sẽ trải qua bước xác minh nội dung, đây là bước quan trọng nhất vì nó đảm bảo tất cả nội dung phải chính xác và tuân theo quy định về phong cách ghi Tài liệu Fabric. + +### Làm Gọn + +Đây là giai đoạn mà đội ngũ biên soạn sẽ sửa chữa bất kỳ lỗi ngữ pháp nào được tìm thấy và thực hiện bất kỳ thay đổi nào khác mà họ cho là cần thiết trước khi hợp nhất pull request! diff --git a/versions/1.21/translated/vi_vn/develop/commands/arguments.md b/versions/1.21/translated/vi_vn/develop/commands/arguments.md new file mode 100644 index 000000000..bf55a82f7 --- /dev/null +++ b/versions/1.21/translated/vi_vn/develop/commands/arguments.md @@ -0,0 +1,56 @@ +--- +title: Tham Số Câu Lệnh +description: Học cách tạo ra câu lệnh với tham số phức tạp. +--- + +# Tham Số Câu Lệnh + +Hầu hết các câu lệnh đều có tham số. Nhiều khi tham số đó không bắt buộc, bạn không cần phải đưa vào câu lệnh nhưng nó vẫn chạy. Một node có thể có nhiều loại tham số, nhưng bạn nên tránh xảy ra trường hợp kiểu dữ liệu của tham số không rõ. + +@[code lang=java highlight={3} transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Trong trường hợp này, sau `/argtater`, bạn cần đưa ra một số nguyên làm tham số. Chẳng hạn, khi bạn chạy `/argtater 3`, bạn sẽ nhận được thông báo `Called /argtater with value = 3`. Khị bạn nhập `/argtater` mà không đưa ra tham số, câu lệnh trên sẽ không chạy được. + +Chúng ta có thể thêm vào đối số không bắt buộc thứ hai: + +@[code lang=java highlight={3,13} transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Giờ đây, bạn có thể nhập một hoặc hai số nguyên làm tham số. Nếu bạn đưa vào một số nguyên, bạn sẽ nhận được thông báo với một giá trị. Nếu là hai số nguyên, thông báo sẽ đưa ra hai giá trị. + +Có thể bạn thấy việc viết hai quy trình xử lý dữ liệu giống nhau là không cần thiết. Ta có thể tạo một method sử dụng trong cả hai tham số. + +@[code lang=java highlight={3,5,6,7} transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## Kiểu Tham Số Tùy Chỉnh + +Nếu bạn không tìm thấy kiểu tham số bạn cần trong vanilla, bạn có thể tự tạo kiểu của riêng mình. Bạn cần tạo một class mà kế thừa interface `ArgumentType`, với `T` là kiểu tham số. + +Bạn cần phải thêm method `parse` để xử lý tham số từ kiểu xâu ký tự sang kiểu tham số mà bạn cần. + +Giả sử bạn cần một kiểu tham số cho ra `BlockPos` khi người dùng nhập: `{x, y, z}` + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### Đăng Ký Kiểu Tham Số Tùy Chỉnh + +:::warning +Câu lệnh của bạn sẽ không hoạt động nếu bạn không đăng ký kiểu tham số tùy chỉnh trên cả máy chủ lẫn máy khách! +::: + +Bạn có thể đăng ký kiểu tham số tùy chỉnh trong khi mod của bạn đang khởi động trong method `onInitialize`, sử dụng class `ArgumentTypeRegistry`: + +@[code lang=java transcludeWith=:::11](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### Sử Dụng Kiểu Tham Số Tùy Chỉnh + +Bạn có thể sử dụng kiểu tham số tùy chỉnh trong một câu lệnh bằng cách đưa một instance của nó vào method `.argument` khi đang xây dựng một câu lệnh. + +@[code lang=java transcludeWith=:::10 highlight={3}](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +Thử chạy câu lệnh xem kiểu tham số của chúng ta có hoạt động không: + +![Tham số không hợp lệ](/assets/develop/commands/custom-arguments_fail.png) + +![Tham số hợp lệ](/assets/develop/commands/custom-arguments_valid.png) + +![Kết quả câu lệnh](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/vi_vn/index.md b/versions/1.21/translated/vi_vn/index.md new file mode 100644 index 000000000..004c60109 --- /dev/null +++ b/versions/1.21/translated/vi_vn/index.md @@ -0,0 +1,27 @@ +--- +title: Tài Liệu Fabric +description: Tài liệu chính thức của Fabric, một công cụ modding dành cho Minecraft. +layout: home +hero: + name: Tài Liệu Fabric + tagline: Tài liệu chính thức của Fabric, một công cụ modding dành cho Minecraft. +features: + - title: Developer Guides + icon: 🛠️ + details: Our curated developer guides, written by the community, span a wide range of topics from setting up a development environment to more advanced topics, such as rendering and networking. + link: /develop/ + linkText: Khởi Đầu + - title: Hướng Dẫn Cho Người Chơi + icon: 📚 + details: Có phải bạn đang tìm kiếm cách chạy các bản mod dành cho Fabric? Bộ hướng dẫn của chúng tôi sẽ giúp bạn điều đó. Những cách này sẽ giúp bạn trong việc tải xuống, cài đặt và khắc phục sự cố khi dùng mod Fabric. + link: /players/ + linkText: Đọc Thêm +--- + +
+ +## Muốn đóng góp? + +If you want to contribute to the Fabric Documentation, you can find the source code on [GitHub](https://github.com/FabricMC/fabric-docs), and the relevant [contribution guidelines](./contributing). + +
diff --git a/versions/1.21/translated/vi_vn/players/index.md b/versions/1.21/translated/vi_vn/players/index.md new file mode 100644 index 000000000..216968c17 --- /dev/null +++ b/versions/1.21/translated/vi_vn/players/index.md @@ -0,0 +1,12 @@ +--- +title: Hướng Dẫn Cho Người Chơi +description: Một bộ tài liệu hướng dẫn cho người chơi và quản trị viên máy chủ về cách cài đặt và sử dụng Fabric. +--- + +# Hướng Dẫn Cho Người Chơi + +Phần này của Tài liệu Fabric dành riêng cho người chơi và quản trị viên máy chủ muốn tìm hiểu cách cài đặt, sử dụng và khắc phục sự cố Fabric. + +Bạn nên tham khảo các phần ở thanh bên để biết danh sách tất cả các hướng dẫn có sẵn. + +Nếu bạn gặp bất cứ sự cố nào, vui lòng báo cáo chúng trên [GitHub](https://github.com/FabricMC/fabric-docs) hoặc xin sự trợ giúp từ kênh `#player-support` hay kênh `#server-admin-support` trong [Discord Fabric](https://discord.gg/v6v4pMv). diff --git a/versions/1.21/translated/vi_vn/players/installing-fabric.md b/versions/1.21/translated/vi_vn/players/installing-fabric.md new file mode 100644 index 000000000..64ca01703 --- /dev/null +++ b/versions/1.21/translated/vi_vn/players/installing-fabric.md @@ -0,0 +1,55 @@ +--- +title: Cài Đặt Fabric +description: Bộ hướng dẫn từng bước để cài đặt Fabric. +authors: + - IMB11 +--- + +# Cài Đặt Fabric + +Bài hướng dẫn này sẽ giúp bạn cài đặt Fabric cho trình Launcher Minecraft chính thức. + +Đối với các trình launcher bên thứ ba, bạn nên tham khảo tài liệu của họ. + +## 1. Tải xuống Trình cài đặt Fabric + +Bạn có thể tải trình cài đặt Fabric từ [trang chủ Fabric](https://fabricmc.net/use/). + +Nếu bạn sử dụng Windows, hãy tải phiên bản có đuôi `.exe` (`Download For Windows`), bởi vì nó không yêu cầu Java phải được cài trước đó trên hệ thống của bạn. Nó sẽ sử dụng phiên bản Java đi cùng trình launcher chính thức. + +Đối với macOS và Linux, bạn nên tải phiên bản có đuôi `.jar`. Đôi khi, cách này sẽ yêu cầu Java phải được cài đặt trước đó. + +## 2. Chạy Trình cài đặt Fabric + +:::warning +Hãy đóng Minecraft và trình Launcher của Minecraft trước khi cài đặt. +::: + +:::details Thông tin cho người dùng MacOS + +Trên macOS, bạn có thể cần bấm chuột phải vào tập tin `.jar` trong thư mục tải xuống của mình và bấm `Open` để chạy nó. + +![Trình cài đặt Fabric với chữ "Cài đặt" được tô đậm](/assets/players/installing-fabric/macos-downloads.png) + +Khi được hỏi "Bạn có muốn mở nó không?", bấm `Open` lần nữa. +::: + +Ngay khi bạn mở trình cài đặt, bạn sẽ thấy màn hình như thế này: + +![Trình cài đặt Fabric với chữ "Cài đặt" được tô đậm](/assets/players/installing-fabric/installer-screen.png) + +Để cài đặt Fabric, hãy chọn phiên bản trò chơi bạn muốn từ danh sách thả xuống, và bấm `install`. + +**Hãy đảm bảo đã chọn 'Create Profile'.** + +## 3. Hoàn tất! + +Sau khi trình cài đặt hoàn tất, bạn có thể mở trình Launcher Minecraft và chọn hồ sơ Fabric từ danh sách thả xuống ở góc trái bên dưới và bấm nút Chơi! + +![Trình Launcher Minecraft với hồ sơ Fabric được chọn](/assets/players/installing-fabric/launcher-screen.png) + +## Bước Tiếp Theo + +Bây giờ bạn đã hoàn tất việc cài Fabric, bạn có thể thêm mod vào trong trò chơi! Check out the [Finding Mods](./finding-mods) guide for more information. + +Nếu bạn gặp bất cứ vấn đề nào khi đang làm theo bài hướng dẫn này, bạn có thể xin sự trợ giúp từ kênh `#player-support` trong [Discord Fabric](https://discord.gg/v6v4pMv). diff --git a/versions/1.21/translated/vi_vn/players/installing-mods.md b/versions/1.21/translated/vi_vn/players/installing-mods.md new file mode 100644 index 000000000..796e7353c --- /dev/null +++ b/versions/1.21/translated/vi_vn/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: Cài Đặt Mod +description: Bộ hướng dẫn từng bước để cài đặt mod cho Fabric. +authors: + - IMB11 +--- + +# Cài Đặt Mod + +Bài hướng dẫn này sẽ giúp bạn cài đặt các bản mod Fabric cho trình Launcher Minecraft chính thức. + +Đối với các trình launcher bên thứ ba, bạn nên tham khảo tài liệu của họ. + +## 1. Tải Mod + +:::warning +Bạn chỉ nên tải mod từ các nguồn uy tín. Để biết thêm thông tin về cách tìm mod, hãy tham khảo tài liệu [Tìm Mod](./finding-mods). +::: + +Phần lớn các bản mod đều yêu cầu Fabric API, thứ mà có thể được tải từ [Modrinth](https://modrinth.com/mod/fabric-api) hoặc [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api) + +Khi chuẩn bị tải mod, cần lưu ý: + +- Chúng phải hỗ trợ phiên bản Minecraft bạn muốn chơi. Ví dụ một bản mod mà hoạt động tốt ở bản 1.20, có thể không hoạt động được ở bản 1.20.2. +- Chúng phải dùng được cho Fabric và không phải là các trình mod khác. +- Thêm vào đó, chúng phải đúng phiên bản Minecraft (Phiên bản Java). + +## 2. Di chuyển tệp mod vào trong thư mục `mods` + +Thư mục mods có thể được tìm thấy ở các địa chỉ bên dưới ứng với mỗi hệ điều hành. + +Bạn có thể dán những đường dẫn đó vào thanh địa chỉ của explorer để nhanh chóng điều hướng đến thư mục. + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +Khi bạn đã tìm thấy thư mục `mods`, bạn có thể di chuyển tệp mod `.jar` vào trong đó. + +![Cài đặt mod ở thư mục mods](/assets/players/installing-mods.png) + +## 3. Bạn đã hoàn tất! + +Sau khi bạn đã di chuyển tệp mod vào trong thư mục `mods`, bạn có thể mở trình Launcher Minecraft và chọn hồ sơ Fabric từ danh sách thả xuống ở góc trái bên dưới và bấm nút chơi! + +![Trình Launcher Minecraft với hồ sơ Fabric được chọn](/assets/players/installing-fabric/launcher-screen.png) + +## Khắc Phục Sự Cố + +Nếu bạn gặp bất cứ vấn đề nào khi đang làm theo bài hướng dẫn này, bạn có thể xin sự trợ giúp từ kênh `#player-support` trong [Discord Fabric](https://discord.gg/v6v4pMv). + +Bạn cũng có thể tự sửa chữa lỗi bằng cách tham khảo các trang khắc phục sự cố sau: + +- [Báo Cáo Dừng Đột Ngột](./troubleshooting/crash-reports) +- [Tải Lên Tệp Log](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/vi_vn/players/updating-fabric.md b/versions/1.21/translated/vi_vn/players/updating-fabric.md new file mode 100644 index 000000000..2811f9d1e --- /dev/null +++ b/versions/1.21/translated/vi_vn/players/updating-fabric.md @@ -0,0 +1,42 @@ +--- +title: Cập Nhật Fabric +description: Bộ hướng dẫn từng bước để cập nhật Fabric. +authors: + - IMB11 + - modmuss50 +--- + +# Cập Nhật Fabric + +Bài hướng dẫn này sẽ giúp bạn cập nhật Fabric cho trình Launcher Minecraft chính thức. + +Đối với các trình launcher bên thứ ba, bạn nên tham khảo tài liệu của họ. + +Việc cập nhật Fabric là một quá trình khá tương đồng so với việc cài đặt Fabric, vì vậy đa phần bài hướng dẫn này sẽ giống với +bài [Cài Đặt Fabric](./installing-fabric). + +## Vì sao tôi phải cập nhật Fabric Loader? + +Những bản mod mới có thể yêu cầu phiên bản mới hơn của Fabric Loader để hoạt động, vì vậy bạn nên liên tục cập nhật nó để có thể sử dụng nhiều bản mod mới nhất. + + + + + +Để cập nhật Fabric, đảm bảo chọn đúng cả phiên bản trò chơi và phiên bản loader rồi sau đó bấm `Cài Đặt`. + +**Hãy đảm bảo bỏ chọn `Tạo Hồ Sơ` khi chạy trình cài đặt, nếu không, nó sẽ tạo hồ sơ mới mà có thể chúng ta không cần.** + +## 3. Mở phần Hồ Sơ ở trình Launcher Minecraft + +Khi trình cài đặt hoàn tất, bạn có thể mở trình Launcher Minecraft và đi đến tab `Cài Đặt`. Chọn hồ sơ Fabric của bạn và mở màn hình chỉnh sửa. + +Thay thể phiên bản cũ với một phiên bản mới hơn của Fabric Loader mà bạn đã cài trước đó, và bấm `Lưu`. + +![Cập nhật phiên bản Fabric Loader ở trình Launcher Minecraft](/assets/players/updating-fabric.png) + +## 4. Bạn đã hoàn tất! + +Sau khi bạn đã hoàn thành xong các bước, bạn có thể quay trở lại tab `Chơi`, chọn hồ sơ Fabric từ danh sách thả xuống ở góc trái bên dưới và bấm nút chơi! + +Nếu bạn gặp bất cứ vấn đề nào khi đang làm theo bài hướng dẫn này, bạn có thể xin sự trợ giúp từ kênh `#player-support` trong [Discord Fabric](https://discord.gg/v6v4pMv). diff --git a/versions/1.21/translated/vi_vn/sidebar_translations.json b/versions/1.21/translated/vi_vn/sidebar_translations.json new file mode 100644 index 000000000..e044d0684 --- /dev/null +++ b/versions/1.21/translated/vi_vn/sidebar_translations.json @@ -0,0 +1,47 @@ +{ + "players.title": "Hướng Dẫn Cho Người Chơi", + "players.faq": "Các Câu Hỏi Thường Gặp", + "players.installingJava": "Đang Cài Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "Đang Cài Fabric", + "players.findingMods": "Đang Tìm Các Mod Đáng Tin Cậy", + "players.installingMods": "Đang Cài Các Mod", + "players.troubleshooting": "Khắc Phục Sự Cố", + "players.troubleshooting.uploadingLogs": "Tải Lên Tệp Log Của Bạn", + "players.troubleshooting.crashReports": "Báo Cáo Dừng Đột Ngột", + "players.updatingFabric": "Đang Cập Nhật Fabric", + "develop.title": "Hướng Dẫn Cho Nhà Phát Triển", + "develop.gettingStarted": "Khởi Đầu", + "develop.gettingStarted.introduction": "Giới thiệu về Fabric và Modding", + "develop.gettingStarted.devEnvSetup": "Thiết lập Môi trường Phát triển", + "develop.gettingStarted.creatingProject": "Tạo một Dự án", + "develop.gettingStarted.projectStructure": "Cấu trúc Dự án", + "develop.gettingStarted.launchGame": "Chạy Game", + "develop.items": "Vật Phẩm", + "develop.items.potions": "Thuốc", + "develop.entities": "Thực Thể", + "develop.entities.effects": "Trạng Thái Các Hiệu Ứng", + "develop.entities.damage-types": "Các Loại Sát Thương", + "develop.commands": "Lệnh", + "develop.commands.basics": "Tạo Lệnh", + "develop.commands.arguments": "Đối số", + "develop.commands.suggestions": "Gợi Ý", + "develop.rendering": "Kết Xuất", + "develop.rendering.basicConcepts": "Các Khái Niệm Kết Xuất Cơ Bản", + "develop.rendering.drawContext": "Sử Dụng Bối Cảnh Vẽ", + "develop.rendering.hud": "Kết Xuất Trên Hud", + "develop.rendering.gui": "GUI và Màn Hình", + "develop.rendering.gui.customScreens": "Màn hình Tuỳ Chỉnh", + "develop.rendering.gui.customWidgets": "Tiện Ích Tuỳ Chỉnh", + "develop.rendering.particles": "Hạt Hiệu Ứng", + "develop.rendering.particles.creatingParticles": "Tạo Các Hạt Hiệu Ứng", + "develop.misc": "Trang Khác", + "develop.misc.codecs": "Codecs", + "develop.misc.events": "Sự Kiện", + "develop.sounds": "Âm thanh", + "develop.sounds.using-sounds": "Chạy SoundEvent", + "develop.sounds.custom": "Tạo Âm thanh Tùy chỉnh", + "github.edit": "Sửa trang này trên GitHub" +} \ No newline at end of file diff --git a/versions/1.21/translated/vi_vn/website_translations.json b/versions/1.21/translated/vi_vn/website_translations.json new file mode 100644 index 000000000..17f120302 --- /dev/null +++ b/versions/1.21/translated/vi_vn/website_translations.json @@ -0,0 +1,8 @@ +{ + "title": "Tài Liệu Tham Khảo Fabric", + "home": "Trang Chủ", + "download": "Tải", + "contribute": "Đóng Góp", + "contribute.api": "Fabric API", + "version_switcher": "Thay Đổi Phiên Bản" +} \ No newline at end of file diff --git a/versions/1.21/translated/zh_cn/contributing.md b/versions/1.21/translated/zh_cn/contributing.md new file mode 100644 index 000000000..400d37799 --- /dev/null +++ b/versions/1.21/translated/zh_cn/contributing.md @@ -0,0 +1,253 @@ +--- +title: 贡献指南 +description: Fabric 文档贡献指南 +--- + +# 贡献指南{#contributing} + +此网站使用 [VitePress](https://vitepress.dev/) 从多个 Markdown 文件生成静态 HTML 网页。 您应该熟悉 VitePress 所支持的 Markdown 扩展语法,参见[此链接](https://vitepress.dev/guide/markdown.html#features)。 + +贡献此网站有三种方法: + +- [翻译文档](#translating-documentation) +- [贡献内容](#contributing-content) +- [贡献网页框架](#contributing-framework) + +所有贡献应该遵守我们的[样式指南](#style-guidelines)。 + +## 翻译文档{#translating-documentation} + +如果想将文档翻译为你的语言,可以在 [Fabric Crowdin 页面](https://zh.crowdin.com/project/fabricmc)翻译。 + + + +## new-content 贡献内容{#contributing-content} + +贡献内容是贡献 Fabric 文档的主要方式。 + +所有内容贡献都经过以下步骤,每个步骤都与一个标签相关联: + +1. 本地 准备您的更改并推出一个PR +2. stage:expansion:扩展指南(如果可能) +3. stage:verification:内容验证 +4. 步骤:整理中:语法检查中... +5. 步骤:准备:准备合并! + +所有的内容都应当遵循我们的[样式指南](#style-guidelines)。 + +### 1. 准备你的更改{#1-prepare-your-changes} + +网站是开源的,在 GitHub 仓库中开发,意味着我们依赖 GitHub 工作流。 + +1. [复刻 GitHub 仓库](https://github.com/FabricMC/fabric-docs/fork) +2. 为你的复刻创建新分支 +3. 在那个分支上做出更改 +4. 在源仓库开拉取请求 + +可以在[这里](https://docs.github.com/en/get-started/using-github/github-flow)了解更多关于 GitHub 流。 + +可以在 GitHub 网站界面上做出更改,也可以本地开发和预览网站。 + +#### 克隆你的复刻{#clone-your-fork} + +如果想要本地克隆复刻,需要安装 [Git](https://git-scm.com/)。 + +然后,用以下代码克隆仓库的复刻: + +```sh +# make sure to replace "your-username" with your actual username +git clone https://github.com/your-username/fabric-docs.git +``` + +#### 安装依赖{#install-dependencies} + +**如果想要本地预览更改,需要安装 [Node.js 18+](https://nodejs.org/en/)** + +然后,确保用以下代码安装所有依赖: + +```sh +npm install +``` + +#### 运行开发服务器{#run-the-development-server} + +这将允许您在本地地址 `localhost:3000` 预览您的更改,并自动在修改时重载页面。 + +```sh +npm run dev +``` + +现在可以从浏览器访问 `http://localhost:5173` 打开和浏览网站。 + +#### 构建网站{#building-the-website} + +这会把所有 Markdown 文件编译为静态 HTML 文件并保存至 `.vitepress/dist`: + +```sh +npm run build +``` + +#### 预览构建的网站{#previewing-the-built-website} + +这将在端口 `4173` 启动本地服务器并展示 `.vitepress/dist` 中的网页: + +```sh +npm run preview +``` + +#### 打开拉取请求{#opening-a-pull-request} + +对你的更改满意了,就可以 `推送(push)` 你的更改。 + +```sh +git add . +git commit -m "Description of your changes" +git push +``` + +然后,跟随 `git push` 的输出打开拉取请求。 + +### 2. stage:expansion 需要时扩展指南{#2-guidance-for-expansion-if-needed} + +如果文档团队认为您需要拓展您的拉去请求,团队成员将添加 stage:expansion 标签到您的拉去请求,并附上一条评论解释为什么他认为可以拓展。 如果同意建议,可以扩展你的拉取请求。 + +如果不想扩展您的拉取请求,但乐于让其他人在未来扩展它,最好在[议题页面](https://github.com/FabricMC/fabric-docs/issues)创建议题,并解释您想如何扩展。 之后文档制作团队将会在你的PR中加入帮助-追踪标签 + +### 3. stage:verification 内容验证{#3-content-verification} + +这是最重要的阶段,因为这能确保内容准确且遵循 Fabric 文档的样式指南。 + +在这一步,以下问题应被回答: + +- 所有内容都正确吗? +- 所有内容都是最新的吗? +- 内容是否涵盖所有情况,例如不同的操作系统? + +### 4. stage:cleanup 清理{#4-cleanup} + +在这一步,会发生以下内容: + +- 使用[LanguageTool](https://languagetool.org/)来修复一切语法问题 +- 使用 [`markdownlint`](https://github.com/DavidAnson/markdownlint) 检查所有 Markdown 文件 +- 使用[检查工具](https://checkstyle.sourceforge.io/)来格式化所有Java代码 +- 其它杂项翻译或优化 + +## framework 贡献网页框架{#contributing-framework} + +“框架”指的是网站的内部结构,任何修改网站框架的拉取请求都应该用 framework 标签标记。 + +您应该在咨询了 [Fabric Discord](https://discord.gg/v6v4pMv) 上的文档团队或通过一个 issue 后再发起框架相关的拉取请求。 + +:::info +修改侧边栏文件和导航栏配置不算作框架拉取请求。 +::: + +## 样式指南{#style-guidelines} + +如果有任何疑问,请在 [Fabric Discord](https://discord.gg/v6v4pMv) 或 GitHub Discussions 中提出。 + +### 用美式英语写原文{#write-the-original-in-american-english} + +所有原始文档都使用英文书写,遵循美国的语法规则。 + +### 给 Frontmatter 添加数据{#add-data-to-the-frontmatter} + +所有页面必须在 frontmatter 中有 `title` 和 `description`。 + +记得还要在 Markdown 文件的 frontmatter 中的 `authors` 添加你的 GitHub 用户名! 这种方式可以给你适当的致谢。 + +```md +--- +title: Title of the Page +description: This is the description of the page. +authors: + - your-username +--- + +# Title of the Page {#title-of-the-page} + +... +``` + +### 给标题添加锚点{#add-anchors-to-headings} + +每个标题都必须要有个锚点,用于链接至那个标题: + +```md +# This Is a Heading {#this-is-a-heading} +``` + +锚点必须使用小写字母、数字和横杠 + +### 将代码置于 `/reference` 模组中{#place-code-within-the-reference-mod} + +如果创建或修改包含代码的页面,将代码置于参考模组(位于目录的 `/reference` 文件夹内)的适当位置。 然后,使用[由 VitePress 提供的代码片段功能](https://vitepress.dev/guide/markdown#import-code-snippets)来嵌入代码。 + +例如,高亮参考模组中的 `FabricDocsReference.java` 的第 15-21 行: + +::: code-group + +```md +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21} +``` + +<<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21}[java] + +::: + +如果需要更大范围的控制,可以使用[来自 `markdown-it-vuepress-code-snippet-enhanced` 的 transclude 功能](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced)。 + +例如,这会嵌入上面的文件中被标记 `#entrypoint` 标签的部分: + +::: code-group + +```md +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) +``` + +@[code transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +::: + +### 为每个新段落创建侧边栏{#create-a-sidebar-for-each-new-section} + +如果创建新章节,你应该在 `.vitepress/sidebars` 文件夹中创建新的侧边栏,并添加到 `i18n.mts` 文件。 + +如果这个需要帮助,请在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#docs` 频道提问。 + +### 将新页面添加到相关的侧边栏{#add-new-pages-to-the-relevant-sidebars} + +写新页面时,应该将其添加到 `.vitepress/sidebars` 文件夹中的相关侧边栏。 + +还是那句,如果需要帮助,请在 Fabric Discord 的 `#docs` 频道提问。 + +### 把媒体放在 `/assets` 中{#place-media-in-assets} + +任何图片都应该放在 `/assets` 文件夹中的适当位置。 + +### 使用相对链接! {#use-relative-links} + +这是因为现有的版本控制系统会预处理链接,以便事先添加版本号。 如果您使用绝对链接,版本号将不会添加到链接中。 + +你也不能够给链接添加扩展名。 + +例如,要从页面 `/players/index.md` 链接到位于 `/players/installing-fabric.md` 的页面,需要进行以下操作: + +::: code-group + +```md:no-line-numbers [✅ Correct] +This is a relative link! +[Page](../players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This is an absolute link. +[Page](/players/index) +``` + +```md:no-line-numbers [❌ Wrong] +This relative link has the file extension. +[Page](../players/index.md) +``` + +::: diff --git a/versions/1.21/translated/zh_cn/develop/blocks/blockstates.md b/versions/1.21/translated/zh_cn/develop/blocks/blockstates.md new file mode 100644 index 000000000..94567acad --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/blocks/blockstates.md @@ -0,0 +1,127 @@ +--- +title: 方块状态 +description: 学习为什么方块状态是一个向你的方块添加可视化功能的好方法。 +authors: + - IMB11 +--- + +# 方块状态{#block-states} + +方块状态是附加到 Minecraft 世界中的单个方块上的一段数据,包含属性形式的方块块信息——原版存储在方块状态中的属性的一些示例: + +- Rotation:主要用于原木方块和其他自然方块中。 +- Activated:主要用于红石装置方块和类似于熔炉、烟熏炉的方块中。 +- Age:用于农作物、植物、树苗、海带等方块中使用。 + +你可能看出了为什么方块状态有用——避免了在方块实体中存储 NBT 数据的需要——这既减小了世界大小,也防止产生 TPS 问题! + +方块状态的定义能在 `assets//blockstates` 文件夹中找到。 + +## 示例:柱方块{#pillar-block} + + + +Minecraft 已经有些自定义的类,允许你快速创建特定类型的方块——这个例子会通过创建“Condensed Oak Log”方块来带你创建带有 `axis` 属性的方块。 + +原版的 `PillarBlock` 允许方块按 X、Y 或 Z 轴放置。 + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +柱方块有两个纹理,顶部(`top`)和侧面(`side`),使用 `block/cube_column` 模型。 + +同样,纹理文件可以在 `assets//textures/block` 中找到。 + +纹理 + +由于柱方块有两个位置,水平和垂直,我们需要创建两个单独的模型文件: + +- `condensed_oak_log_horizontal.json`,继承 `block/cube_column_horizontal` 模型。 +- `condensed_oak_log.json`,继承 `block/cube_column` 模型。 + +`condensed_oak_log_horizontal.json` 文件的示例: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_oak_log_horizontal.json) + +--- + +::: info +Remember, blockstate files can be found in the `assets//blockstates` folder, the name of the blockstate file should match the block ID used when registering your block in the `ModBlocks` class. For instance, if the block ID is `condensed_oak_log`, the file should be named `condensed_oak_log.json`. + +更加深入了解方块状态文件中可用的所有修饰器,可看看 [Minecraft Wiki - 模型(方块状态)](https://zh.minecraft.wiki/w/Tutorial:模型/方块状态)页面。 +::: + +然后,我们需要创建方块状态文件。 方块状态文件就是魔法发生的地方——柱方块有三个轴,所以我们使用以下情形中的特定模型: + +- `axis=x` - 方块沿 X 轴放置时,旋转模型以朝向正 X 方向。 +- `axis=y` - 方块沿 Y 轴旋转时,使用正常的垂直模型。 +- `axis=z` - 方块沿Z 轴放置时,旋转模型以朝向正 X 方向。 + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_oak_log.json) + +同样,需要为你的方块创建翻译,以及继承了这两个模型中的任意一个的物品模型。 + +![游戏内的柱方块的示例](/assets/develop/blocks/blockstates_1.png) + +## 自定义方块状态{#custom-block-states} + +如果你的方块有独特的属性,那么自定义方块状态会非常不错——有时你会发现你的方块可以复用原版的属性。 + +这个例子会创建一个叫做 `activated` 的独特属性——玩家右键单击方块时,方块会由 `activated=false` 变成 `activated-true` 并相应改变纹理。 + +### 创建属性{#creating-the-property} + +首先,需要创建属性本身——因为是个布尔值,所以使用 `BooleanProperty.of` 方法。 + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +然后,需要在 `appendProperties` 方法中将属性添加到 blockstate manager\` 中。 需要覆盖此方法以访问 builder: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +你还需要在你的自定义方块的构造函数中,设置 `activated` 属性的默认状态。 + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +:::warning +别忘了注册方块时使用自定义的类而不是 `Block`! +::: + +### 使用属性{#using-the-property} + +这个例子会在玩家与方块交互时,翻转 `activated` 属性的布尔值。 我们可以为此覆盖 `onUse` 方法: + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +### 视觉呈现属性{#visualizing-the-property} + +创建方块状态前,我们需要为方块的激活的和未激活的状态都提供纹理,以及方块模型。 + +纹理 + +用你的方块模型知识,创建方块的两个模型:一个用于激活的状态,一个用于未激活的状态。 完成后,就可以开始创建方块状态文件了。 + +因为创建了新的属性,所以需要为方块更新方块状态文件以使用那个属性。 + +如果方块有多个属性,那么会需要包含所有可能的组合。 例如,`activated` 和 `axis` 可能就会导致 6 个组合(`activated` 有两个可能的值,`axis` 有三个可能的值)。 + +因为方块只有一个属性(`activated`),只有两个变种,所以方块状态 JSON 看起来应该像这样: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/prismarine_lamp.json) + +--- + +因为这个示例方块是灯,所以还需要让它在 `activated` 属性为 true 时发光。 可以通过在注册方块时传入构造器的 block settings 来完成。 + +可以使用 `luminance` 方法设置方块放出的光,可以在 `PrismarineLampBlock` 类中创建一个静态方法,从而根据 `activated` 属性返回光照等级,并将其作为方法引入传入 `luminance` 方法中。 + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/block/custom/PrismarineLampBlock.java) + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + + + +一切完成后,最终的结果应该看起来像这样: + + diff --git a/versions/1.21/translated/zh_cn/develop/blocks/first-block.md b/versions/1.21/translated/zh_cn/develop/blocks/first-block.md new file mode 100644 index 000000000..f21a93db7 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/blocks/first-block.md @@ -0,0 +1,170 @@ +--- +title: 创建你的第一个方块 +description: 学习如何在 Minecraft 中创建你的第一个自定义方块。 +authors: + - IMB11 + - xEobardThawne + - its-miroma +--- + +# 创建你的第一个方块{#creating-your-first-block} + +方块是构成 Minecraft 世界的主要组成部分——和 Minecraft 的其他一切一样,是储存在注册表中的。 + +## 准备你的 Blocks 类{#preparing-your-blocks-class} + +如果你已经完成了[创建你的第一个物品](../items/first-item),那么这一过程会非常熟悉——你会需要创建一个注册方块以及方块物品的方法。 + +你应该把这个方块放在叫做 `ModBlocks` 的类中(也可以是其他你想要的名称)。 + +Mojang 对原版方块的处理方法和这个也非常相似,你可以参考 `Blocks` 类看看他们是怎么做的。 + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +像物品一样,你需要确保类被加载,这样所有包含方块实体的静态字段都会初始化。 + +你可以添加一个 `initialize` 方法,并在模组的[初始化](./getting-started/project-structure#entrypoints)中调用以进行静态初始化。 + +:::info +如果不知道什么是静态初始化,那么这里说下,这是初始化类中的所有静态字段的过程。 JVM 加载类时,以及创建类的任何实例之前,都会完成这一过程。 +::: + +```java +public class ModBlocks { + // ... + + public static void initialize() {} +} +``` + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/block/FabricDocsReferenceBlocks.java) + +## 创建并注册你的方块{#creating-and-registering-your-block} + +和物品类似,方块会在构造函数中接收一个 `Block.Settings` 类,指定了方块的属性,例如其声音效果和挖掘等级。 + +这里不会把所有选项都提到——可以查看类本身来看看各种选项,应该能直接懂的。 + +这里为作举例,我们会创建一个拥有和泥土的相同属性但材料不同的方块。 + +:::tip +可以使用 `AbstractBlock.Settings.copy(AbstractBlock block)` 从已存在的方块中复制 settings,这种情况下,可以使用 `Blocks.DIRT` 以从泥土中复制 settings,但是为作举例,我们使用 builder。 +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +我们上一步创建过 `regisger` 方法,要自动创建方块物品,我们在方法的 `shouldRegisterItem` 参数中传入 `true`。 + +### 将方块添加到物品组{#adding-your-block-to-an-item-group} + +由于 `BlockItem` 是自动创建和注册的,要将其添加到物品组中,必须使用 `Block.asItem()` 方法来获得 `BlockItem` 实例。 + +例如,我们使用在[自定义物品组](../items/custom-item-groups)页面中创建的自定义物品组。 + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/block/ModBlocks.java) + +--- + +你应该注意到,你的方块现在在创造模式物品栏中,并且可以放在世界中! + +![世界内没有模型和纹理的方块](/assets/develop/blocks/first_block_0.png) + +但是还有点问题——方块物品没有命名,方块没有纹理、方块模型和物品模型。 + +## 添加方块翻译{#adding-block-translations} + +要添加翻译,必须在你的翻译文件——`assets//lang/en_us.json` 中创建翻译键。(类似地,中文翻译可添加到 `assets/<0>/lang/zh_cn.json`。) + +Minecraft 会在创造模式物品栏中,以及其他显示方块名称的地方(例如命令反馈)中显示这个翻译。 + +```json +{ + "block.mod_id.condensed_dirt": "Condensed Dirt" +} +``` + +你可以重启游戏,或者构建你的模组,然后在游戏里按 F3 + T 以重新加载资源文件——你将会看到方块在创造模式物品栏里或者其他地方(例如统计屏幕)中有个名字了。 + +## 模型和纹理{#models-and-textures} + +所有方块纹理都可以在 `assets//textures/block` 文件夹中找到——“Condensed Dirt”方块的示例纹理可以自由使用。 + +纹理 + +要确保模型在游戏内显示,必须创建方块和物品模型,“Condensed Dirt”方块的方块和物品模型分别可以在下列地方找到: + +- `assets//models/block/condensed_dirt.json` +- `assets//models/item/condensed_dirt.json` + +物品模型很简单,只需要继承方块模型即可,因为大多数方块模型都支持在 GUI 中渲染。 + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/condensed_dirt.json) + +但是,在我们的例子中,方块模型就必须继承 `block/cube_all` 模型。 + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/block/condensed_dirt.json) + +载入游戏,你可能会发现模型还是缺失。 这是因为,你还需要添加方块状态定义。 + +## 创建方块状态定义{#creating-the-block-state-definition} + +方块状态定义用于指示游戏基于当前方块的状态要渲染哪个模型。 + +示例方块没有复杂的方块状态,只需要定义一项。 + +这个方块应该位于 `assets/mod_id/blockstates` 文件夹内,名字应该匹配在 `ModBlocks` 类中注册方块时使用的方块 ID。 例如,方块 ID 是 `condensed_dirt`,那么文件名称就是 `condensed_dirt.json`。 + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/blockstates/condensed_dirt.json) + +方块状态很复杂,会在之后的页面[方块状态](./blockstates)中详述。 + +重启游戏,或者按下F3 + T重新加载资源文件以应用更改——你应该能看到方块在物品栏内的纹理,以及在世界中呈现: + +![世界内有适当的纹理和模型的方块](/assets/develop/blocks/first_block_4.png) + +## 添加方块掉落物{#adding-block-drops} + +在生存模式下破坏方块时,你可能看到方块不会掉落——你可能想要这个功能,但是要让方块被破坏时掉落为物品,必须要实现其战利品表——战利品表文件应置于 `data//loot_table/blocks/` 文件夹中。 + +:::info +对战利品表的更深入理解,可参考 [Minecraft Wiki - 战利品表](https://zh.minecraft.wiki/w/战利品表)页面。 +::: + +@[code](@/reference/1.21/src/main/resources/data/fabric-docs-reference/loot_tables/blocks/condensed_dirt.json) + +这个战利品表提供了方块在被破坏以及被爆炸破坏时掉落的单个方块物品。 + +## 推荐挖掘工具{#recommending-a-harvesting-tool} + +你可能也想要让方块只能被特定类型的方块挖掘——例如,可能想让你的方块用锹挖掘更快。 + +所有的工具标签都位于 `data/minecraft/tags/block/mineable/` 文件夹内——其中文件的名称取决于使用的工具的类型,是以下之一: + +- `hoe.json`(锄) +- `axe.json`(斧) +- `pickaxe.json`(镐) +- `shovel.json`(锹) + +文件的内容很简单,是要添加到标签中的物品的列表。 + +这个例子会将“Condensed Dirt”方块添加到 `shovel` 标签中。 + +@[code](@/reference/1.21/src/main/resources/data/minecraft/tags/mineable/shovel.json) + +如果应使用工具来挖掘此方块,则需要在方块属性(`Block.Settings`)中添加`.requiresTool()`,并添加相应的挖掘标签。 + +## 挖掘等级{#mining-levels} + +类似地,`data/minecraft/tags/block/` 文件夹内也可以找到挖掘等级,并遵循以下格式: + +- `needs_stone_tool.json` - 最低需要石质工具 +- `needs_iron_tool.json` - 最低需要铁质工具 +- `needs_diamond_tool.json` - 最低需要钻石工具 + +文件与挖掘工具文件的格式相同——要添加到标签中的物品的列表。 + +## 备注{#extra-notes} + +如果将多个方块添加到你的模组中,可能需要考虑使用[数据生成](https://fabricmc.net/wiki/tutorial:datagen_setup)来自动化创建方块和物品模型、方块状态定义和战利品表。 diff --git a/versions/1.21/translated/zh_cn/develop/codecs.md b/versions/1.21/translated/zh_cn/develop/codecs.md new file mode 100644 index 000000000..e7fca0281 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/codecs.md @@ -0,0 +1,401 @@ +--- +title: Codec +description: 一份用于理解和使用 Mojang 的 codec 系统以序列化和反序列化对象的全面指南。 +authors: + - enjarai + - Syst3ms +--- + +# Codecs {#codecs} + +Codec 是用于简单地解析 Java 对象的系统,被包含在 Minecraft 所包含的 Mojang 的 DataFixerUpper (DFU) 库中。 在模组环境中,它们可以用作替代方案 +到 GSON 和 Jankson 中,尽管它们开始变得 +越来越相似,这是因为 Mojang 正在重写许多旧代码以使用 Codecs。 + +Codec 与 DFU 的另一个 API `DynamicOps` 一起使用。 一个 Codec 定义一个对象的结构,而动态管理器用于定义一个序列化格式,例如 json 或 NBT。 这意味着任何 codec 都可以与任何 dynamic ops 一起使用,反之亦然,这样使其极其灵活。 + +## 使用 Codecs{#using-codecs} + +### 序列化和反序列化{#serializing-and-deserializing} + +Codec 的基本用法是将对象序列化为特定格式或反序列化为特定格式。 + +一些原版的类已经定义了 Codecs,这些我们可以用作示例。 Mojang 默认提供了两个 dynamic ops 类,`JsonOps` 和 `NbtOps`,涵盖大部分的使用场景。 + +现在,假设我们要把一个 `BlockPos` 对象序列化成 json 再反序列化回对象。 我们可以分别使用 `BlockPos.CODEC` 中的静态方法 `Codec#encodeStart` 和 `Codec#parse`。 + +```java +BlockPos pos = new BlockPos(1, 2, 3); + +// 序列化该 BlockPos 为 JsonElement +DataResult result = BlockPos.CODEC.encodeStart(JsonOps.INSTANCE, pos); +``` + +使用 codec 时,返回的结果为 `DataResult` 的形式。 这是个包装,可以代表成功或者失败。 有几种方式使用:如果只想要我们序列化的值, `DataResult#result` 会简单返回一个包含我们的值的 `Optional` ,而 `DataResult#resultOrPartial` 还允许我们提供一个函数来处理可能发生的任何错误。 后者对于自定义数据包资源尤其有用,因为我们想要记录错误,而不会在其他地方引起问题。 + +那么,让我们获取我们的序列化值,并将其转换回 `BlockPos` : + +```java +// 实际编写模组时,你当然会想要适当地处理空的 Optional。 +JsonElement json = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// 这里我们有我们的 json 值,应该对应于 `[1, 2, 3]`, +// 因为这是 BlockPos codec 使用的格式。 +LOGGER.info("Serialized BlockPos: {}", json); + +// 现在将 JsonElement 反序列化为 BlockPos +DataResult result = BlockPos.CODEC.parse(JsonOps.INSTANCE, json); + +// 我们将再次只是从 result 中获取我们的值 +BlockPos pos = result.resultOrPartial(LOGGER::error).orElseThrow(); + +// 接下来我们可以看到我们成功序列化和反序列化我们的 BlockPos! +LOGGER.info("Deserialized BlockPos: {}", pos); +``` + +### 内置的 Codec{#built-in-codecs} + +正如之前所说,Mojang 已经为几个原版和标准 Java 类定义了 codec,包括但不限于 `BlockPos`、`BlockState`、`ItemStack`、`Identifier`、`Text` 和正则表达式 `Pattern`。 Mojang 自己的 codec 通常可以在类内找到名为 `CODEC` 的静态字段,其他的保持在 `Codecs` 类。 还要注意,所有原版注册表都包含 `getCodec()` 方法,例如,你可以使用 `Registries.BLOCK.getCodec()` 获取一个 `Codec`,可用于序列化为方块 id 或是反过来。 + +Codec API 自己也包含一些基础类型的 codec,例如 `Codec.INT` 和 `Codec.STRING`。 这些都在 `Codec` 类中作为静态字段存在,通常用作更多复杂 codec 的基础,会在下方做出解释。 + +## 构建 Codec{#building-codecs} + +现在我们已经知道如何使用 codec,让我们看看我们如何构建自己的 codec。 假设我们有以下类,希望从 json 文件中反序列化其实例: + +```java +public class CoolBeansClass { + + private final int beansAmount; + private final Item beanType; + private final List beanPositions; + + public CoolBeansClass(int beansAmount, Item beanType, List beanPositions) {...} + + public int getBeansAmount() { return this.beansAmount; } + public Item getBeanType() { return this.beanType; } + public List getBeanPositions() { return this.beanPositions; } +} +``` + +相应的 json 文件可能如下所示: + +```json +{ + "beans_amount": 5, + "bean_type": "beanmod:mythical_beans", + "bean_positions": [ + [1, 2, 3], + [4, 5, 6] + ] +} +``` + +我们可以将多个较小的 codec 组合成较大的 codec,从而为这个类制作 codec。 在这种情况下,我们的每个字段都需要: + +- 一个 `Codec` +- 一个 `Codec` +- 一个 `Codec>` + +第一个可以从前面提到的 `Codec` 类中的基本类型 codec 中得到,也就是 `Codec.INT`。 而第二个可以从 `Registries.ITEM` 注册表中获取,它有 `getCodec()` 方法,返回 `Codec`。 我们没有用于 `List` 的默认 codec,但我们可以从 `BlockPos.CODEC` 制作一个。 + +### 列表{#lists} + +`Codec#listOf` 可用于创建任意 codec 的列表版本。 + +```java +Codec> listCodec = BlockPos.CODEC.listOf(); +``` + +应该注意的是,以这种方式创建的 codec 总是会反序列化为一个 `ImmutableList`。 如果需要的是可变的列表,可以利用 [xmap](#mutually-convertible-types) 在反序列化期间转换为可变列表。 + +### 合并用于类似 Record 类的 Codec{#merging-codecs-for-record-like-classes} + +现在每个字段都有了单独的 codec,我们可以使用 `RecordCodecBuilder` 为我们的类将其合并为一个 codec。 假定我们的类有一个包含想序列化的所有字段的构造方法,并且每个字段都有相应的 getter 方法。 这使得它非常适合与 record 一起使用,但也可以用于常规类。 + +来看看如何为我们的 `CoolBeansClass` 创建一个 codec: + +```java +public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("beans_amount").forGetter(CoolBeansClass::getBeansAmount), + Registries.ITEM.getCodec().fieldOf("bean_type").forGetter(CoolBeansClass::getBeanType), + BlockPos.CODEC.listOf().fieldOf("bean_positions").forGetter(CoolBeansClass::getBeanPositions) + // 最多可以在这里声明 16 个字段 +).apply(instance, CoolBeansClass::new)); +``` + +在 group 中的每一行指定 codec、字段名称和 getter 方法。 调用 `Codec#fieldOf` 是为将 codec 转换为 [map codec](#mapcodec),调用 `forGetter` 则是指定了从类的实例中检索字段值的 getter 方法。 同时,调用 `apply` 则指定了用于创建新实例的构造函数。 注意 group 中的字段的顺序应与构造函数中参数的顺序相同。 + +这里也可以使用 `Codec#optionalFieldOf` 使字段可选,在 [可选字段](#optional-fields) 章节会有解释。 + +### 不要将 MapCodec 与 Codec&lt;Map&gt; 混淆 {#mapcodec} + +调用 `Codec#fieldOf` 会将 `Codec` 转换成 `MapCodec`,这是 `Codec` 的一个变体,但不是直接实现。 正如其名称所示,`MapCodec` 保证序列化为 +键到值的映射,或所使用的 `DynamicOps` 类似类型。 一些函数可能需要使用 `MapCodec` 而不是常规的 codec。 + +这种创建 `MapCodec` 的特殊方式本质上是在一个映射中封装源 codec 的值,并使用给定的字段名作为键。 例如,一个 `Codec` 序列化为 json 时看起来像是这样: + +```json +[1, 2, 3] +``` + +但当使用 `BlockPos.CODEC.fieldOf("pos")` 转换为 `MapCodec` 时,看起来像是这样: + +```json +{ + "pos": [1, 2, 3] +} +``` + +虽然 map codec 最常见的用途是与其他 map codec 合并以构造一个完整类字段的 codec,如前文的 [合并用于类似 Record 类的 Codec](#merging-codecs-for-record-like-classes) 章节所述,但也可以通过使用 `MapCodec#codec` 再次转换成常规的 codec,这将保持封装输入值的相同行为。 + +#### 可选字段{#optional-fields} + +`Codec#optionalFieldOf` 可用于创建一个可选的 map codec。 反序列化过程中,当特定字段不存在于容器中时,反序列化为一个空的 `Optional`,或指定的默认值。 + +```java +// 无默认值 +MapCodec> optionalCodec = BlockPos.CODEC.optionalFieldOf("pos"); + +// 有默认值 +MapCodec optionalCodec = BlockPos.CODEC.optionalFieldOf("pos", BlockPos.ORIGIN); +``` + +需要注意,可选字段会忽略反序列化过程中可能发生的任何错误而不报错。 这意味着如果字段存在,但值无效,该字段总是会被反序列化为默认值。 + +**从 1.20.2 开始**,Minecraft 自己 (不是 DFU!) 却确实提供`Codecs#createStrictOptionalFieldCodec`, +如果字段值无效,则反序列化失败。 + +### 常量、约束和组合{#constants-constraints-composition} + +#### Unit{#unit} + +`Codec.unit` 可用于创建一个无论输入什么都总是反序列化为常量值的 codec。 序列化时什么也不做。 + +```java +Codec theMeaningOfCodec = Codec.unit(42); +``` + +#### 数值范围{#numeric-ranges} + +`Codec.intRange` 及其伙伴 `Codec.floatRange` 和 `Codec.doubleRange` 可用于创建只接受在指定的**包含两端的**范围内的数字值的 codec, 这适用于序列化和反序列化。 + +```java +// 不能大于 2 +Codec amountOfFriendsYouHave = Codec.intRange(0, 2); +``` + +#### Pair{#pair} + +`Codec.pair` 将两个 codec `Codec
` 和 `Codec` 合并为 `Codec>`。 请记住,它只能与序列化到特定字段的Codec配合使用,例如[转换的`MapCodec`](#mapcodec)或 +[记录Codec](#merging-codecs-for-record-like-classes)。 +结果的 codec 将序列化为结合了两个使用的 codec 字段的 map。 + +例如,运行这些代码: + +```java +// 创建两个单独的装箱的 codec +Codec firstCodec = Codec.INT.fieldOf("i_am_number").codec(); +Codec secondCodec = Codec.BOOL.fieldOf("this_statement_is_false").codec(); + +// 将其合并为 pair codec +Codec> pairCodec = Codec.pair(firstCodec, secondCodec); + +// 用它序列化数据 +DataResult result = pairCodec.encodeStart(JsonOps.INSTANCE, Pair.of(23, true)); +``` + +将输出该 json: + +```json +{ + "i_am_number": 23, + "this_statement_is_false": true +} +``` + +#### Either{#either} + +`Codec.either` 将两个 codec `Codec` 和 `Codec` 组合为 `Codec>`。 产生的 codec 会在反序列化过程中尝试使用第一个 codec,并且_仅当失败时_才尝试使用第二个。 +如果第二个也失败,则会返回第二个 codec 的错误。 + +#### Map{#maps} + +要处理有任意键的 map,如 `HashMap`,可以使用 `Codec.unboundedMap`。 这将返回给定 `Codec` 和 `Codec` 的 `Codec>`。 生成的 codec 将序列化为 JSON 对象,或当前 dynamic ops 可用的任何等效对象。 + +由于 json 和 nbt 的限制,使用的键的 codec _必须_序列化为字符串。 这包括类型自身不是字符串但会序列化为字符串的 codec,例如 `Identifier.CODEC`。 看看下面的例子: + +```java +// 创建一个 Identifier 到 Integer 的 map 的 codec +Codec> mapCodec = Codec.unboundedMap(Identifier.CODEC, Codec.INT); + +// 使用它序列化数据 +DataResult result = mapCodec.encodeStart(JsonOps.INSTANCE, Map.of( + new Identifier("example", "number"), 23, + new Identifier("example", "the_cooler_number"), 42 +)); +``` + +将输出该 json: + +```json +{ + "example:number": 23, + "example:the_cooler_number": 42 +} +``` + +正如你所见,因为 `Identifier.CODEC` 直接序列化到字符串,所以这样做有效。 对于无法序列化为字符串的简单对象,可以使用[xmap 及其友元](#mutually-convertible-types)进行转换,从而实现类似的效果。 + +### 相互可转换的类型{#mutually-convertible-types} + +#### `xmap`{#xmap} + +我们有两个可以互相转换的类,但没有继承关系。 例如,原版的 `BlockPos` 和 `Vec3d`。 如果我们有其中一个 codec,我们可以使用 `Codec#xmap` 创建一个双向的特定转换函数。 + +`BlockPos` 已有 codec,但让我们假装它不存在。 我们可以基于 `Vec3d` 的 codec 这样为它创建一个: + +```java +Codec blockPosCodec = Vec3d.CODEC.xmap( + // 转换 Vec3d 到 BlockPos + vec -> new BlockPos(vec.x, vec.y, vec.z), + // 转换 BlockPos 到 Vec3d + pos -> new Vec3d(pos.getX(), pos.getY(), pos.getZ()) +); + +// 当转换一个存在的类 (比如 `X`)到您自己的类 (`Y`) +// 最好是在 `Y` 类中添加 `toX` 和静态的 `fromX` 方法 +// 并且使用在您的 `xmap` 调用中使用方法引用 +``` + +#### flatComapMap、comapFlatMap 与 flatXMap{#flatcomapmap-comapflatmap-flatxmap} + +`flatComapMap`、`comapFlatMap` 与 `flatXMap` 类似于 xmap,但允许一个或多个转换函数返回 DataResult。 这在实践中很有用,因为特定的对象实例可能并不总是适合转换。 + +以原版的 `Identifier` 为例。 虽然所有的 identifier 都可以转换为字符串,但并不是所有的字符串都是有效的 identifier,所以使用 xmap 意味着转换失败就会抛出难看的异常。 +正因此,其内置 codec 实际上是 `Codec.STRING` 上的 `comapFlatMap`,很好地说明了如何使用: + +```java +public class Identifier { + public static final Codec CODEC = Codec.STRING.comapFlatMap( + Identifier::validate, Identifier::toString + ); + + // ... + + public static DataResult validate(String id) { + try { + return DataResult.success(new Identifier(id)); + } catch (InvalidIdentifierException e) { + return DataResult.error("Not a valid resource location: " + id + " " + e.getMessage()); + } + } + + // ... +} +``` + +虽然这些方法非常有用,但方法名称有点让人困惑,所以这里有一个表格帮助你记住应该使用哪一个: + +| 方法 | A -> B 总是有效? | B -> A 总是有效? | +| ----------------------- | ------------ | ------------ | +| `Codec#xmap` | 是 | 是 | +| `Codec#comapFlatMap` | 否 | 是 | +| `Codec#flatComapMap` | 是 | 否 | +| `Codec#flatXMap` | 否 | 否 | + +### 注册表分派{#registry-dispatch} + +`Codec#dispatch` 让我们可以定义一个 codec 的注册表,并根据序列化数据中字段的值分派到一个特定的 codec。 当反序列化有不同字段的对象,而这些字段依赖于类型,但不同类型仍代表相同的事物时,这非常有用。 + +例如我们有一个抽象的 `Bean` 接口与两个实现类:`StringyBean` 和 `CountingBean`。 为了用注册表分派序列化他们,我们需要一些事: + +- 每个 bean 类型的独立 codec。 +- 一个 `BeanType` 类或 record,代表 bean 的类型并可返回它的 codec。 +- 一个在 `Bean` 中可以用于检索其 `BeanType` 的函数。 +- 一个 `Identifier` 到 `BeanType` 的 map 或注册表 +- 一个基于该注册表的 `Codec>`。 如果你使用 `net.minecraft.registry.Registry`,那么可以简单地调用 `Registry#getCodec`。 + +有了这些,就可以创建一个 bean 的注册表分派 codec。 + +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/Bean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanType.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/StringyBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/CountingBean.java) +@[code transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/codec/BeanTypes.java) + +```java +// 现在我们可以创建一个用于 bean 类型的 codec +// 基于之前创建的注册表 +Codec> beanTypeCodec = BeanType.REGISTRY.getCodec(); + +// 基于那个,这是我们用于 bean 的注册表分派 codec! +// 第一个参数是这个 bean 类型的字段名 +// 当省略时默认是 "type"。 +Codec beanCodec = beanTypeCodec.dispatch("type", Bean::getType, BeanType::codec); +``` + +我们的新 codec 将会这样将 bean 类序列化为 json,仅抓取与特定类型相关的字段: + +```json +{ + "type": "example:stringy_bean", + "stringy_string": "This bean is stringy!" +} +``` + +```json +{ + "type": "example:counting_bean", + "counting_number": 42 +} +``` + +### 递归 Codec{#recursive-codecs} + +有时,使用_自身_来解码特定字段的 codec 很有用,例如在处理某些递归数据结构时。 在原版代码中,这用于 `Text` 对象,可能会存储其他的 `Text` 作为子对象。 可以使用 `Codec#recursive` 构建这样的 codec。 + +例如,让我们尝试序列化单链列表。 列表是由一组节点的表示的,这些节点既包含一个值,也包含对列表中下一个节点的引用。 然后列表由其第一个节点表示,遍历列表是通过跟随下一个节点来完成的,直到没有剩余节点。 以下是存储整数的节点的简单实现。 + +```java +public record ListNode(int value, ListNode next) {} +``` + +我们无法通过普通方法为此构建 codec,因为对 `next` 字段要使用什么 codec? 我们需要一个 `Codec`,这就是我们还在构建的! `Codec#recursive` 能让我们使用看上去像魔法的 lambda 来达到这点。 + +```java +Codec codec = Codec.recursive( + "ListNode", // codec的名称 + selfCodec -> { + // 这里,`selfCodec` 代表 `Codec`,就像已经构造好了一样 + // 这个 lambda 应该返回我们从一开始就想要使用的 codec, + // 通过 `selfCodec` 引用自身 + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("value").forGetter(ListNode::value), + // `next`字段将使用自己 codec 递归处理 + Codecs.createStrictOptionalFieldCodec(selfCodec, "next", null).forGetter(ListNode::next) + ).apply(instance, ListNode::new) + ); + } +); +``` + +序列化的 `ListNode` 可能看起来像这样: + +```json +{ + "value": 2, + "next": { + "value": 3, + "next": { + "value": 5 + } + } +} +``` + +## 参考{#references} + +- 关于 codec 及相关 API 的更全面的文档,可以在[非官方 DFU JavaDoc](https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec) 中找到。 +- 本指南的总体结构受到了 [Forge 社区 Wiki 关于 Codec 的页面](https://forge.gemwire.uk/wiki/Codecs)的重大启发,这是对同一主题的更具 Forge 特色的解读。 diff --git a/versions/1.21/translated/zh_cn/develop/commands/arguments.md b/versions/1.21/translated/zh_cn/develop/commands/arguments.md new file mode 100644 index 000000000..0f0b63382 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/commands/arguments.md @@ -0,0 +1,64 @@ +--- +title: 命令参数 +description: 学习如何创建带有复杂参数的命令。 +--- + +# 命令参数{#command-arguments} + +大多数命令都使用了参数。 有时参数是可选的,也就是说如果你不提供此参数,命令仍能运行。 一个节点可以有多个参数类型,但是注意有可能出现二义性,这是需要避免的。 + +@[code lang=java highlight={3} transcludeWith=:::command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +在这个例子中,在命令文本 `/command_with_arg` 之后,你需要输入一个整数。 例如,如果运行 `/command_with_arg 3`,会收到反馈消息: + +> 调用了 /command_with_arg 其中 value = 3 + +如果你输入 `/command_with_arg` 不带参数,命令无法正确解析。 + +接下来我们将添加第二个可选的参数: + +@[code lang=java highlight={3,5} transcludeWith=:::command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_with_two_args](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +现在你可以输入一个或者两个整数了。 如果提供了一个整数,那么会打印单个值的反馈文本。 如果提供了两个整数,那么会打印有两个值的反馈文本。 + +你可能发现,两次指定类似的执行内容有些不太必要。 因此,我们可以创建一个在两个执行中都使用的方法。 + +@[code lang=java highlight={4,6} transcludeWith=:::command_with_common_exec](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_common](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 自定义参数类型{#custom-argument-types} + +如果原版没有你想要的参数类型,可以自己创建一个。 为此,创建一个类并继承 `ArgumentType` 接口,其中 `T` 是参数的类型。 + +您需要实现 `parse` 这个方法,这个方法会把输入的字符串解析为期望的类型。 + +举个例子,您可以创建一个可以把格式形如 `{x, y, z}` 的字符串解析为一个 `BlockPos` 参数类型。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/BlockPosArgumentType.java) + +### 注册自定义参数类型{#registering-custom-argument-types} + +:::warning +您需要在服务端和客户端都注册自定义参数类型,否则命令不会生效! +::: + +你可以在你的模组[入口点](./getting-started/project-structure#entrypoints)中的初始化方法 `onInitialize` 中使用 `ArgumentTypeRegistry` 类来注册: + +@[code lang=java transcludeWith=:::register_custom_arg](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### 使用自定义参数类型{#using-custom-argument-types} + +我们可以在命令中使用我们的自定义参数类型──通过在 command builder 中传递实例到 `.argument` 方法。 + +@[code lang=java highlight={3} transcludeWith=:::custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java highlight={2} transcludeWith=:::execute_custom_arg_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +运行命令,我们可以测试参数类型是否生效: + +![无效参数](/assets/develop/commands/custom-arguments_fail.png) + +![有效参数](/assets/develop/commands/custom-arguments_valid.png) + +![命令结果](/assets/develop/commands/custom-arguments_result.png) diff --git a/versions/1.21/translated/zh_cn/develop/commands/basics.md b/versions/1.21/translated/zh_cn/develop/commands/basics.md new file mode 100644 index 000000000..da8b85ca6 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/commands/basics.md @@ -0,0 +1,174 @@ +--- +title: 创建命令 +description: 创建带有复杂参数和行为的命令。 +authors: + - dicedpixels + - i509VCB + - pyrofab + - natanfudge + - Juuxel + - solidblock + - modmuss50 + - technici4n + - atakku + - haykam + - mschae23 + - treeways + - xpple +--- + +# 创建命令 {#creating-commands} + +创建命令可以允许模组开发者添加一些可以通过命令使用的功能。 这个指南将会教会你如何注册命令和 Brigadier 的一般命令结构。 + +::: info +Brigadier is a command parser and dispatcher written by Mojang for Minecraft. It is a tree-based command library where +you build a tree of commands and arguments. + +Brigadier 是开源的: + +## `Command` 接口{#the-command-interface} + +`com.mojang.brigadier.Command` 是一个可以执行指定行为的函数式接口,在某些情况下会抛出 `CommandSyntaxException` 异常。 命令有一个泛型 `S`,定义了_命令来源_的类型。 +命令来源提供了命令运行的上下文。 在 Minecraft 中,命令来源通常是 `ServerCommandSource`,代表服务器、命令方块、远程连接(RCON)、玩家或者实体。 + +`Command` 中的单个方法 `run(CommandContext)`,接收一个 `CommandContext` 作为唯一参数,并返回一个整数。 命令上下文存储命令来源 `S`,并允许你获取参数、查看已解析的命令节点,并查看此命令中使用的输入。 + +就像其他的函数型接口那样,命令通常用作 lambda 或者方法引用: + +```java +Command command = context -> { + return 0; +}; +``` + +这个整数相当于命令的结果。 通常,小于或等于零的值表示命令失败,什么也不做。 正数则表示命令执行成功并做了一些事情。 Brigadier 提供了一个常量来表示执行成功:`Command#SINGLE_SUCCESS`。 + +### `ServerCommandSource` 可以做什么? {#what-can-the-servercommandsource-do} + +`ServerCommandSource` 提供了命令运行时的一些额外的上下文,有特定实现, 包括获取运行这个命令的实体、命令执行时所在的世界以及服务器。 + +可以通过在 `CommandContext` 实例上调用 `getSource()` 方法来获得命令上下文中的命令来源。 + +```java +Command command = context -> { + ServerCommandSource source = context.getSource(); + return 0; +}; +``` + +## 注册一个基本命令{#registering-a-basic-command} + +可以通过 Fabric API 提供的 `CommandRegistrationCallback` 来注册命令 。 + +:::info +关于如何注册回调,请查看[事件](../events) 指南。 +::: + +该事件应要在你的模组的[入口点](./getting-started/project-structure#entrypoints)中注册。 + +这个回调有三个参数: + +- `CommandDispatcher dispatcher` - 用于注册、解析和执行命令。 `S` 是命令派发器支持的命令源的类型。 +- `CommandRegistryAccess registryAccess` - 为可能传入特定命令参数的注册表提供抽象方法 +- `CommandManager.RegistrationEnvironment environment` - 识别命令将要注册到的服务器的类型。 + +在模组的入口点中,我们只注册两个简单的命令: + +@[code lang=java transcludeWith=:::test_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +在 `sendFeedback()` 方法之中,第一个参数是要发送的文本, 是 `Supplier`,以避免在不必要时实例化 Text 对象。 + +第二个参数决定是否广播反馈给其他的管理员。 一般来讲,如果命令是查询一些东西而不实际改变世界,比如查询世界的时间或者玩家的分数,则应该是 `false`。 如果命令实际上做了些事情,例如改变时间或者修改一些人的分数,则应该是 `true`。 + +如果命令失败,可以不必调用 `sendFeedback()`,而是直接抛出任何异常,服务器和客户端会适当处理。 + +通常抛出 `CommandSyntaxException` 异常来指示命令或参数中的语法错误。 你也可以实现你自己的异常。 + +要执行这个命令,必须输入 `/test_command`,这是大小写敏感的。 + +:::info +这里也说下,我们会把写在传入 `.execute()` 构造器中的 lambda 中的逻辑,写到单独的方法中。 然后给 `.execute()` 传入方法引用。 这样做是为了更清晰。 +::: + +### 注册环境{#registration-environment} + +如有需要,你可以确保命令仅在一些特定情况下注册,例如仅在专用的环境中: + +@[code lang=java highlight={2} transcludeWith=:::dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_dedicated_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +### 命令要求{#command-requirements} + +假如说你希望命令只有管理员可以执行, 这时就要用到 `requires()` 方法。 `requires()` 方法有一个 `Predicate` 参数,提供一个 `ServerCommandSource` 以检测并确定 `CommandSource` 能否执行命令。 + +@[code lang=java highlight={3} transcludeWith=:::required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_required_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +这个命令只会在命令源至少为 2 级管理员(包括命令方块)时才会执行, 否则,命令不会被注册。 + +这样做的副作用就是,非 2 级管理员会看到命令不会被 tab 补全, 这也就是为什么没有启用作弊时不能够 tab 补全大多数命令。 + +### 子命令{#sub-commands} + +要添加子命令,你需要先照常注册第一个字面节点。 为拥有子命令,需要把下一个节点追加到已经存在的节点后面。 + +@[code lang=java highlight={3} transcludeWith=:::sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_sub_command_one](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +类似于参数,子命令节点也可以设置为可选的。 在下面这个例子中,`/command_two` 和 `/command_two sub_command_two` 都是有效的。 + +@[code lang=java highlight={2,8} transcludeWith=:::sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_command_sub_command_two](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 客户端命令{#client-commands} + +Fabric API 有个 `ClientCommandManager`,位于 `net.fabricmc.fabric.api.client.command.v2` 包中,可用于注册客户端命令。 代码应该仅存在于客户端的代码中。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) + +## 命令重定向{#command-redirects} + +命令重定向(也称为别名)是将一个命令的功能重定向到另一个命令的方法。 这在您想更改命令名称但仍希望支持旧名称时非常有用。 + +:::warning +Brigadier [只会重定向有参数的命令节点](https://github.com/Mojang/brigadier/issues/46)。 如果需要重定向没有参数的命令节点,给 `.execute()` 构造器提供一个到相同逻辑的引用,就像这个例子中。 +::: + +@[code lang=java transcludeWith=:::redirect_command](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code lang=java transcludeWith=:::execute_redirected_by](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 常见问题{#faq} + +### 为什么我的代码为什么不编译? {#why-does-my-code-not-compile} + +- 捕捉或抛出 `CommandSyntaxException` - `CommandSyntaxException` 不是 `RuntimeException`, 如果抛出,则抛出的地方所在方法必须在方法签名中也抛出 `CommandSyntaxException`,或者捕获。 + Brigadier 会处理已检查的异常,并在游戏内为你转发适当的错误消息。 + +- 泛型问题 -你可能遇到了泛型问题。 如果你在注册服务器命令(大多数情况都是如此),确保你在静态导入中使用 `CommandManager.literal` 或 `CommandManager.argument` 而不是`LiteralArgumentBuilder.literal` 或 `RequiredArgumentBuilder.argument`。 + +- 检查 `sendFeedback()` 方法 - 你可能忘记了提供第二个参数(一个布尔值)。 还需要注意,从 Minecraft 1.20 开始,第一个参数是 `Supplier` 而不是 `Text`。 + +- 命令应该返回整数:注册命令时,`executes()` 方法接受一个 `Command` 对象,通常是 lambda。 这个 lambda 应该返回整数,而不是其他的类型。 + +### 可以运行时注册命令吗? {#can-i-register-commands-at-runtime} + +::: warning +You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands +you wish to its `CommandDispatcher`. + +然后需要通过 `CommandManager.sendCommandTree(ServerPlayerEntity)` 向每个玩家再次发送命令树。 + +这是必需的,因为客户端已经缓存了命令树并在登录过程中(或发出管理员数据包时)使用,以用于本地的补全和错误消息。 +::: + +### 可以在运行时取消注册命令吗? {#can-i-unregister-commands-at-runtime} + +::: warning +You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side +effects. + +为简化事情,你需要在 brigadier 中使用反射并移除这个节点, 然后还需要再次使用 `sendCommandTree(ServerPlayerEntity)` 向每个玩家发送命令树。 + +如果不发送更新的命令树,客户端可能还是会认为命令依然存在,即使服务器无法执行。 +::: diff --git a/versions/1.21/translated/zh_cn/develop/commands/suggestions.md b/versions/1.21/translated/zh_cn/develop/commands/suggestions.md new file mode 100644 index 000000000..13ecb6498 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/commands/suggestions.md @@ -0,0 +1,49 @@ +--- +title: 命令建议 +description: 学习如何向用户建议命令参数的值。 +authors: + - IMB11 +--- + +# 命令建议{#command-suggestions} + +Minecraft 有个强大的命令建议系统,用在很多地方,例如 `/give` 命令中。 该系统允许您向用户建议命令参数的值,然后他们可以从中选择——这是使你的命令更加用户友好且用起来舒适的好办法。 + +## 建议提供器{#suggestion-providers} + +`SuggestionProvider` 用于制作将会发送至客户端的建议的列表。 建议提供器是一个函数式接口,接收一个 `CommandContext` 和 `SuggestionBuilder` 并返回 `Suggestions`。 `SuggestionProvider` 返回 `CompletableFuture`,因为这些建议并不一定立即可用。 + +## 使用建议提供器{#using-suggestion-providers} + +要使用建议提供器,你需要在 argument builder 中调用 `suggests` 方法。 此方法接收一个 `SuggestionProvider`,返回一个附加了新的建议提供器的 argument builder。 + +@[code java highlight={4} transcludeWith=:::command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +## 内置的建议提供器{#built-in-suggestion-providers} + +你可以使用一些内置的建议提供器: + +| 建议提供器 | 描述 | +| ----------------------------------------- | ------------ | +| `SuggestionProviders.SUMMONABLE_ENTITIES` | 建议所有可召唤的实体。 | +| `SuggestionProviders.AVAILABLE_SOUNDS` | 建议所有可播放的声音。 | +| `LootCommand.SUGGESTION_PROVIDER` | 建议所有可用的战利品表。 | +| `SuggestionProviders.ALL_BIOMES` | 建议所有可用的生物群系。 | + +## 创建自定义的建议提供器{#creating-a-custom-suggestion-provider} + +如果内置的建议提供器无法满足你的需要,可以创建自己的建议提供器。 为此,需要创建一个实现 `SuggestionProvider` 接口的类,并重写 `getSuggestions` 方法。 + +对此示例,我们需要制作一个建议提供器,建议所有在服务器上的玩家的名称。 + +@[code java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) + +要使用这个建议提供器,只需将一个实例传递到参数构造器的 `.suggests` 方法。 + +@[code java highlight={4} transcludeWith=:::command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) +@[code java transcludeWith=:::execute_command_with_custom_suggestions](@/reference/1.21/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) + +显然,建议提供器能够更复杂,因为还可以读取命令上下文以根据命令的状态(例如已经提供的参数)提供建议。 + +这可以是读取玩家的背包或提示玩家附近的物品或实体的形式。 diff --git a/versions/1.21/translated/zh_cn/develop/entities/damage-types.md b/versions/1.21/translated/zh_cn/develop/entities/damage-types.md new file mode 100644 index 000000000..4597bbcff --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/entities/damage-types.md @@ -0,0 +1,96 @@ +--- +title: 伤害类型 +description: 学习如何添加自定义伤害类型。 +authors: + - dicedpixels + - hiisuuii + - mattidragon +--- + +# 伤害类型{#damage-types} + +伤害类型定义了实体能受到的伤害的种类。 从 Minecraft 1.19.4 开始,创建新的伤害类型的方式已是数据驱动,也就是说由 JSON 文件创建。 + +## 创建伤害类型{#creating-a-damage-type} + +让我们创建一种叫 _土豆_ 的伤害类型。 我们先从为你的自定义伤害创建 JSON 文件开始。 这个文件放在你的模组的 `data` 目录下的 `damage_type` 子目录。 + +```:no-line-numbers +resources/data/fabric-docs-reference/damage_type/tater.json +``` + +其结构如下: + +@[code lang=json](@/reference/1.21/src/main/generated/data/fabric-docs-reference/damage_type/tater.json) + +这个自定义伤害类型在玩家每次受到来自非玩家的生物(例:方块)造成的伤害时增加 0.1 [消耗度](https://zh.minecraft.wiki/w/饥饿#饥饿因素)。 此外,造成的伤害量将随世界难度而变化。 + +::: info + +所有可用的键值详见 [Minecraft Wiki](https://zh.minecraft.wiki/w/伤害类型/JSON格式)。 + +::: + +### 通过代码访问伤害类型{#accessing-damage-types-through-code} + +当需要在代码中访问我们的自定义伤害类型时,可以用它的 `RegistryKey` 来创建一个 `DamageSource` 实例。 + +这个 `RegistryKey` 可用以下方式获取: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/FabricDocsReferenceDamageTypes.java) + +### 使用伤害类型{#using-damage-types} + +为了演示自定义伤害类型如何使用,我们将使用一个自定义方块 _土豆块_ 。 让我们实现生物踩在 _土豆块_ 上时会造成 _土豆_ 伤害。 + +你可以重写 `onSteppedOn` 方法来造成这个伤害。 + +我们从创建一个属于我们的自定义伤害类型的 `DamageSource` 开始。 + +@[code lang=java transclude={21-24}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +然后,调用 `entity.damage()` 并传入我们的 `DamageSource` 和伤害量。 + +@[code lang=java transclude={25-25}](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +方块的完整实现: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/damage/TaterBlock.java) + +现在,每当生物踩在我们的自定义方块上时,都将受到使用我们的自定义伤害类型的 5 点伤害(2.5 颗心)。 + +### 自定义死亡消息{#custom-death-message} + +你可以在你的模组的 `en_us.json` 文件中以 `death.attack.` 的格式定义伤害类型的死亡信息。 + +@[code lang=json transclude={4-4}](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/lang/en_us.json) + +当死因是我们的伤害类型时,你将会看到如下的死亡信息: + +![玩家物品栏内的效果](/assets/develop/tater-damage-death.png) + +### 伤害类型标签{#damage-type-tags} + +有些伤害类型能够无视护甲、无视状态效果等等。 伤害类型的这些属性是由标签控制的。 + +你可以在 `data/minecraft/tags/damage_type` 中找到既有的伤害类型标签。 + +::: info + +全部伤害类型的列表详见 [Minecraft Wiki](https://zh.minecraft.wiki/w/标签#伤害类型)。 + +::: + +让我们把我们的土豆伤害类型加入伤害类型标签 `bypasses_armor`。 + +要将我们的伤害类型加入这些标签,需要在 `minecraft` 命名空间下创建一个 JSON 文件。 + +```:no-line-numbers +data/minecraft/tags/damage_type/bypasses_armor.json +``` + +包含以下内容: + +@[code lang=json](@/reference/1.21/src/main/generated/data/minecraft/tags/damage_type/bypasses_armor.json) + +将 `replace` 设置为 `false` 以确保你的标签不会替换既有的标签。 diff --git a/versions/1.21/translated/zh_cn/develop/entities/effects.md b/versions/1.21/translated/zh_cn/develop/entities/effects.md new file mode 100644 index 000000000..fc3361085 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/entities/effects.md @@ -0,0 +1,86 @@ +--- +title: 状态效果 +description: 学习如何添加自定义状态效果。 +authors: + - dicedpixels + - YanisBft + - FireBlast + - Friendly-Banana + - SattesKrokodil + - Manchick0 +authors-nogithub: + - siglong + - tao0lu +--- + +# 状态效果{#status-effects} + +状态效果,又称效果,是一种可以影响实体的状况, 可以是正面、负面或中性的。 游戏本体通过许多不同的方式应用这些效果,如食物和药水等等。 + +命令 `/effect` 可用来给实体应用效果。 + +## 自定义状态效果{#custom-status-effects} + +在这篇教程中我们将加入一个叫 _土豆_ 的新状态效果,每游戏刻给你 1 点经验。 + +### 继承 `StatusEffect`{#extend-statuseffect} + +让我们通过继承所有状态效果的基类 `StatusEffect` 来创建一个自定义状态效果类。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/TaterEffect.java) + +### 注册你的自定义状态效果{#registering-your-custom-effect} + +与注册方块和物品类似,我们使用 `Registry.register` 将我们的自定义状态效果注册到 `STATUS_EFFECT` 注册表。 这可以在我们的初始化器内完成。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/effect/FabricDocsReferenceEffects.java) + +### 纹理{#texture} + +状态效果的图片是一个 18x18 的 PNG,显示在玩家的背包中。 将你的自定义图标放在: + +```:no-line-numbers +resources/assets/fabric-docs-reference/textures/mob_effect/tater.png +``` + +示例纹理 + +### 翻译{#translations} + +像其它翻译一样,你可以在语言文件中添加一个 ID 格式的条目 `"effect..": "Value"`。 + +```json +{ + "effect.fabric-docs-reference.tater": "Tater" +} +``` + +### 应用效果{#applying-the-effect} + +不妨看看你会如何将效果应用到实体。 + +::: tip +For a quick test, it might be a better idea to use the previously mentioned `/effect` command: + +```mcfunction +effect give @p fabric-docs-reference:tater +``` + +::: + +要在代码内部应用状态效果,需要使用 `LivingEntity#addStatusEffect` 方法,接收一个 `StatusEffectInstance` 实例,返回布尔值,以表示效果是否成功应用了。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/ReferenceMethods.java) + +| 参数 | 类型 | 描述 | +| ----------- | ----------------------------- | --------------------------------------------------------------------------- | +| `effect` | `RegistryEntry` | 代表效果的注册表项。 | +| `duration` | `int` | 效果的时长,单位为**刻**,而非**秒** | +| `amplifier` | `int` | 效果等级的倍率。 不是与效果的**等级**直接对应,而是有增加的。 比如,`amplifier` 为 `4` => 等级为 `5` | +| `ambient` | `boolean` | 这个有些棘手, 基本上是指定效果是由环境(比如**信标**)施加的,没有直接原因。 如果是 `true`,HUD内的效果图标会以青色覆盖层的形式出现。 | +| `particles` | `boolean` | 是否显示粒子。 | +| `icon` | `boolean` | 是否在 HUD 中显示效果的图标。 效果会在物品栏中显示,无论其设置的属性。 | + +:::info +要创建使用此效果的药水,请参阅[药水](../items/potions)指南。 +::: diff --git a/versions/1.21/translated/zh_cn/develop/events.md b/versions/1.21/translated/zh_cn/develop/events.md new file mode 100644 index 000000000..612d99920 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/events.md @@ -0,0 +1,122 @@ +--- +title: 事件 +description: Fabric API 提供的事件的使用指南。 +authors: + - dicedpixels + - mkpoli + - daomephsta + - solidblock + - draylar + - jamieswhiteshirt + - PhoenixVX + - Juuxel + - YanisBft + - liach + - natanfudge +authors-nogithub: + - stormyfabric +--- + +# 事件{#events} + +Fabric API 提供了一个系统,允许模组对行为或发生的事(也被定义为游戏中发生的_事件_)做出反应。 + +事件是一种 Hook ,可满足常见的使用情况,并且增强和优化多个模组间对于同一代码区间的 Hook 的兼容性。 使用事件往往就可以替代 mixin 的使用。 + +Fabric API 为 Minecraft 代码库中的重要区域提供事件,许多模组制作者可能有兴趣将其接入。 + +事件由 `net.fabricmc.fabric.api.event.Event` 实例表示,该实例存储并调用_回调(CallBack)_。 一个回调通常只有一个事件实例,存储在回调接口的静态字段 `EVENT` 中,但也有其他可能。 例如,`ClientTickEvents` 会为多个相关连的事件分组。 + +## 回调{#callbacks} + +回调是作为参数传递给事件的一段代码。 当游戏触发事件时,将执行所传递的代码。 + +### 回调接口{#callback-interfaces} + +每个事件都有一个对应的回调接口,通常命名为 `Callback`。 回调是通过在事件实例上调用 `register()` 方法注册的,其参数为一个回调接口的实例。 + +Fabric API 提供的所有事件回调接口,可见 `net.fabricmc.fabric.api.event` 包。 + +## 监听事件{#listening-to-events} + +这个例子注册一个 `AttackBlockCallback`,当玩家徒手击打不掉落物品的方块时,伤害玩家。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +### 将物品添加到已存在的战利品表{#adding-items-to-existing-loot-tables} + +有时,你可能需要向战利品表中添加物品。 例如,为原版方块或实体添加掉落物。 + +最简单的解决方案是替换战利品表文件,但这可能会破坏其他模组的兼容性: 如果他们也想修改呢? 让我们来看看如何在不覆盖战利品表的情况下将物品添加到战利品表中。 + +我们将会把添加鸡蛋到煤炭矿石的战利品表里。 + +#### 监听战利品表加载{#listening-to-loot-table-loading} + +Fabric API 有一个在加载战利品表时触发的事件,即 `LootTableEvents.MODIFY`。 可以在你的模组的[初始化器](./getting-started/project-structure#entrypoints)中注册回调。 我们还要检查一下监听的战利品表是否是煤炭矿石战利品表。 + +@[code lang=java transclude={38-40}](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +#### 将物品添加到战利品表{#adding-items-to-the-loot-table} + +在战利品表中,物品存储在_战利品池条目_,条目存储在_战利品池_。 要添加物品,我们需要在战利品表中添加一个带有物品条目的池。 + +我们可以使用 `LootPool#builder` 来创建一个战利品池,并将其添加到战利品表中。 + +我们的战利品池中没有任何项目,因此我们将使用 `ItemEntry#builder` 创建一个物品条目,并将其添加到战利品池中。 + +@[code highlight={6-7} transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +## 自定义事件{#custom-events} + +游戏中某些区域并没有 Fabric API 提供的事件,因此需要使用 mixin 或者创建自己的事件。 + +我们将创建一个在羊剪毛时触发的事件。 创建事件的过程是: + +- 创建事件回调接口 +- 从 mixin 触发事件 +- 创建测试实现 + +### 创建事件回调接口{#creating-the-event-callback-interface} + +事件回调接口描述了您监听的事件必须实现哪些功能, 同时也描述了我们如何从 mixin 中调用这个事件。 通常在回调接口中创建一个 `Event` 字段作为我们实际事件的唯一标识符。 + +对于我们 `Event` 的实现,我们选择用数组来存储他们。 该数组将包含所有监听这个事件的监听器。 + +我们实现这个事件时,将依次调用这个数组中的所有监听器,直到某个监听器返回非 `ActionResult.PASS`。 这意味着一个监听器可以使用返回值表明“_取消_”、“_批准_”或者“_无所谓,交给下一个监听器处理_”。 + +使用 `ActionResult` 作为返回值是各个事件处理器之间的常规协作方式。 + +您将需要创建一个带有 `Event` 实例和响应实现方法的接口。 一个典型的剪羊毛回调像是这样: + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +让我们更深入地看看。 当 invoker 被调用时,我们将遍历所有监听器: + +@[code lang=java transclude={21-22}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +然后在监听器上调用我们的方法(在本例中为 `interact`)来获取响应: + +@[code lang=java transclude={33-33}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +如果监听器决定我们必须取消(`ActionResult.FAIL`)或者完成(`ActionResult.SUCCESS`)这个事件,回调将返回这个结果,并且结束循环。 `ActionResult.PASS` 将继续触发下一个监听器,并且在绝大多数没有注册多个监听器的情况下都应该返回 `ActionResult.SUCCESS`: + +@[code lang=java transclude={25-30}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +我们可以在回调类的顶部添加 Javadoc 注释注明每一种 `ActionResult` 的作用。 在本例中,它应该是这样的: + +@[code lang=java transclude={9-16}](@/reference/1.21/src/main/java/com/example/docs/event/SheepShearCallback.java) + +### 从 mixin 中触发事件{#triggering-the-event-from-a-mixin} + +我们现在有基本的事件框架了,但还需要触发它。 我们希望在玩家试图剪羊毛时调用事件,所以我们要在当 `SheepEntity#interactMob` 中的`sheared()` 被调用时去调用事件的 `invoker`(例如:羊可以被剪毛且玩家手持剪刀) + +@[code lang=java transcludeWith=:::](@/reference/1.21/src/main/java/com/example/docs/mixin/event/SheepEntityMixin.java) + +### 创建测试实现{#creating-a-test-implementation} + +现在我们需要测试一下我们的事件。 你可以在初始化方法(如果需要,在其他区域也可以)中注册监听器,并在其中添加自定义逻辑。 这里有一个例子——羊的脚上掉落的不是羊毛,而是一颗钻石: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/event/FabricDocsReferenceEvents.java) + +如果你进入游戏并剪羊毛,掉落的应该是钻石而不是羊毛。 diff --git a/versions/1.21/translated/zh_cn/develop/getting-started/creating-a-project.md b/versions/1.21/translated/zh_cn/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..2d62769dd --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/getting-started/creating-a-project.md @@ -0,0 +1,71 @@ +--- +title: 创建项目 +description: 关于如何使用 Fabric 模板模组生成器创建新的模组项目的逐步指南。 +authors: + - IMB11 + - Cactooz +--- + +# 创建项目{#creating-a-project} + +Fabric 提供了一种简单的方法来使用 Fabric 模板模组生成器来创建新的模组项目——如果你愿意,你可以使用示例模组代码仓库手动创建一个新项目,请参考 [手动创建项目](#manual-project-creation) 章节。 + +## 生成项目{#generating-a-project} + +你可以使用 [Fabric 模板模组生成器](https://fabricmc.net/develop/template/)为你的模组生成一个新项目——你应该填写必要的字段,比如模组称和包名,以及你想要基于其开发的 Minecraft 版本。 + +包名应该是小写字母,由点隔开;命名必须唯一,以避免和其他开发者的包冲突。 通常是网络域名的反向,例如 `com.example.modid`。 + +![生成器预览图](/assets/develop/getting-started/template-generator.png) + +如果要使用 Kotlin 语言,或使用 Mojang 的官方映射而非 Yarn 映射,或需要添加数据生成,可以在 “Advanced Options”中选择适当的选项。 + +![“Advanced Options”部分](/assets/develop/getting-started/template-generator-advanced.png) + +填写好了必需的字段后,单击“Generate”按钮,生成器将以 zip 文件的形式创建新项目供你使用。 + +你需要将这个 zip 文件解压到你想要的位置,然后在 IntelliJ IDEA 中打开解压的文件夹: + +![打开项目按钮提示](/assets/develop/getting-started/open-project.png) + +## 导入项目{#importing-the-project} + +在 IntelliJ IDEA 中打开该项目之后,IDEA 会自动加载项目的 Gradle 配置并执行必要的初始化任务。 + +如果收到一个关于 Gradle 构建脚本的通知,应该点击 `Import Gradle Project` 按钮以导入Gradle项目: + +![Gradle 按钮提示](/assets/develop/getting-started/gradle-prompt.png) + +项目导入好之后,你可以在项目资源管理器中看到项目的文件,就能够开始开发你的模组了。 + +## 手动创建项目{#manual-project-creation} + +:::warning +你需要安装 [Git](https://git-scm.com/) 来克隆示例模组代码仓库。 +::: + +如果不能使用 Fabric 模板模组生成器,可以按以下步骤手动创建新项目。 + +首先,使用 Git 克隆示例模组代码仓库: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +这会将代码仓库克隆进一个叫 `my-mod-project`的新文件夹。 + +然后应该删除 `.git` 文件夹,并在 IntelliJ IDEA 中打开项目。 如果找不到 `.git` 文件夹,你需要在你的文件资源管理器中启用显示隐藏文件。 + +在 IntelliJ IDEA 中打开了项目之后,IDEA 会自动加载项目的 Gradle 配置并执行必要的初始化任务。 + +强调一遍,如上所述,如果你收到一个关于 Gradle 构建脚本的通知,你应该点击 `Import Gradle Project` 按钮: + +### 修改模板{#modifying-the-template} + +项目导入好后,你需要修改项目的详细信息,以匹配你的模组的信息: + +- 修改项目的 `gradle.properties` 文件,把 `maven_group` 和 `archive_base_name` 修改为匹配你的模组的信息。 +- 修改项目中的 `fabric.mod.json` 文件,把 `id`、`name` 和 `description` 修改为匹配你的模组的信息。 +- 确保更新 Minecraft、映射、Fabric Loader 和 Fabric Loom 的版本——所有这些都可以通过 查询,以匹配你希望的目标版本。 + +你还可以修改包名和模组的主类来匹配你的模组的详细信息设定。 diff --git a/versions/1.21/translated/zh_cn/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/zh_cn/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..d9ae32135 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Fabric 和模组简介 +description: Minecraft:Java 版中 Fabric 和模组的简要介绍。 +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Fabric 和模组简介 {#introduction-to-fabric-and-modding} + +## 先决条件 {#prerequisites} + +在开始学习之前,你应该对 Java 开发有基本的了解,并对面向对象编程(OOP)有所认识。 + +如果你不熟悉这些概念,在开始开发之前,你可能需要了解一些有关 Java 和 OOP 的教程,以下是可以用来学习 Java 和 OOP 的一些资源: + +- [W3: Java Tutorials](https://www.w3schools.com/java/) +- [Codecademy: Learn Java](https://www.codecademy.com/learn/learn-java) +- [W3: Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium: Introduction to OOP](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### 术语 {#terminology} + +开始之前,先来看看使用 Fabric 编写模组时会遇到的一些术语: + +- **模组(Mod)**: 对游戏的修改,添加新功能或更改现有功能。 +- **模组加载器(Mod Loader)**: 将模组载入游戏的工具,例如 Fabric Loader。 +- **Mixin**: 运行时修改游戏代码的工具——更多信息请参阅 [Mixin 介绍](https://fabricmc.net/wiki/zh_cn::tutorial:mixin_introduction) 。 +- **Gradle**: 用于构建和编译模组的自动化构建工具,Fabric 用其构建模组。 +- **映射(Mappings)**: 将被混淆的代码转化为人类可读代码的映射的集合。 +- **混淆(Obfuscation)**: 使代码无法被人类阅读的过程,Mojang 用其来保护 Minecraft 的源代码。 +- **重映射(Remapping)**: 将混淆代码映射为人类可读代码的过程。 + +## Fabric 是什么? {#what-is-fabric} + +Fabric 是用于 Minecraft: Java Edition 的轻量级模组开发工具链。 + +Fabric 旨在成为简单易用的模组开发平台。 Fabric 是由社区驱动的项目,而且开源,这意味着任何人都可以为项目做出贡献。 + +你应该了解的 Fabric 的四个主要组成部分: + +- **Fabric Loader**: 灵活的独立于平台的模组加载器,专为 Minecraft 及其他游戏和应用程序而设计。 +- **Fabric Loom**:Gradle 插件,使开发者能够轻松开发和调试模组。 +- **Fabric API**:一套 API 和工具,供模组开发者在创建模组时使用。 +- **Yarn**: 一套开放的 Minecraft 映射表,在 Creative Commons Zero 许可证下供所有人任意使用。 + +## 为什么开发 Minecraft 模组需要 Fabric? {#why-is-fabric-necessary-to-mod-minecraft} + +> “模组(Modding)”是指修改游戏以改变其行为或添加新功能的过程,就 Minecraft 而言,这可以是添加新物品、方块或实体,也可以是改变游戏机制或添加新的游戏模式。 + +Minecraft: Java Edition 被 Mojang 混淆,因此很难单独修改。 不过,在 Fabric 等模组开发工具的帮助下,修改变得更加容易。 有一些映射系统可以协助这一过程。 + +Loom 使用这些映射将混淆代码重映射为人类可读的格式,使模组开发者更容易理解和修改游戏代码。 在这方面,Yarn 是一个富有人气且十分优秀的映射选择,但也有其他选择。 每个映射表项目都有自己的优势和侧重点。 + +Loom 可让你轻松开发且编译重映射模组的代码,而 Fabric Loader 可让你将这些模组加载到游戏中。 + +## Fabric API 提供哪些功能,为什么需要它? {#what-does-fabric-api-provide-and-why-is-it-needed} + +> Fabric API 是一套 API 和工具,供模组开发者在创建模组时使用。 + +Fabric API 在 Minecraft 现有功能的基础上提供了一系列使开发更方便的 API。例如,提供新的 Hook 和事件供开发者使用,或提供新的实用程序和工具让魔改变得更容易,如访问加宽器(Access Wideners)和访问内部注册表(如可堆肥物品注册表)的能力。 + +虽然 Fabric API 提供了强大的功能,但有些任务,如基本的方块注册,不使用 Fabric API 也能完成。 diff --git a/versions/1.21/translated/zh_cn/develop/getting-started/launching-the-game.md b/versions/1.21/translated/zh_cn/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..b623c8ffe --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/getting-started/launching-the-game.md @@ -0,0 +1,72 @@ +--- +title: 启动游戏 +description: 了解如何利用各种启动配置文件在实时游戏环境中启动和调试你的模组。 +authors: + - IMB11 + - Tenneb22 +--- + +# 启动游戏{#launching-the-game} + +Fabric Loom 提供了各种启动配置文件,可以帮助你在实时游戏环境中启动以及调试你的模组。 本指南将介绍各种启动配置文件以及如何用它们来调试和在游戏中测试你的模组。 + +## 启动配置文件{#launch-profiles} + +如果在使用 IntelliJ IDEA,那么可以从窗口右上角找到启动配置文件。 单击下拉菜单可以查看可用的启动配置文件。 + +应该有一个客户端和服务器配置文件,可以选择正常运行或在调试模式下运行它: + +![启动配置文件](/assets/develop/getting-started/launch-profiles.png) + +## Gradle 任务{#gradle-tasks} + +如果使用的是命令行,则可以使用以下 Gradle 命令启动游戏: + +- `./gradlew runClient` - 以客户端模式启动游戏。 +- `./gradlew runServer` - 以服务器模式启动游戏。 + +这种方法的唯一问题是无法轻松调试代码。 如果要调试代码,则需要使用 IntelliJ IDEA 中的启动配置文件或通过你所使用的 IDE 中的 Gradle 集成。 + +## 热交换类{#hotswapping-classes} + +在调试模式下运行游戏时,可以热交换你的类而无需重启游戏。 这对于快速测试代码的更改很有用。 + +但你仍然受到很大限制: + +- 你无法添加或移除方法 +- 你无法更改方法参数 +- 你无法添加或移除字段 + +但是,通过使用 [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime),你可以绕过大部分限制,甚至可以添加或删除类和方法。 这样大多数更改无需重启游戏即可生效。 + +不要忘记在 Minecraft 运行配置中的 VM 参数选项中添加以下内容: + +```:no-line-numbers +-XX:+AllowEnhancedClassRedefinition +``` + +## 热交换 Mixin{#hotswapping-mixins} + +如果正在使用 Mixin,则可以热交换 Mixin 类而无需重启游戏。 这对于快速测试 Mixin 的更改很有用。 + +但是你需要安装 Mixin Java 代理才能使其正常工作。 + +### 1. 找到 Mixin 库 Jar{#1-locate-the-mixin-library-jar} + +在 IntelliJ IDEA 中,你可以在“项目”部分的“外部库”部分中找到 mixin 库 jar: + +![Mixin 库](/assets/develop/getting-started/mixin-library.png) + +你需要复制 jar 的“绝对路径”以供下一步使用。 + +### 2. 添加 `-javaagent` VM 参数{#2-add-the--javaagent-vm-argument} + +在你的“Minecraft 客户端”和/或“Minecraft 服务器”运行配置中,将以下内容添加到 VM 参数选项: + +```:no-line-numbers +-javaagent:"此处为 mixin 库 jar 的路径" +``` + +![VM 参数屏幕截图](/assets/develop/getting-started/vm-arguments.png) + +现在,你应该能够在调试期间修改 mixin 方法的内容,并且无需重启游戏即可使更改生效。 diff --git a/versions/1.21/translated/zh_cn/develop/getting-started/project-structure.md b/versions/1.21/translated/zh_cn/develop/getting-started/project-structure.md new file mode 100644 index 000000000..4f240d9c2 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/getting-started/project-structure.md @@ -0,0 +1,64 @@ +--- +title: 项目结构 +description: Fabric 模组项目结构概述 +authors: + - IMB11 +--- + +# 项目结构{#project-structure} + +本页将介绍 Fabric 模组项目的结构以及项目中每个文件和文件夹的用途。 + +## `fabric.mod.json`{#fabric-mod-json} + +`fabric.mod.json` 是向 Fabric Loader 描述你的模组的主要文件, 包含模组的 ID、版本、依赖等信息。 + +`fabric.mod.json` 文件最重要的字段是: + +- `id`:模组的 ID,必须是独特的,不能和其他模组重复。 +- `name`:模组的显示名称。 +- `environment`:模组运行环境,可以是 `client`(仅客户端)、`server`(仅服务端)和 `*`(双端)。 +- `entrypoints`:模组提供的入口点,例如 `main` 和 `client` 等。 +- `depends`:模组的依赖模组/库。 +- `mixins`:模组提供的 Mixin。 + +下面看到的是示例的 `fabric.mod.json` 文件——这是该文档的开发参考项目的 `fabric.mod.json` 文件。 + +:::details 参考项目 `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## 入口点{#entrypoints} + +如前所述,`fabric.mod.json` 文件包含一个名为 `entrypoints` 的字段——该字段用于指定你的模组提供的入口点。 + +默认情况下,模板模组生成器会同时创建 `main` 和 `client` 入口点: + +- `main`入口点用于通用代码,它包含在一个实现了 `ModInitializer` 的类中; +- `client`入口点用于特殊的仅客户端的代码,并且其实现 `ClientModInitializer`。 + +这些入口点将会在游戏启动时依次调用。 + +这是一个简单的 `main` 入口点的使用示例,会在游戏开始时记录一条消息到控制台: + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +## `src/main/resources`{#src-main-resources} + +`src/main/resources` 用于存储模组的资源文件,例如纹理、模型和声音。 + +它也是 `fabric.mod.json` 和模组使用的 Mixin 配置文件的存放位置。 + +资源文件存储在与资源包结构相似的结构中——例如,方块的纹理会存放在 `assets/modid/textures/block/block.png` 中。 + +## `src/client/resources`{#src-client-resources} + +`src/client/resources` 文件夹用于存储客户端特定的资源,例如仅在客户端使用的纹理、模型和音效。 + +## `src/main/java`{#src-main-java} + +`src/main/java` 文件夹用于存储模组的 Java 源代码——在客户端和服务端环境中都存在。 + +## `src/client/java`{#src-client-java} + +`src/client/java` 文件夹用于存储客户端专属的 Java 源代码,例如渲染代码或客户端逻辑——例如方块颜色提供程序。 diff --git a/versions/1.21/translated/zh_cn/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/zh_cn/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..38b69bb85 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: 设置开发环境 +description: 关于如何搭建 Fabric 开发环境的逐步指南。 +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# 设置开发环境{#setting-up-a-development-environment} + +要开始使用 Fabric 开发模组,需要使用 IntelliJ IDEA 设置开发环境。 + +## 安装 JDK 21 {#installing-jdk-21} + +为 Minecraft 1.21 开发模组,需要 JDK 21。 + +如果需要安装 Java 方面的帮助,可以参考[玩家指南部分](../../players/index)中的各种 Java 安装指南。 + +## 安装 IntelliJ IDEA{#installing-intellij-idea} + +:::info +你显然可以使用其他 IDE, 比如 Eclipse 或 Visual Studio Code,但本文档站点上的大多数页面都假定你使用的是 IntelliJ IDEA - 如果你使用的是其他 IDE,则应参考那些 IDE 的文档。 +::: + +如果没有安装 IntelliJ IDEA,可以从[官方网站](https://www.jetbrains.com/idea/download/)下载 - 按照你的操作系统的安装步骤操作。 + +IntelliJ IDEA 的社区版是免费且开源的,是使用 Fabric 开发模组的推荐版本。 + +你可能需要向下滚动才能找到社区版下载链接 - 如下所示: + +![IDEA 社区版下载提示](/assets/develop/getting-started/idea-community.png) + +## 安装 IDEA 插件{#installing-idea-plugins} + +这些插件虽然不是绝对必要的,但可以让使用 Fabric 开发模组更容易 - 应该要考虑安装。 + +### Minecraft Development {#minecraft-development} + +Minecraft Development 插件为使用 Fabric 开发模组提供支持,是要安装的最重要的插件。 + +如要安装,可以打开 IntelliJ IDEA,然后在搜索栏中导航到 `文件 > 设置 > 插件 > Marketplace 标签页` - 在搜索框中搜索 `Minecraft Development`,然后点击 `安装` 按钮。 + +或者你可以从[插件页面](https://plugins.jetbrains.com/plugin/8327-minecraft-development)下载,然后依次点击 `文件 > 设置 > 插件 > 从硬盘上安装插件` 来安装。 diff --git a/versions/1.21/translated/zh_cn/develop/ide-tips-and-tricks.md b/versions/1.21/translated/zh_cn/develop/ide-tips-and-tricks.md new file mode 100644 index 000000000..34a4198ee --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/ide-tips-and-tricks.md @@ -0,0 +1,242 @@ +--- +title: IDE 提示和技巧 +description: 让你在 IDE 中高效处理并遍历你的项目的有用信息 +authors: + - JR1811 +--- + +# IDE 提示和技巧{#ide-tips-and-tricks} + +本页面提供一些有用的信息,加速并简化开发者的工作流程。 根据你的喜好自由发挥到你的项目中。 +学习并习惯这些捷径和其他选项可能会花点时间。 你可以以此页面作为参考。 + +:::warning +除非另有说明,本文中所述快捷键均绑定为 Windows 快捷键,并参考 IntelliJ IDEA 的默认按键映射。 +如果你使用不同的键盘布局,请参阅 `文件 > 设置 > 按钮映射` 设置或在其他地方搜索相关功能。 +::: + +## 遍历项目{#traversing-projects} + +### 手动{#manually} + +IntelliJ 有许多不同的方式来遍历项目。 如果你已使用终端中的 `./gradlew genSources` 命令生成源代码或在 Gradle 窗口中使用了 `Tasks > fabric > genSources` Gradle 任务,则可以在项目窗口的外部库中手动浏览 Minecraft 的源文件。 + +![Gradle 任务](/assets/develop/misc/using-the-ide/traversing_01.png) + +如果你在项目窗口的外部库中搜索 `net.minecraft`,则可以找到 Minecraft 源代码。 如果你的项目使用来自在线[模板模组生成器](https://fabricmc.net/develop/template/)的拆分源,则会有两个源,如名称所示(client/common)。 此外,通过 `build.gradle` 文件导入的其他项目源、库和依赖项也将可用。 这种方法常用于浏览资源文件、标签和其他文件。 + +![外部库](/assets/develop/misc/using-the-ide/traversing_02_1.png) + +![拆分源](/assets/develop/misc/using-the-ide/traversing_02_2.png) + +### 搜索{#search} + +按两次 Shift 键可打开“搜索”窗口。 你可以在其中搜索项目的文件和类。 当激活复选框 `包括非项目条目` 或再次按两次 Shift 时,搜索不仅会查找你自己的项目,还会查找其他项目,例如外部库。 + +![搜索窗口](/assets/develop/misc/using-the-ide/traversing_03.png) + +### 最近窗口{#recent-window} + +IntelliJ 中的另一个有用的工具是 `最近` 窗口, 可以使用快捷键 CTRL + E 打开。 在那里可以跳转到已经访问过的文件并打开工具窗口,例如[结构](#structure-of-a-class)或[书签](#bookmarks)窗口。 + +![最近窗口](/assets/develop/misc/using-the-ide/traversing_04.png) + +## 遍历代码{#traversing-code} + +### 跳转至定义/用法{#jump-to-definition-usage} + +如果你需要查看变量、方法、类和其他内容的定义或用法,可以按 CTRL + 左键单击 +或在其名称上使用 鼠标中键(按下鼠标滚轮)。 这样,你就可以避免长时间滚动会话或手动搜索位于另一个文件中的定义。 + +### 书签{#bookmarks} + +你可以为代码行、文件甚至打开的“编辑器”选项卡添加书签。 +特别是在研究源代码时,书签可以帮助你标记将来想要再次快速找到的位置。 + +右键单击 `项目` 窗口、编辑器选项卡或文件中的行号中的文件。 +创建`助记书签`使你能够使用其快捷键 CTRL 和你为其选择的数字快速切换回这些书签。 + +![设置书签](/assets/develop/misc/using-the-ide/traversing_05.png) + +如果你需要分离或排序书签列表,可以在`书签`窗口中同时创建多个书签列表。 +[断点](./basic-problem-solving#breakpoint) 也将显示在那里。 + +![书签窗口](/assets/develop/misc/using-the-ide/traversing_06.png) + +## 分析类{#analyzing-classes} + +### 类的结构{#structure-of-a-class} + +打开`结构`窗口(Alt + 7),可以获得当前活动类的概览。 你可以看到该文件中有哪些类和枚举、实现了哪些方法以及声明了哪些字段和变量。 + +有时,在寻找可能要覆盖的方法时,在“视图”选项顶部激活`继承`选项也会很有帮助。 + +![结构窗口](/assets/develop/misc/using-the-ide/analyzing_01.png) + +### 类的类型层次结构{#type-hierarchy-of-a-class} + +将光标放在类名上并按 CTRL + H,可以打开一个新的类型层次结构窗口,其中显示所有父类和子类。 + +![类型层次结构窗口](/assets/develop/misc/using-the-ide/analyzing_02.png) + +## 代码实用工具{#code-utility} + +### 代码补全{#code-completion} + +代码补全应该默认激活。 你将在编写代码时自动获得建议。 如果不小心关闭或者只是将光标移动到了新的位置,可以使用 CTRL + 空格 再次打开。 + +例如,使用 Lambda 时可以用这种方法快速编写。 + +![具有多个参数的 Lambda](/assets/develop/misc/using-the-ide/util_01.png) + +### 代码生成{#code-generation} + +“生成”菜单可通过 ⌘/CTRLN 快速访问。 +在 Java 文件中,你可以生成构造器、getter、setter、重写或实现方法,等等。 +你还可以生成 accessor 和 invoker,如果有安装了 [Minecraft Development 插件](./getting-started/setting-up-a-development-environment#minecraft-development)的话。 + +此外,你还可以通过 ⌘/CTRLO 快速重写方法,或通过 ⌘/CTRLI 实现方法。 + +![Java 文件中的代码生成菜单](/assets/develop/misc/using-the-ide/generate_01.png) + +在 Java 测试文件中,会有选项生成相关的测试方法,就像下面这样: + +![Java 测试文件中的代码生成菜单](/assets/develop/misc/using-the-ide/generate_02.png) + +### 显示参数{#displaying-parameters} + +显示参数应默认激活。 你将在编写代码时自动获取参数的类型和名称。 +如果不小心关闭或者只是将光标移动到了新的位置,可以使用 CTRL + P 再次打开。 + +方法和类可以有具有不同参数的多个实现,也称为“重载”。 这样,你可以在编写方法调用时决定要使用哪种实现。 + +![显示方法参数](/assets/develop/misc/using-the-ide/util_02.png) + +### 重构{#refactoring} + +重构是在不改变代码运行时功能的情况下重组代码的过程。 安全地重命名和删除部分代码是其中的一部分,但将部分代码提取到单独的方法中以及为重复的代码语句引入新变量等操作也称为“重构”。 + +许多 IDE 都有丰富的工具包来帮助完成这一过程。 在 IntelliJ 中,只需右键单击文件或部分代码即可访问可用的重构工具。 + +![重构](/assets/develop/misc/using-the-ide/refactoring_01.png) + +重构工具“重命名”的快捷键 Shift + F6,习惯之后会非常有用,因为未来你会需要重命名很多东西。 使用这一功能,重命名的代码中每次出现的地方都会被重命名,并保持功能不变。 + +### 查找和替换文件内容{#search-and-replace-file-content} + +有时需要用更简单的工具来编辑代码出现的各个地方。 + +| 按键绑定 | 功能 | +| ------------------------------------------------- | ------------------------ | +| CTRL + F | 在当前文件中查找 | +| CTRL + R | 在当前文件中替换 | +| CTRL + Shift + F | 在更大的范围内查找(可以设置特定的文件类型掩码) | +| CTRL + Shift + R | 在更多的范围内替换(可以设置特定的文件类型掩码) | + +如果启用,还可以使用“[正则表达式](https://zh.wikipedia.org/wiki/正则表达式)”以进行更加专门的样式匹配。 + +![正则表达式替换](/assets/develop/misc/using-the-ide/search_and_replace_01.png) + +## 注释{#comments} + +好的代码应该可读并且[是自解释的](https://bytedev.medium.com/code-comment-anti-patterns-and-why-the-comment-you-just-wrote-is-probably-not-needed-919a92cf6758)。 变量、类、方法选择能清晰表达的名称,这会很有帮助,但有时也需要用注释来留下记录,或者**暂时**把代码禁用以做测试。 + +### 准备快捷键{#prepare-shortcuts} + +要更快地将代码注释掉,打开 IntelliJ 的设置,找到“使用行注释进行注释”和“使用块注释进行注释”,并根据自己的喜好设置按键绑定。 + +![按键映射设置](/assets/develop/misc/using-the-ide/comments_01.png) + +现在你可以高亮必要的代码,并使用快捷键将这一段注释掉。 + +```java +// private static final int PROTECTION_BOOTS = 2; +private static final int PROTECTION_LEGGINGS = 5; +// private static final int PROTECTION_CHESTPLATE = 6; +private static final int PROTECTION_HELMET = 1; +``` + +```java +/* +ModItems.initialize(); +ModSounds.initializeSounds(); +ModParticles.initialize(); +*/ + +private static int secondsToTicks(float seconds) { + return (int) (seconds * 20 /*+ 69*/); +} +``` + +### 区域注释{#region-comments} + +在 IntelliJ 中,在行号旁边,可以会有小的 [+] 和 [-] 图标。 这些可以用于暂时折叠方法、if-语句、类和很多其他东西,如果这些你并不是正在进行工作。 要创建自定义的可以被折叠的块,使用 `region` 和 `endregion` 注释。 + +```java +// region collapse block name + ModBlocks.initialize(); + ModBlockEntities.registerBlockEntityTypes(); + ModItems.initialize(); + ModSounds.initializeSounds(); + ModParticles.initialize(); +// endregion +``` + +![区域折叠](/assets/develop/misc/using-the-ide/comments_02.png) + +:::warning +如果你发现这些用太多了,考虑重构你的代码从而让它更加可读。 +::: + +### TODO 和 FIXME 注释{#todo-and-fixme-notes} + +写代码时,把需要关心的东西留下注释也是很方便的。 有时你可以也注意到代码中有潜在的问题,但是不想停下当前的事情去关注这个问题。 这时,可以使用 `TODO` 或 `FIXME` 注释。 + +![TODO 和 FIXME 注释](/assets/develop/misc/using-the-ide/comments_03.png) + +IntelliJ 会在 `TODO` 窗口中跟踪,并如果在提交使用了这些类型的注释的代码时提醒你。 + +![TODO 和 FIXME 注释](/assets/develop/misc/using-the-ide/comments_04.png) + +![带有 TODO 的提交](/assets/develop/misc/using-the-ide/comments_05.png) + +### Javadoc{#javadocs} + +给你的代码写文档最好的方式是使用 JavaDoc。 JavaDoc 不仅提供方法和类的实现的有用信息,还能与 IntelliJ 深度融合。 + +当鼠标悬念在有添加了 JavaDoc 注释的方法或类名上时,信息窗口中会显示这个信息。 + +![JavaDoc](/assets/develop/misc/using-the-ide/comments_06.png) + +要开始写,先在方法或类的定义上方写上 `/**`,然后按 Enter。 IntelliJ 会自动为返回值及各参数生成行,但你也可以随意改变。 有很多可用的自定义功能,还可以在需要时使用 HTML。 + +Minecraft 的 `ScreenHandler` 类有些例子。 要开启渲染视图,可使用行号旁边的笔按钮。 + +![JavaDoc 编辑](/assets/develop/misc/using-the-ide/comments_07.png) + +## 进一步优化 IntelliJ{#optimizing-intellij-further} + +还有很多捷径和便捷的小技巧,这个页面没有提到。 +Jetbrains 有很多关于如何进一步个性化你的工作空间的讨论、视频和文档页面。 + +### PostFix Completion{#postfix-completion} + +写了代码后,可以用 PostFix Completion 来快速修改。 常用的一些例子有 `.not`、`.if`、`.var`、`.null`、`.nn`、`.for`、`.fori`、`.return` 和 `.new`。 除了这些已有的之外,你也可以在 IntelliJ 的设置中创建你自己的。 + + + +### 实时模板{#live-templates} + +使用实时模板可以更快地生成自定义样板代码。 + + + +### 更多提示和技巧{#more-tips} + +Jetbrains 的 Anthon Arhipov 也有关于正则表达式匹配、代码补全、调试和其他 IntelliJ 话题的深入讨论。 + + + +更多信息请看 [Jetbrains' Tips & Tricks site](https://blog.jetbrains.com/zh-hans/idea/category/tips-tricks/)。 大多数这些帖子都适用于 Fabric 的生态系统中。 + +--- diff --git a/versions/1.21/translated/zh_cn/develop/index.md b/versions/1.21/translated/zh_cn/develop/index.md new file mode 100644 index 000000000..c15bad856 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/index.md @@ -0,0 +1,14 @@ +--- +title: 开发者指南 +description: 我们的社区编写的开发者指南,涵盖一切,从设置你的开发环境,到渲染和网络通信等高级话题。 +--- + +# 开发者指南{#developer-guides} + +本指南由社区编写,包含广泛的主题,从设置你的开发环境,到渲染、网络通信等更高级的内容。 + +完整的指南列表请检查侧边栏。 如果在寻找某个具体的话题,可以使用页面顶部的搜索栏找到你想要的。 + +记住:包含本文档所有代码的完整有效模组可在 [GitHub 中的 `/reference` 文件夹](https://github.com/FabricMC/fabric-docs/tree/main/reference/1.21)中找到。 + +如果想给 Fabric 文档做贡献,可以在 [GitHub](https://github.com/FabricMC/fabric-docs) 找到本项目的源代码,以及相关的[贡献指南](../contributing)。 diff --git a/versions/1.21/translated/zh_cn/develop/items/custom-armor.md b/versions/1.21/translated/zh_cn/develop/items/custom-armor.md new file mode 100644 index 000000000..08ac35604 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/custom-armor.md @@ -0,0 +1,160 @@ +--- +title: 自定义盔甲 +description: 学习如何创建自己的盔甲集。 +authors: + - IMB11 +--- + +# 自定义盔甲{#custom-armor} + +盔甲增强玩家的防御,抵御来自生物和其他玩家的攻击。 + +## 创建盔甲材料类{#creating-an-armor-materials-class} + +和类似于物品和方块类似,盔甲材料也需要注册。 为了组织好,我们创建一个 `ModArmorMaterials` 类存储我们的自定义盔甲材料。 + +需要为这个类添加静态的 `initialize()` 方法,并在你的[模组的初始化器](./getting-started/project-structure#entrypoints)入口点中调用,从而注册这些材料。 + +```java +// Within the ModArmorMaterials class +public static void initialize() {}; +``` + +:::warning +确保在注册你的物品**之前**调用这个方法,因为需要注册了材料才能创建物品。 +::: + +```java +@Override +public void onInitialize() { + ModArmorMaterials.initialize(); +} +``` + +--- + +在这个 `ModArmorMaterials` 类中,你还会需要创建一个静态方法,注册盔甲材料。 这个方块应该会返回材料的一个注册表项,因为这个项会用于 ArmorItem 的构造方法中创建盔甲物品。 + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## 盔甲材料属性{#armor-material-properties} + +:::tip +如果不清楚这些属性的哪些值合适的话,考虑看看 `ArmorMaterials` 中的原版盔甲材料。 +::: + +创建盔甲材料时,你会需要定义以下属性: + +### 防御点{#defense-points} + +:::warning +确保为创建的每种盔甲部分的类型都赋一个值,并注册为物品。 如果为盔甲部分制作物品但没有设置防御点值,游戏会崩溃。 +::: + +`defensePoints` 映射用于定义每个盔甲物品会提供的防御点的数量。 数字越高,盔甲部分提供的保护越多。 这个映射应该包含每个盔甲部分的类型的项。 + +### 附魔能力{#enchantability} + +`enchantability` 属性定义了物品被附魔有多容易。 数字越高,盔甲可以接受更高的附魔。 + +### 装备声音{#equip-sound} + +`equipmentSound` 属性是盔甲装备时会播放的声音。 这个声音应该是 `SoundEvent` 的注册表项。 如果你考虑创建自定义的声音,而不是依靠 `SoundEvents` 类中的原版声音,可以考虑看看[自定义声音事件](../sounds/custom)页面。 + +### 修复原料{#repair-ingredient} + +`repairingIngredientSupplier` 属性是用于修复盔甲的 `Ingredient`(原料)的 supplier。 这个原料什么都可以是,推荐将其保持与事实上用于合成盔甲物品的合成原料相同的材料。 + +### 坚硬度{#toughness} + +`toughness` 属性定义了盔甲会吸收多少伤害。 数字越高,盔甲吸收的伤害越多。 + +### 击退抗性{#knockback-resistance} + +`knockbackResistance` 属性定义了玩家被击中时会反弹多少击退。 数字越高,玩家接收的击退越少。 + +### 可染色{#dyeable} + +`dyable` 属性是布尔值,定义了盔甲是否可染色。 如果设置为 `true`,那么盔甲可以使用染料在工作台中染色。 + +如果选择让你的盔甲可染色,就必须将你的盔甲层和物品纹理_设计为可染色_,因为染料会叠加在纹理上,而不是替代纹理。 看看原版的皮革装备作为示例,纹理是灰度的,染色应用为叠加层,使盔甲改变颜色。 + +## 注册盔甲材料{#registering-the-armor-material} + +现在创建好了注册盔甲材料的实用方法,可以注册你的自定义盔甲材料了,作为 `ModArmorMaterials` 类的静态字段。 + +看这个例子,我们创建 Guidite 盔甲,有以下属性: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +## 创建盔甲物品{#creating-the-armor-items} + +现在材料已经注册了,就可以在你的 `ModItems` 类中创建盔甲物品。 + +显然,盔甲集并不需要满足每种类型,可以让你的集只有靴或护腿等——原版的海龟壳头盔就是个例子,盔甲集缺了部分槽位。 + +### 耐久度{#durability} + +不像 `ToolMaterial`,`ArmorMaterial` 并不储存物品的耐久度信息。 +因此当注册盔甲物品时耐久度需要被手动添加到它的 `Item.Settings` 里。 + +这是使用 `Item.Settings` 类中 `maxDamage` 方法实现的。 +不同的盔甲槽位有不同的基础耐久,通常都会在乘以一个共享的盔甲材料倍率,但也可以使用硬编码的值。 + +对于 Guidite 盔甲,我们使用存储在盔甲材料中的共享盔甲倍率。 + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/armor/ModArmorMaterials.java) + +然后,使用耐久度常数创建盔甲物品。 + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +如果需要让物品能从创造模式物品栏获取的话,还需要**给将物品添加到物品组**。 + +就像所有物品一样,要为这些物品创建翻译键。 + +## 给予纹理和模型{#texturing-and-modelling} + +你会需要创建两套纹理: + +- 用于物品本身的纹理和模型。 +- 盔甲穿在实体身上时可见的真正盔甲模型。 + +### 物品纹理和模型{#item-textures-and-model} + +这些纹理和其他物品没有区别——必须创建纹理、创建一般的 generated 的物品模型,这在[创建你的第一个物品](./first-item#adding-a-texture-and-model)指南中有讲到。 + +例如,你可以使用下面的纹理和模型 JSON 作为参考。 + +物品纹理 + +:::info +你需要所有物品的模型 JSON 文件,不只是头盔,这原则和其他物品模型一样。 +::: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_helmet.json) + +可以看到,游戏内的盔甲物品应该有合适的模型: + +![盔甲物品模型](/assets/develop/items/armor_1.png) + +## 盔甲纹理和模型{#armor-textures-and-model} + +实体穿着你的盔甲时,现在显示的还是缺失纹理: + +![玩家身上的损坏的盔甲模型](/assets/develop/items/armor_2.png) + +盔甲纹理有两层,都要有。 + +因为我们这个例子中,盔甲的材料名称是 `guidite`,所以文本的位置会是: + +- `assets//textures/models/armor/guidite_layer_1.png` +- `assets//textures/models/armor/guidite_layer_2.png` + +盔甲模型纹理 + +第一层包含头盔和胸甲的纹理,第二层包含护腿和靴的纹理。 + +这些纹理存在时,你应该能够看到实体穿着的盔甲了: + +![玩家身上的生效的盔甲模型](/assets/develop/items/armor_3.png) diff --git a/versions/1.21/translated/zh_cn/develop/items/custom-data-components.md b/versions/1.21/translated/zh_cn/develop/items/custom-data-components.md new file mode 100644 index 000000000..04a9d60bc --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/custom-data-components.md @@ -0,0 +1,271 @@ +--- +title: 自定义数据组件 +description: 学习如何使用 1.20.5 新的组件系统为你的物品添加自定义数据 +authors: + - Romejanic +--- + +# 自定义数据组件{#custom-data-components} + +物品越来越复杂,你会发现自己需要存储与每个物品关联的自定义数据。 游戏需要你将持久的数据存储在 `ItemStack`(物品堆)中,在 1.20.5 中,方法就是使用**数据组件**。 + +数据组件替代了之前版本中的 NBT 数据,替换成能应用在 `ItemStack` 的结构化的数据,从而存储物品堆的持久数据。 数据组件是有命名空间的,也就是说,我们可以实现自己的数据组件,存储 `ItemStack` 的自定义数据,并稍后再访问。 所有原版可用的数据组件可以见于此 [Minecraft wiki 页面](https://zh.minecraft.wiki/w/%E7%89%A9%E5%93%81%E5%A0%86%E5%8F%A0%E7%BB%84%E4%BB%B6#%E7%BB%84%E4%BB%B6%E6%A0%BC%E5%BC%8F)。 + +除了注册自定义组件外,本页还介绍了组件 API 的一般用法,这些也可用于原版的组件。 你可以在 `DataComponentTypes` 类中查看并访问所有原版组件的定义。 + +## 注册组件{#registering-a-component} + +就你模组中的其他东西一样,你需要使用 `ComponentType` 注册自定义的组件。 这个组件类型接受一个泛型参数,包含你的组件的值的类型。 之后在讲[基本](#basic-data-components)和[高级](#advanced-data-components)组件时会更深入研究。 + +把这个组件放到一个合理的类中。 对于这个例子,我们创建一个新的包,叫做 `compoennt`,以及一个类,叫做 `ModComponents`,包含我们所有的组件类型。 确保在你的[模组的初始化器](./getting-started/project-structure#entrypoints)中调用 `ModComponents.initialize()`。 + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +这是注册一个组件类型的基本模板: + +```java +public static final ComponentType MY_COMPONENT_TYPE = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of(FabricDocsReference.MOD_ID, "my_component"), + ComponentType.builder().codec(null).build() +); +``` + +有几点需要注意。 在第一行,你看到了一个 `?`, 这将被替换成你的组件的值的类型, 我们稍后完成。 + +其次,你需要提供一个 `Identifier`,包含你的组件的 ID, 其命名空间就是你的模组的 ID。 + +最后,我们有一个 `ComponentType.Builder`,创建一个需要注册的实际`ComponentType` 实例。 这包含我们会需要讨论的另一个重要细节:你的组件的 `Codec`。 现在还是 `null`,但我们也会稍后完成。 + +## 基本数据组件{#basic-data-components} + +基本数据组件(例如 `minecraft:damagae`)包含单个数据值,例如 `int`、`float`、`boolean` 或 `String`。 + +例如,我们创建一个 `Integer` 值,追踪玩家手持我们的物品右键点击了多少次。 参照下面的代码,更新刚刚注册组件的代码。 + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +可以提到,我们这里将 `` 传入作为我们的泛型类型,表示这个组件会存储为单个的 `int` 值。 对于我们的 codec,直接使用提供的 `Codec.INC` codec 就可以了。 对于这样简单的组件,可以使用基本的 codec,但是更加复杂的情形可能需要自定义的 codec(后面就会讲到)。 + +如果开始游戏,就可以输入像这样的命令: + +![/give 命令显示自定义的组件](/assets/develop/items/custom_component_0.png) + +运行命令时,你应该能收到一个包含组件的物品。 但是,现在还没使用这个组件做些有用的事情。 先开始以我们能看到的方式读取组件的值吧。 + +## 读取组件的值{#reading-component-value} + +添加新物品,每次右键点击时都会增加计数器。 可以阅读[自定义物品交互](./custom-item-interactions)页面以了解我们在这个教程中使用的技巧。 + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +记得要和平时一样,在 `ModItems` 类中注册物品。 + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings() +), "counter"); +``` + +我们会添加一些物品提示,在物品栏中鼠标悬浮在物品上时,显示点击次数的当前值。 可以使用 `ItemStack` 的 `get()` 方法获取组件的值: + +```java +int clickCount = stack.get(ModComponents.CLICK_COUNT_COMPONENT); +``` + +这会返回组件的当前值,其类型为我们注册组件时定义的类型。 可以将这个值添加到物品提示中。 在 `CounterItem` 类中,把这一行添加到 `appendTooltip` 方法: + +```java +public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + int count = stack.get(ModComponents.CLICK_COUNT_COMPONENT); + tooltip.add(Text.translatable("item.fabric-docs-reference.counter.info", count).formatted(Formatting.GOLD)); +} +``` + +不要忘记更新你的语言文件(`/assets//lang/en_us.json` 和 `/assets/<0>/lang/zh_cn.json`),并添加这两行: + +```json +{ + "item.fabric-docs-reference.counter": "Counter", + "item.fabric-docs-reference.counter.info": "Used %1$s times" +} +``` + +启动游戏,运行这个命令,给自己一个计数为 5 的新的计数器物品。 + +```mcfunction +/give @p fabric-docs-reference:counter[fabric-docs-reference:click_count=5] +``` + +在物品栏内鼠标悬停在这个物品上时,你可以看到物品提示中显示了计数! + +![显示“使用了 5 次”的物品提示](/assets/develop/items/custom_component_1.png) + +但是,如果给自己一个_没有_自定义组件的新的计数器物品,当你在物品栏内选中物品时游戏会崩溃。 崩溃报告中,会提示这样的信息: + +```log +java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "net.minecraft.item.ItemStack.get(net.minecraft.component.ComponentType)" is null + at com.example.docs.item.custom.CounterItem.appendTooltip(LightningStick.java:45) + at net.minecraft.item.ItemStack.getTooltip(ItemStack.java:767) +``` + +这是因为 `ItemStack` 当前没有包含我们的自定义组件的实例,因此对于我们的组件类型,调用 `stack.get()` 会返回 `null`。 + +解决这个问题有三种方法。 + +### 设置默认组件值{#setting-default-value} + +当你注册你的物品并传递 `Item.Settings` 对象到你的物品构造器中,你还可以提供应用于所有新物品的默认组件的列表。 如果回到我们的 `ModItems` 类,注册 `CounterItem` 的地方,就可以为我们的自定义组件添加默认值。 添加这个,这样新物品会显示计数为 `0`。 + +@[code transcludeWith=::_13](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +创建了新物品后,就会自动为我们的自定义组件应用给定的值。 + +:::warning +使用命令有可能会从 `ItemStack` 中移除默认组件。 当组件不存在于新的物品时,可以参考接下来两个章节,以适当处理这种情况。 +::: + +### 带有默认值读取{#reading-default-value} + +此外,添加组件值时,可以对 `ItemStack` 对象使用 `getOrDefault()` 方法,当组件不存在于物品堆中时,返回指定的默认值。 这可以避免任何由缺失组件导致的错误。 我们可以像这样调整物品提示代码: + +```java +int clickCount = stack.getOrDefault(ModComponents.CLICK_COUNT_COMPONENT, 0); +``` + +正如你所见,方法接受两个参数:和之前一样的组件类型,还有一个默认值,组件不存在时就返回默认值。 + +### 检查组件是否存在{#checking-if-component-exists} + +你也可以使用 `contains()` 方法检查 `ItemStack` 中是否存在特定的组件。 这会接收一个组件类型作为参数,并返回 `true` 或 `false`,取决于物品堆是否包含组件。 + +```java +boolean exists = stack.contains(ModComponents.CLICK_COUNT_COMPONENT); +``` + +### 修复错误{#fixing-the-error} + +我们现在以第三个选项开始。 添加了默认的组件值,还需要检测组件是否存在于物品堆中,只有存在时才显示提示。 + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +再次启动游戏,并将鼠标悬停在没有组件的物品上,你应该看到显示的是“使用了 0 次”并不再崩溃游戏。 + +![显示“使用了 0 次”的物品提示](/assets/develop/items/custom_component_2.png) + +尝试给予自己一个不含自定义组件的计数器。 可以运行如下命令: + +```mcfunction +/give @p fabric-docs-reference:counter[!fabric-docs-reference:click_count] +``` + +鼠标悬浮在物品上,应该不会有提示。 + +![没有提示的计数器物品](/assets/develop/items/custom_component_7.png) + +## 更新组件值{#setting-component-value} + +现在尝试更新我们的组件值。 我们尝试在每次使用我们的计数器物品时增加点击次数。 要改变 `ItemStack` 的组件的值,使用 `set()` 方法,就像这样: + +```java +stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +这会接收我们的组件类型,以及需要设置的值, 在这种情况下为新的点击次数。 这个方法也会返回组件原来的值(如果有的话),有些情况下可能会有用。 例如: + +```java +int oldValue = stack.set(ModComponents.CLICK_COUNT_COMPONENT, newValue); +``` + +我们调用 `use()` 方法,先读旧的点击次数,增加一,然后设置新的点击次数。 + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/CounterItem.java) + +尝试启动游戏并右键点击手中的计数器物品。 如果打开物品栏并再次看看物品,应该就会发现,使用次数随点击的次数增加了。 + +![显示“使用了 8 次”的物品提示](/assets/develop/items/custom_component_3.png) + +## 移除组件值{#removing-component-value} + +如果不再需要组件,可以将其从 `ItemStack` 移除, 方法就是使用 `remove()` 方法,接收你的组件的类型。 + +```java +stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +这个方法也会返回组件移除之前的值,所以可以像这样使用它: + +```java +int oldCount = stack.remove(ModComponents.CLICK_COUNT_COMPONENT); +``` + +## 高级数据组件{#advanced-data-components} + +你可能需要将多个属性存储在单个组件中。 原版有些例子,比如 `minecraft:food` 组件存在几个和食品相关的值,例如 `nutrition`(营养)、`saturation`(饱和度)、`eat_seconds`(食用所需秒数)等。 本教程中我们将其称为“合成”组件。 + +对于合成组件,需要创建一个 `record`(记录)类来存储数据。 这是我们需要给组件类型注册的类型,与这个 `ItemStack` 交互时进行读写。 先在之前创建的 `component` 包中创建新的 record 类。 + +```java +public record MyCustomComponent() { +} +``` + +注意类名后有一组括号。 这里我们定义组件需要有的一系列的属性。 先添加一个浮点数和布尔值,分别叫做 `temperature` 和 `burnt`。 + +@[code transcludeWith=::1](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +因为我们定义自定义的数据结构,所以这种情况下不会像[基本组件](#basic-data-components)那样有预先存在的 `Codec`。 也就是说,需要创建自己的 codec。 我们在 record 类中使用 `RecordCodecBuilder` 定义一个,这样在注册组件时就可以引用。 关于使用 `RecordCodecBuilder` 的更多细节,请参考 [Codec 页面的这个章节](../codecs#merging-codecs-for-record-like-classes)。 + +@[code transcludeWith=::2](@/reference/1.21/src/main/java/com/example/docs/component/MyCustomComponent.java) + +你可以看到我们基于原始的 `Codec` 类型定义了一系列的自定义字段。 我们用 `fieldOf()` 来说明我们的字段叫做什么,然后用 `forGetter()` 告诉游戏怎样从记录中获取该字段。 + +你也可以使用 `optionalFieldOf()` 来定义可选的字段,并在第二个参数传入默认值。 任何没有被标记为可选的字段使用 `/give` 设置组件时都是必需的,所以确保在创建我们的 codec 时,将任何可选的参数都标记为可选。 + +最后,调用 `apply()` 并传递这个 record 的构造方法。 关于构造 codec 的更多细节以及更深入的用法,可阅读 [Codecs](../codecs) 页面。 + +注册“合成”组件和之前类似, 就只需要传入我们的 record 类作为泛型类型,以及给 `codec()` 方法传入自定义的 `Codec`。 + +@[code transcludeWith=::3](@/reference/1.21/src/main/java/com/example/docs/component/ModComponents.java) + +现在启动游戏, 使用 `/give` 命令,尝试应用组件。 合成组件的值传入时是作为对象,用 `{}` 包围起来。 如果用空的花括号,会看到错误,提示你缺少必需的键 `temperature`。 + +![give 命令,显示缺少必需的键“temperature”](/assets/develop/items/custom_component_4.png) + +使用语法 `temperature:8.2`,从而给对象添加 temperature 值。 你还可以为字段 `burnt` 也传入一个值,使用相同语法,不过是 `true` 或 `false`。 现在应该可以看到命令是有效的,会给你包含这个组件的物品。 + +![有效的 give 命令,显示两个属性](/assets/develop/items/custom_component_5.png) + +### 获取、设置和移除高级的组件{#getting-setting-removing-advanced-comps} + +在代码中使用组件和之前都是一样的。 使用 `stack.get()` 会返回你的 `record` 类的实例,可以用于读取值。 不过由于 `record` 都是只读的,所以要更新值时,需要创建你的 record 的新的实例。 + +```java +// read values of component +MyCustomComponent comp = stack.get(ModComponents.MY_CUSTOM_COMPONENT); +float temp = comp.temperature(); +boolean burnt = comp.burnt(); + +// set new component values +stack.set(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(8.4f, true)); + +// check for component +if (stack.contains(ModComponents.MY_CUSTOM_COMPONENT)) { + // do something +} + +// remove component +stack.remove(ModComponents.MY_CUSTOM_COMPONENT); +``` + +你也可以在你的 `Item.Settings` 中传入组件对象来为合成组件设置默认的值。 例如: + +```java +public static final Item COUNTER = register(new CounterItem( + new Item.Settings().component(ModComponents.MY_CUSTOM_COMPONENT, new MyCustomComponent(0.0f, false)) +), "counter"); +``` + +现在你就能够在 `ItemStack` 中存储自定义的数据。 好好使用吧! + +![显示计数数量、温度和燃烧的物品提示的物品](/assets/develop/items/custom_component_6.png) diff --git a/versions/1.21/translated/zh_cn/develop/items/custom-item-groups.md b/versions/1.21/translated/zh_cn/develop/items/custom-item-groups.md new file mode 100644 index 000000000..db0160056 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/custom-item-groups.md @@ -0,0 +1,38 @@ +--- +title: 自定义物品组 +description: 学习如何创建自己的物品组,并往里面添加物品。 +authors: + - IMB11 +--- + +# 自定义物品组{#custom-item-groups} + +物品组是创造模式物品栏内存储物品的标签页。 你可以创建自己的物品组,从而在单独的标签页内存储物品。 如果你的模组添加许多物品,需要保持组织在你的玩家容易访问的一个位置中,这就非常有用。 + +## 创建物品组{#creating-the-item-group} + +创建物品组极其容易。 只要在你的物品类中简单创建一个新的 static final 字段,存储物品组以及注册表键,就可以使用物品组事件,类型于给原版物品组添加物品的方式: + +@[code transcludeWith=:::9](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::_12](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +
+ +你现在应该可以在物品栏菜单内看到物品组了。 然而还没有翻译——必须给你的翻译文件添加翻译键——类似于翻译你的第一个物品的方式。 + +![创建模式菜单内没有翻译的物品组](/assets/develop/items/itemgroups_0.png) + +## 添加翻译键{#adding-a-translation-key} + +如果在物品组的 builder 内,为 `displayName` 方法使用了 `Text.translatable`,就需要往语言文件添加翻译。 + +```json +{ + "itemGroup.fabric_docs_reference": "Fabric Docs Reference" +} +``` + +现在可以看到,物品组应该被正确命名了。 + +![完全完成的物品组,有翻译和物品](/assets/develop/items/itemgroups_1.png) diff --git a/versions/1.21/translated/zh_cn/develop/items/custom-item-interactions.md b/versions/1.21/translated/zh_cn/develop/items/custom-item-interactions.md new file mode 100644 index 000000000..86c98b179 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/custom-item-interactions.md @@ -0,0 +1,71 @@ +--- +title: 自定义物品交互 +description: 学习如何创建使用内置原版事件的物品 +authors: + - IMB11 +--- + +# 自定义物品交互{#custom-item-interactions} + +基础物品的功能是有限的——你还是需要个能在使用时与世界交互的物品。 + +有些关键的类你必须理解,然后才能看看原版的物品事件。 + +## 带类型的操作结果(TypedActionResult) {#typedactionresult} + +对于物品来说,最常见的 `TypedActionResult` 是用于 `ItemStacks` 的——他负责告诉游戏在事件发生后是否需要替换物品堆叠(item stack)。 + +如果事件中没有发生任何变化,你应该使用 `TypedActionResult#pass(stack)` 方法,其中 `stack` 是当前的物品堆。 + +获取物品堆叠的一种方式是通过玩家的手。 需要返回 `TypedActionResult` 的事件往往会将手作为参数传递给事件方法。 + +```java +TypedActionResult.pass(user.getStackInHand(hand)) +``` + +如果传递返回当前的物品堆叠, 那么无论将事件声明为什么——失败(failed)、通过(passed) 或忽略(ignored)、 成功(successful),物品堆叠都不会发生变化。 _译者注:在源代码中并没有ignored的枚举值, 可能的情况是`PASS`被用来表示事件未处理,游戏将继续执行默认行为。此处注解可能不准确, 希望后来者指正_ + +当想要清空物品堆叠时,你应当传递一个空的。 同样的,当想要减少物品堆叠的数量时,你应当先获取当该品堆,并按数量减少他,就像下面那样: + +```java +ItemStack heldStack = user.getStackInHand(hand); +heldStack.decrement(1); +TypedActionResult.success(heldStack); +``` + +## 操作结果(ActionResult) {#actionresult} + +同样,`ActionResult` 告诉游戏事件的状态,无论是被忽略(PASS)、失败(FAIL) 还是成功(Success)。_译者注:`ActionResult`实际上是一个枚举类,而`TypedActionResult`包装了 这个类,不仅可以表示结果的状态,还可以携带附加的数据,比如 item stack_ + +## 可以被重写的事件(Overridable Events) {#overridable-events} + +`Item` 类有许多方法可以被重写,从而为物品添加额外的功能。 + +:::info +[Playing SoundEvents](../sounds/using-sounds) 这里有一个比较好的例子, 他通过重写`useOnBlock` 实现了在玩家右击方块时播放声音的功能。 +::: + +| 方法 | 信息 | +| --------------- | -------------------------------------------------- | +| `postHit` | 当玩家攻击实体时被调用 | +| `postMine` | 当玩家挖掘方块时被调用 | +| `inventoryTick` | 当物品在物品栏(inventory)中时,每一tick调用一次 | +| `onCraft` | 当物品被合成时调用 | +| `useOnBlock` | 当玩家手持物品右键方块时调用(确切的说是对着方块按下使用按键) | +| `use` | 当玩家手持物品按下右键时调用(确切的说是按下使用按键) | + +## 以使用(use) 事件为例 {#use-event} + +假设你想制作一个在玩家面前召唤闪电的物品,这显然需要创建一个自定义的物品类。 + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +`use` 事件可能是最有用的事件之一:你可以利用这个事件来召唤闪电。下面的代码实现了在玩家面向的方向前10个方块的位置生成闪电。 + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +同样的,你需要注册物品,并添加模型和纹理。 + +然后,效果就是这样 + + diff --git a/versions/1.21/translated/zh_cn/develop/items/custom-tools.md b/versions/1.21/translated/zh_cn/develop/items/custom-tools.md new file mode 100644 index 000000000..982d12923 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/custom-tools.md @@ -0,0 +1,104 @@ +--- +title: 工具和武器 +description: 学习如何创建自己的工具并配置其属性。 +authors: + - IMB11 +--- + +# 工具{#tools} + +工具对于生存和游戏进程至关重要,可让玩家收集资源、建造建筑物和保护自己。 + +## 创建工具材料{#creating-a-tool-material} + +::: info +If you're creating multiple tool materials, consider using an `Enum` to store them. Vanilla does this in the `ToolMaterials` class, which stores all the tool materials that are used in the game. + +此类还可用于确定你的工具原型相较于原版工具原型不同的的属性。 +::: + +为了创建一个工具材料,你可以创建一个继承它的、新的类——在此示例中,将创建 Guidite 质的工具: + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +创建了工具原型并根据自己的喜好对其进行了调整后,你就可以创建它的一个实例以用于工具物品构造函数。 + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +工具原型向游戏告知以下信息: + +### 耐久 - `getDurability()` {#durability} + +该工具在损坏前可被使用多少次: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### 挖掘速度 - `getMiningSpeedMultiplier()` {#mining-speed} + +如果该工具用来破坏方块,那么它破坏方块的速度应该多快? + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +作为参考,钻石工具材料的挖掘速度为 `8.0F`,而石质工具材料的挖掘速度为 `4.0F`。 + +### 攻击伤害 - `getAttackDamage()` {#attack-damage} + +将工具作为武器攻击别的实体时,应该造成多少点伤害? + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### 反向标签 - `getMiningLevel()` {#inverse-tag} + +反向标签显示工具 _**无法**_ 挖掘的内容。 例如,使用 `BlockTags.INCORRECT_FOR_WOODEN_TOOL` 标签可阻止工具挖掘某些方块: + +```json +{ + "values": [ + "#minecraft:needs_diamond_tool", + "#minecraft:needs_iron_tool", + "#minecraft:needs_stone_tool" + ] +} +``` + +这意味着该工具无法开采需要钻石、铁或石质工具才能开采的方块。 + +我们使用铁制工具标签。 铁制工具标签会阻止 Guidite 工具开采需要用比铁制工具更强的的工具来开采的方块。 + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +如果你想自定义标签,可以使用 `TagKey.of(...)` 来创建自定义标签键。 + +### 附魔能力 - `getEnchantability()` {#enchantability} + +这个物品在附魔台中附上更好、更高级的附魔有多轻松? 作为参考和比较,金质的附魔等级为 22,而下界合金的附魔等级为 15。 + +@[code transcludeWith=:::6](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +### 修复原料 - `getRepairIngredient()` {#repair-ingredient} + +使用什么物品来修理该工具? + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/tool/GuiditeMaterial.java) + +## 创建工具物品{#creating-tool-items} + +使用与 [创建你的第一个物品](./first-item) 指南中相同的实用功能,你可以创建工具物品: + +@[code transcludeWith=:::7](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +如果你想从创造物品栏中访问它们,请记得将它们添加到物品组中! + +@[code transcludeWith=:::8](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +你还得添加纹理、物品翻译和物品模型。 然而,对于物品模型,你需要使用 `item/handheld` 模型作为你的父级。 + +在此示例中,我将对“Guidite Sword”物品使用以下模型和纹理: + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/guidite_sword.json) + +纹理 + +这样就差不多了! 如果你进入游戏,你应该会在创造物品栏菜单的工具选项栏中看到你的工具物品。 + +![物品栏中的成品工具](/assets/develop/items/tools_1.png) diff --git a/versions/1.21/translated/zh_cn/develop/items/first-item.md b/versions/1.21/translated/zh_cn/develop/items/first-item.md new file mode 100644 index 000000000..2191d37f7 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/first-item.md @@ -0,0 +1,151 @@ +--- +title: 创建你的第一个物品 +description: 学习如何注册简单的物品,以及如何给物品添加纹理、模型和名称。 +authors: + - IMB11 + - dicedpixels +--- + +# 创建你的第一个物品{#creating-your-first-item} + +本页会带你介绍物品的一些关键概念,以及如果注册物品、添加纹理、添加模型、命名。 + +如果你还不知道的话,Minecraft 中的一切都存储在注册表中,物品也不例外。 + +## 准备你的物品类 {#preparing-your-items-class} + +要简化物品注册,可以创建一个方法,接收一个物品实例和字符串 id。 + +这个方法会用提供的 id 创建物品并在游戏的物品注册表中注册。 + +你可以将这个方法放在叫做 `ModItems` 的类中(也可以是其他你想要的名称)。 + +Mojang 也是对物品这么做的! 看看 `Items` 类以了解。 + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## 注册物品{#registering-an-item} + +你现在可以用这个方法注册物品 + +物品的构造方法会接收一个 `Items.Settings` 类的实例作为参数。 这个类允许你通过一系列构造器方法配置物品的属性。 + +::: tip +If you want to change your item's stack size, you can use the `maxCount` method in the `Items.Settings`/`FabricItemSettings` class. + +如果将物品标记为可被破坏,那么这就不会生效,因为可被破坏的物品的堆叠大小永远是 1 以避免重复损坏。 +::: + +@[code transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +然而,如果现在尝试运行修改的客户端,会发现我们的物品在游戏中还不存在! 这是因为你还没有静态初始化类。 + +要这样做,你需要在你的类中添加静态的 initialize 方法,然后在你的[模组的初始化类](./getting-started/project-structure#entrypoints)中调用。 当前,方法不需要里面有任何东西。 + +@[code transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +@[code transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/FabricDocsReferenceItems.java) + +对类调用一个方法会静态初始化,如果还没有加载的话——这意味着所有的 `static` 字段都会计算。 这就是这个占位的 `initialize` 的方法的目的。 + +## 将物品添加到物品组{#adding-the-item-to-an-item-group} + +:::info +如果想要将物品添加到自定义的 `ItemGroup`,请参阅[自定义物品组](./custom-item-groups)页面以了解更多。 +::: + +这里为举例,我们将这个物品添加到原材料物品组中,你需要使用 Fabric API 的 item group event——也就是 `ItemGroupEvents.modifyEntriesEvent`。 + +你可以在你的物品类的 `initialize` 方法中完成。 + +@[code transcludeWith=:::4](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +载入游戏,你会看到我们的物品已经注册好了,并且在原材料物品组中。 + +![原材料组中的物品](/assets/develop/items/first_item_0.png) + +然而,还缺这些: + +- 物品模型 +- 纹理 +- 翻译(名称) + +## 给物品命名{#naming-the-item} + +物品当前还没有翻译,所以需要添加。 Minecraft 已经提供好了翻译键:`item.mod_id.suspicious_substance`。 + +创建新的 JSON 文件:`src/main/resources/assets//lang/en_us.json`,并将翻译键和名称放在里面: + +```json +{ + "item.mod_id.suspicious_substance": "Suspicious Substance" +} +``` + +要应用更改,可以重启游戏,或者构建模组并按下F3 + T。 + +## 添加纹理和模型{#adding-a-texture-and-model} + +要给你的物品纹理和模型,先简单地为物品创建一个16x16的纹理图像,并存储在 `assets//textures/item` 文件夹中。 根据物品的 id 命名纹理文件的名字,但要有 `.png` 扩展名。 + +例如,将示例纹理用于 `suspicious_substance.png`。 + +纹理 + +重启或重新加载游戏时,你会发现物品还没有纹理,这是因为需要添加一个使用了此纹理的模型。 + +简单创建一个 `item/generated` 模型,接收一个输入纹理,没有其他的。 + +在 `assets//models/item` 文件夹内创建模型 JSON,名称与物品相同, `suspicious_substance.json` + +@[code](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/models/item/suspicious_substance.json) + +### 逐个分析模型 JSON{#breaking-down-the-model-json} + +- `parent`:模型要继承的模型。 在这个例子中,是 `item/generated` 模型。 +- `textures`:为模型定义纹理的地方。 `layer0` 键是模型使用的纹理。 + +大多物品继承的模型是 `item/generate`,因为这是显示纹理的简单模型。 + +也有其他的,比如 `item/handheld`,用于拿在玩家手中的物品,例如工具。 + +你的物品在游戏内看上去应该是这样: + +![模型正确的物品](/assets/develop/items/first_item_2.png) + +## 让物品可堆肥或作燃料 {#making-the-item-compostable-or-a-fuel} + +Fabric API 添加了各种注册表,可用于为物品添加额外属性。 + +例如,要让物品可堆肥,可以使用 `CompostableItemRegistry`: + +@[code transcludeWith=:::_10](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +又如,如果要让物品可作燃料,可以使用 `FuelRegistry` 类。 + +@[code transcludeWith=:::_11](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +## 添加基本的合成配方 {#adding-a-basic-crafting-recipe} + + + +如果要为你的物品添加合成配方,需要将配方 JSON 文件放在 `data//recipe` 文件夹中。 + +更多关于配方格式的信息,可参考以下资源: + +- [配方 JSON 生成器](https://crafting.thedestruc7i0n.ca/) +- [中文 Minecraft Wiki - 配方 JSON](https://zh.minecraft.wiki/w/配方#JSON格式) + +## 自定义物品提示 {#custom-tooltips} + +如果要让你的物品有自定义的物品提示,需要创建继承了 `Item` 的类,并覆盖 `appendTooltip` 方法。 + +:::info +这个例子使用 `LightningStick` 类,这是在[自定义物品交互](./custom-item-interactions)页面创建的。 +::: + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/main/java/com/example/docs/item/custom/LightningStick.java) + +每次调用 `add()` 都会添加一行提示。 + +![物品提示演示](/assets/develop/items/first_item_3.png) diff --git a/versions/1.21/translated/zh_cn/develop/items/food.md b/versions/1.21/translated/zh_cn/develop/items/food.md new file mode 100644 index 000000000..f7a86ae4d --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/food.md @@ -0,0 +1,52 @@ +--- +title: 食物物品 +description: 学会如何给物品添加 FoodComponent 以让它可食用,并配置。 +authors: + - IMB11 +--- + +# 食物物品{#food-items} + +食物是生存 Minecraft 的核心方面,所以创建可食用的物品时,需要考虑食物的用途以及其他可食用物品。 + +除非是在制作有过于强的物品的模型,否则应该考虑: + +- 你的可食用物品会添加或减少多少饥饿值。 +- 会给予什么药水效果? +- 是在游戏早期还是末期可用的? + +## 添加食物组件{#adding-the-food-component} + +要为物品添加食物组件,可以先传递到 `Item.Settings` 实例: + +```java +new Item.Settings().food(new FoodComponent.Builder().build()) +``` + +现在,只要让物品可食用,没有别的。 + +`FoodComponent` 类有很多方法,允许你修改玩家吃你的物品时发生的事情: + +| 方法 | 描述 | +| -------------------- | -------------------------------------------------------- | +| `nutrition` | 设置你的物品会补充的饥饿值的数量。 | +| `saturationModifier` | 设置你的物品会增加的饱和度的数量。 | +| `alwaysEdible` | 允许无论饥饿值均能吃你的物品。 | +| `snack` | 将你的物品描述为零食。 | +| `statusEffect` | 吃你的物品时添加状态效果。 通常传递到此方法的是一个状态效果实例和概率,其中概率是小数(`1f = 100%`) | + +按照你的喜好修改了 builder 后,可以调用 `build()` 方法以获取 `FoodComponent`。 + +@[code transcludeWith=:::5](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +与 [创建你的第一个物品](./first-item) 类似,该示例将使用上述的组件: + +@[code transcludeWith=:::poisonous_apple](@/reference/1.21/src/main/java/com/example/docs/item/ModItems.java) + +这会让物品: + +- 总是可食用,无论饥饿值均可以吃。 +- 是“零食”。 +- 吃完会总会给予 6 秒中毒 II。 + + diff --git a/versions/1.21/translated/zh_cn/develop/items/potions.md b/versions/1.21/translated/zh_cn/develop/items/potions.md new file mode 100644 index 000000000..751ce15d5 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/items/potions.md @@ -0,0 +1,49 @@ +--- +title: 药水 +description: 学习如何加入多种状态效果的自定义药水。 +authors: + - dicedpixels + - PandoricaVi + - Drakonkinst + - JaaiDead +--- + +# 药水{#potions} + +药水是能为实体提供效果的消耗品。 玩家可以使用酿造台酿造药水,或者从其他游戏机制中以物品形式获取。 + +## 自定义药水{#custom-potions} + +和物品和方块一样,药水需要注册。 + +### 创建物品{#creating-the-potion} + +让我们从声明一个用于储存你的 `Potion` 实例的字段开始。 我们将直接使用 `ModInitializer`——实现这个类来持有这个字段。 + +@[code lang=java transclude={18-27}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +我们传入一个 `StatusEffectInstance` 实例,它的构造方法接收以下 3 个参数: + +- `RegistryEntry 类型` - 效果。 我们在这里使用我们的自定义效果。 你也可以通过原版的 `StatusEffects` 类访问原版效果。 +- `int duration` - 状态效果的持续时间(以刻计算)。 +- `int amplifier` - 状态效果的增幅。 比如 急迫 II 的增幅是 1。 + +:::info +要创建自己的药水效果,请使用[效果](../entities/effects)指南。 +::: + +### 注册药水{#registering-the-potion} + +在我们的初始化器中,我们将使用 `FabricBrewingRecipeRegistryBuilder.BUILD` 事件,使用 `BrewingRecipeRegistry.registerPotionRecipe` 方法注册我们的药水。 + +@[code lang=java transclude={29-42}](@/reference/1.21/src/main/java/com/example/docs/potion/FabricDocsReferencePotions.java) + +`registerPotionRecipe` 接收以下 3 个参数: + +- `RegistryEntry 输入` - 初始药水的注册表项。 通常可以是水瓶或粗制的药水。 +- `Item item` - 作为药水主要原料的物品。 +- `RegistryEntry 输出` - 结果药水的注册表项。 + +注册完成后,你就可以用马铃薯酿造土豆药水。 + +![玩家物品栏内的效果](/assets/develop/tater-potion.png) diff --git a/versions/1.21/translated/zh_cn/develop/rendering/basic-concepts.md b/versions/1.21/translated/zh_cn/develop/rendering/basic-concepts.md new file mode 100644 index 000000000..13903c067 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/rendering/basic-concepts.md @@ -0,0 +1,162 @@ +--- +title: 基本渲染概念 +description: 学习 Minecraft 渲染引擎的基本概念。 +authors: + - IMB11 + - "0x3C50" +--- + +# 基本渲染概念{#basic-rendering-concepts} + +::: warning +Although Minecraft is built using OpenGL, as of version 1.17+ you cannot use legacy OpenGL methods to render your own things. Instead, you must use the new `BufferBuilder` system, which formats rendering data and uploads it to OpenGL to draw. + +总的来说,您应该使用 Minecraft 的渲染系统,否则就得利用 `GL.glDrawElements()` 来构建自己的。 +::: + +本文会介绍使用新系统渲染的一些基础,并解释一些关键术语和概念。 + +尽管 Minecraft 的许多渲染都通过 `DrawContext` 中的各种方法抽象出来,且您很可能并不需要接触这里提到的任何内容,但是了解渲染的基础实现依然很重要。 + +## 镶嵌器 `Tessellator`{#the-tessellator} + +镶嵌器 `Tessellator` 是 Minecraft 中用于渲染东西的主类。 它是一个单例,这意味着游戏中只有它的一个实例。 您可以通过 `Tessellator.getInstance()` 获取这个实例。 + +## 缓冲构建器 `BufferBuilder`{#the-bufferbuilder} + +缓冲构建器 `BufferBuilder` 是用来将渲染数据格式化并上传到 OpenGL 的类。 用于创建缓冲,随后也会将这个缓冲上传到 OpenGL 用于绘制。 + +镶嵌器 `Tessellator` 负责创建一个缓冲构建器 `BufferBuilder`,用于将渲染数据格式化并上传到 OpenGL。 + +### 初始化 `BufferBuilder`{#initializing-the-bufferbuilder} + +必须先初始化 `BufferBuilder`,才能往里面写入任何东西。 方法就是使用 `Tessellator#begin(...)` 方法,接收一个 `VertexFormat` 和绘制模式,并返回 `BufferBuilder`。 + +#### 顶点格式{#vertex-formats} + +顶点格式 `VertexFormat` 定义了我们在我们的数据缓冲中包含的元素,并规定了这些元素将如何被转发到 OpenGL。 + +可用的 `VertexFormat` 元素如下: + +| 元素 | 格式 | +| --------------------------------------------- | --------------------------------------------------------------------------------------- | +| `BLIT_SCREEN` | `{ position (3 floats: x, y and z), uv (2 floats), color (4 ubytes) }` | +| `POSITION_COLOR_TEXTURE_LIGHT_NORMAL` | `{ position, color, texture uv, texture light (2 shorts), texture normal (3 sbytes) }` | +| `POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL` | `{ position, color, texture uv, overlay (2 shorts), texture light, normal (3 sbytes) }` | +| `POSITION_TEXTURE_COLOR_LIGHT` | `{ position, texture uv, color, texture light }` | +| `POSITION` | `{ position }` | +| `POSITION_COLOR` | `{ position, color }` | +| `LINES` | `{ position, color, normal }` | +| `POSITION_COLOR_LIGHT` | `{ position, color, light }` | +| `POSITION_TEXTURE` | `{ position, uv }` | +| `POSITION_COLOR_TEXTURE` | `{ position, color, uv }` | +| `POSITION_TEXTURE_COLOR` | `{ position, uv, color }` | +| `POSITION_COLOR_TEXTURE_LIGHT` | `{ position, color, uv, light }` | +| `POSITION_TEXTURE_LIGHT_COLOR` | `{ position, uv, light, color }` | +| `POSITION_TEXTURE_COLOR_NORMAL` | `{ position, uv, color, normal }` | + +#### 绘制模式{#draw-modes} + +绘制模式定义了如何绘制数据。 可用的绘制模式如下: + +| 绘制模式 | 描述 | +| --------------------------- | ------------------------------------------------ | +| `DrawMode.LINES` | 每个元素由 2 个顶点构成,代表一条直线。 | +| `DrawMode.LINE_STRIP` | 第一个元素需要 2 个顶点。 附加的元素只需要 1 个新的顶点就能绘制,创建出一条连续的线。 | +| `DrawMode.DEBUG_LINES` | 与 `DrawMode.LINES` 类似,但线在屏幕上总是保持 1 像素宽。 | +| `DrawMode.DEBUG_LINE_STRIP` | 与 `DrawMode.LINE_STRIP` 相同,但线总是保持 1 像素宽。 | +| `DrawMode.TRIANGLES` | 每个元素都由 3 个顶点组成,形成一个三角形。 | +| `DrawMode.TRIANGLE_STRIP` | 前 3 个顶点形成第一个三角形。 每个新增的顶点与前两个顶点形成一个新的三角形。 | +| `DrawMode.TRIANGLE_FAN` | 前 3 个顶点形成第一个三角形。 每个新增的顶点与第一个顶点和最后的一个顶点形成一个新的三角形。 | +| `DrawMode.QUADS` | 每个元素由 4 个顶点构成,形成一个四边形。 | + +### 向 `BufferBuilder` 写入{#writing-to-the-bufferbuilder} + +`BufferBuilder` 初始化完成后,您就可以向它写入数据。 + +`BufferBuilder` 允许我们一个顶点一个顶点地构造我们的缓冲。 我们调用 `buffer.vertex(matrix, float, float, float)` 方法来添加一个顶点。 参数 `matrix` 是变换矩阵,具体细节我们将在后文中讨论。 3 个 `float` 参数代表顶点坐标的 (x, y, z)。 + +这个方法返回一个顶点构建器(vertex builder),可以用来为这个顶点指定附加信息。 附加这些信息时,按照我们先前定义的顶点格式 `VertexFormat` 是至关重要的。 如果不这么做,OpenGL 可能无法正确解释我们的数据。 完成构建顶点后,只需要给缓冲继续添加更多顶点和数据,直到完成。 + +“剔除”的概念也值得我们理解。 剔除是从 3D 形状中移除那些在观察者视角不可见的面的过程。 如果一个面的顶点指定顺序错误,这个面可能会因为剔除而无法正确渲染。 + +#### 什么是变换矩阵? {#what-is-a-transformation-matrix} + +一个变换矩阵是一个 4×4 的矩阵,用于变换一个向量。 在 Minecraft 中,变换矩阵只是变换我们传入顶点调用的坐标。 这些变换可以放缩、平移和旋转我们的模型。 + +有时称为位置矩阵,或模型矩阵。 + +通常是通过 `MatrixStack` 类获取的, `MatrixStack` 实例可以从 `DrawContext` 对象获取: + +```java +drawContext.getMatrices().peek().getPositionMatrix(); +``` + +#### 渲染三角条纹{#rendering-a-triangle-strip} + +用实际案例来解释如何向 `BufferBuilder` 写入会更轻松一些。 不妨让我们尝试用绘制模式 `DrawMode.TRIANGLE_STRIP` 和顶点格式 `POSITION_COLOR` 来渲染一些东西。 + +我们将在平视显示器(HUD)上的以下几个点按顺序绘制顶点: + +```txt +(20, 20) +(5, 40) +(35, 40) +(20, 60) +``` + +这应当给出一个漂亮的菱形——因为我们在使用绘制模式 `TRIANGLE_STRIP`,渲染器将执行以下几步: + +![四个步骤展示顶点在屏幕上的放置是如何形成两个三角形的](/assets/develop/rendering/concepts-practical-example-draw-process.png) + +因为在这个例子中我们在平视显示器(HUD)上绘制,我们将使用 `HudRenderCallback` 事件: + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +在平视显示器(HUD)上绘制的结果如下: + +![最终结果](/assets/develop/rendering/concepts-practical-example-final-result.png) + +:::tip +尝试给顶点随机的颜色和位置,看看会发生什么! 您也可以尝试使用不同的绘制模式和顶点格式。 +::: + +## 矩阵栈 `MatrixStack`{#the-matrixstack} + +在学习完如何向 `BufferBuilder` 写入后,您可能会好奇如何变换你的模型——或者甚至让它动起来。 这时就需要引入 `MatrixStack` 类。 + +`MatrixStack` 类有以下方法: + +- `push()` - 向栈压入一个新的矩阵。 +- `pop()` - 从栈中弹出一个矩阵。 +- `peek()` - 返回栈顶的矩阵。 +- `translate(x, y, z)` - 平移栈顶的矩阵。 +- `scale(x, y, z)` - 放缩栈顶的矩阵。 + +您也可以使用四元数对栈顶的矩阵做叉乘,这些内容会在下一节讲到。 + +从我们上面的案例出发,我们可以用 `MatrixStack` 和 `tickDelta`(从上一帧到现在经过的时间)让我们的菱形放大和缩小。 + +::: warning +You must first push the matrix stack and then pop it after you're done with it. If you don't, you'll end up with a broken matrix stack, which will cause rendering issues. + +在获取变换矩阵前,请确保向矩阵栈压入一个新的矩阵! +::: + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +![一段展示菱形放大和缩小的视频](/assets/develop/rendering/concepts-matrix-stack.webp) + +## 四元数 `Quaternion`(旋转物体){#quaternions-rotating-things} + +四元数是三维空间中的旋转的一种表示方法, 用于通过 `multiply(Quaternion, x, y, z)` 方法旋转 `MatrixStack` 栈顶的矩阵。 + +您几乎不太可能需要直接使用 `Quaternion` 类,因为 Minecraft 在工具类 `RotationAxis` 中提供了许多预先定义的 `Quaternion` 实例。 + +不妨让我们尝试绕 z 轴旋转我们的菱形。 我们可以通过 `MatrixStack` 和 `multiply(Quaternion, x, y, z)` 方法来实现。 + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/RenderingConceptsEntrypoint.java) + +这会产生如下结果: + +![一段展示菱形绕 z 轴旋转的视频](/assets/develop/rendering/concepts-quaternions.webp) diff --git a/versions/1.21/translated/zh_cn/develop/rendering/draw-context.md b/versions/1.21/translated/zh_cn/develop/rendering/draw-context.md new file mode 100644 index 000000000..daee697a1 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/rendering/draw-context.md @@ -0,0 +1,94 @@ +--- +title: 使用绘制上下文 +description: 学习如何使用 DrawContext 类来渲染各种图形、文字、纹理。 +authors: + - IMB11 +--- + +# 使用绘制上下文{#using-the-drawing-context} + +本文假设您已经看过[基本渲染概念](./basic-concepts)。 + +`DrawContext` 类是用于在游戏内渲染的主类。 用于渲染图形、文字、纹理,而且之前也见过,用于操纵 `MatrixStack` 和使用 `BufferBuilder`。 + +## 绘制图形{#drawing-shapes} + +使用 `DrawContext` 绘制**矩形**十分容易。 如果想绘制三角形或其他非矩形的图形,需要使用 `BufferBuilder`。 + +### 绘制矩形{#drawing-rectangles} + +可以使用 `DrawContext.fill(...)` 方法绘制一个实心矩形。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![矩形](/assets/develop/rendering/draw-context-rectangle.png) + +### 绘制轮廓和边框{#drawing-outlines-borders} + +假设我们想勾勒出刚刚绘制的矩形的轮廓。 我们可以使用 `DrawContext.drawBorder(...)` 方法来绘制轮廓。 + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![带边框的矩形](/assets/develop/rendering/draw-context-rectangle-border.png) + +### 绘制独立线条{#drawing-individual-lines} + +我们可以使用 `DrawContext.drawHorizontalLine(...)` 和 `DrawContext drawVerticalLine(...)` 来绘制线条。 + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![线条](/assets/develop/rendering/draw-context-lines.png) + +## 裁剪管理器{#the-scissor-manager} + +`DrawContext` 有一套内建的裁剪功能。 可以用来把渲染裁剪为特定区域。 这个功能在绘制某些元素时十分有用,比如悬浮提示,或者其他不应该超出指定渲染区域的界面元素。 + +### 使用裁剪管理器{#using-the-scissor-manager} + +:::tip +裁剪区域可以嵌套! 但是请一定配对 `enableScissor` 和 `disableScissor`,否则错误的裁剪区域将影响到其他界面元素。 +::: + +要启用裁剪管理器,只需使用 `DrawContext.enableScissor(...)` 方法。 同样地,要禁用裁剪管理器,使用 `DrawContext.disableScissor()` 方法。 + +@[code lang=java transcludeWith=:::4](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![裁剪区域](/assets/develop/rendering/draw-context-scissor.png) + +如您所见,即使我们告诉游戏用渐变色铺满整个屏幕,也只在裁剪区域内渲染。 + +## 绘制纹理{#drawing-textures} + +在屏幕上绘制纹理没有唯一“正确”的方法,因为 `drawTexture(...)` 方法有很多不同的重载。 本节内容只会涵盖最常用的方法。 + +### 绘制整个纹理{#drawing-an-entire-texture} + +一般来说,我们推荐您使用需要指定 `textureWidth` 和 `textureHeight` 参数的 `drawTexture` 方法重载。 因为如果使用不指定的重载, `DrawContext` 会假设您的纹理文件尺寸是 256x256,而您的纹理文件不一定是这个尺寸,于是渲染结果就不一定正确。 + +@[code lang=java transcludeWith=:::5](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![绘制整个纹理](/assets/develop/rendering/draw-context-whole-texture.png) + +### 绘制纹理的一部分{#drawing-a-portion-of-a-texture} + +在这个情形中,我们需要指定纹理区域的 `u` 和 `v`。 这俩参数用于指定纹理区域左上角的坐标。另外,`regionWidth` 和 `regionHeight` 参数用于指定纹理区域的尺寸。 + +我们以此纹理为例。 + +![配方书纹理](/assets/develop/rendering/draw-context-recipe-book-background.png) + +如果我们只希望绘制包含放大镜的区域,我们可以使用如下 `u`、`v`、`regionWidth`、`regionHeight` 值: + +@[code lang=java transcludeWith=:::6](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![区域纹理](/assets/develop/rendering/draw-context-region-texture.png) + +## 绘制文字{#drawing-text} + +`DrawContext` 提供了许多渲染文字的方法,都解释得很清楚,您可以自行尝试,此处不再赘述。 + +假设我们想在屏幕中绘制“Hello World”。 我们可以使用 `DrawContext.drawText(...)` 方法来完成。 + +@[code lang=java transcludeWith=:::7](@/reference/1.21/src/client/java/com/example/docs/rendering/DrawContextExampleScreen.java) + +![绘制文字](/assets/develop/rendering/draw-context-text.png) diff --git a/versions/1.21/translated/zh_cn/develop/rendering/gui/custom-screens.md b/versions/1.21/translated/zh_cn/develop/rendering/gui/custom-screens.md new file mode 100644 index 000000000..debfbc4d9 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/rendering/gui/custom-screens.md @@ -0,0 +1,64 @@ +--- +title: 自定义界面 +description: 学习如何给你的模组创建自定义界面。 +authors: + - IMB11 +--- + +# 自定义界面{#custom-screens} + +:::info +本文所述均指一般的、未涉及同步的界面,这类界面是由玩家独自在客户端打开的,不需要服务端的参与。 +::: + +界面是指玩家可以交互的 GUI,比如标题界面、暂停界面等。 + +您可以创建自己的界面来展示自定义内容、自定义配置目录等。 + +## 创建界面{#creating-a-screen} + +要创建界面,您需要继承 `Screen` 类并覆写 `init` 方法。您可能还需要覆写 `render` 方法,但是请保证调用 `super.render`, 否则背景和组件都不会渲染。 + +您需要注意: + +- 组件不应该在 `Screen` 的构造方法里创建,因为此时界面还没有初始化,并且某些变量(比如界面的宽 `width` 和高 `height`)也还没有正确地初始化。 +- 当界面正在初始化时,`init` 方法将被调用,这是创建组件对象的最佳时机。 + - 您可以通过 `addDrawableChild` 方法来添加组件,这个方法接收任何实现了 `Drawable` 和 `Element` 接口的组件对象。 +- `render` 方法将在每一帧被调用,您可以在这个方法里获取诸多上下文,比如鼠标的位置。 + +举个例子,我们可以创建一个简单的界面,这个界面有一个按钮和一个按钮的标签。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![自定义界面 1](/assets/develop/rendering/gui/custom-1-example.png) + +## 打开界面{#opening-the-screen} + +您可以使用 `MinecraftClient` 类的 `setScreen` 方法来打开您的界面。您可以在许多地方做这件事,比如当一个按键触发时,当一条命令执行时,或者当客户端收到一个网络包时。 + +```java +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty()) +); +``` + +## 关闭界面{#closing-the-screen} + +当您想要关闭界面时,只需将界面设为 `null` 即可: + +```java +MinecraftClient.getInstance().setScreen(null); +``` + +如果您希望在关闭界面时回退到上一个界面,您可以将当前界面对象传入自定义的 `CustomScreen` 构造方法,把它保存为字段,然后覆写 `close` 方法,将实现修改为 `this.client.setScreen(/* 您保存的上一个界面 */)` 即可。 + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +现在,当您按照上面的步骤打开界面时,您可以给构造方法的第二个参数传入当前界面对象,这样当您调用 `CustomScreen#close` 的时候,游戏就会回到上一个界面。 + +```java +Screen currentScreen = MinecraftClient.getInstance().currentScreen; +MinecraftClient.getInstance().setScreen( + new CustomScreen(Text.empty(), currentScreen) +); +``` diff --git a/versions/1.21/translated/zh_cn/develop/rendering/gui/custom-widgets.md b/versions/1.21/translated/zh_cn/develop/rendering/gui/custom-widgets.md new file mode 100644 index 000000000..52b1e0068 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/rendering/gui/custom-widgets.md @@ -0,0 +1,39 @@ +--- +title: 自定义组件 +description: 学习如何给您的界面创建自定义组件。 +authors: + - IMB11 +--- + +# 自定义组件{#custom-widgets} + +组件本质上是容器化的界面元素,可以被添加到屏幕中供玩家交互,交互方式包括鼠标点击、键盘输入等。 + +## 创建组件{#creating-a-widget} + +有很多种创建组件的方式,例如继承 `ClickableWidget`。 这个类提供了许多实用功能,比如控制组件的尺寸和位置,以及接收用户输入事件。事实上这些功能由 `Drawable`、`Element`、`Narratable`、`Selectable` 接口规定: + +- `Drawable` 用于渲染,需要通过 `Screen#addDrawableChild` 将组件注册到屏幕中。 +- `Element` 用于事件,比如鼠标点击、键盘输入等,需要这个来处理事件。 +- `Narratable` 用于无障碍,让组件能够通过屏幕阅读器或其他无障碍工具访问。 +- `Selectable` 用于选择,实现此接口后组件可以由 Tab 键选中,这也能帮助无障碍。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +## 将组件添加到屏幕{#adding-the-widget-to-the-screen} + +如同其他组件,您需要使用 `Screen#addDrawableChild` 来将组件添加到界面中。 请确保这一步在 `Screen#init` 方法中完成。 + +@[code lang=java transcludeWith=:::3](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomScreen.java) + +![屏幕中的自定义组件](/assets/develop/rendering/gui/custom-widget-example.png) + +## 组件事件{#widget-events} + +您可以自定义用户输入事件的处理逻辑,比如覆写 `onMouseClicked`、`onMouseReleased`、`onKeyPressed` 等方法。 + +举个例子,您可以使用 `ClickableWidget#isHovered` 方法来使组件在鼠标悬停时变色。 + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/screens/CustomWidget.java) + +![鼠标悬停事件](/assets/develop/rendering/gui/custom-widget-events.webp) diff --git a/versions/1.21/translated/zh_cn/develop/rendering/hud.md b/versions/1.21/translated/zh_cn/develop/rendering/hud.md new file mode 100644 index 000000000..8b6a03678 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/rendering/hud.md @@ -0,0 +1,30 @@ +--- +title: 在 Hud 中渲染 +description: 学习如何使用 HudRenderCallback 事件来渲染Hud。 +authors: + - IMB11 +--- + +# 渲染 Hud{#rendering-in-the-hud} + +在 [基本渲染概念](./basic-concepts) 页面和[使用绘制上下文](./draw-context) 中,我们已经简要介绍了如何将内容渲染到 Hud,因此在本页中,我们将重点介绍 `HudRenderCallback` 事件和 `deltaTick` 参数。 + +## HudRenderCallback{#hudrendercallback} + +由 Fabric API 提供的 `HudRenderCallback` 事件每帧都会被调用,用于向 HUD 渲染内容。 + +要注册此事件,只需调用 `HudRenderCallback.EVENT.register` 并传入一个以 `DrawContext` 和一个 `float` (deltaTick) 为参数的 lambda 表达式即可。 + +绘制上下文可用于访问游戏提供的各种渲染工具,并访问原始矩阵堆栈。 + +要了解有关绘制上下文的更多信息,应该查看[使用绘制上下文](./draw-context)页面。 + +### DeltaTick{#deltatick} + +`deltaTick` 是指距上一帧的时间,单位为秒。 这可以用来制作动画和其他基于时间的效果。 + +例如,假设要让颜色随时间变化。 可以使用 `deltaTickManager` 获得 deltaTick,并随时间存储以变化颜色。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/HudRenderingEntrypoint.java) + +![](/assets/develop/rendering/hud-rendering-deltatick.webp) diff --git a/versions/1.21/translated/zh_cn/develop/rendering/particles/creating-particles.md b/versions/1.21/translated/zh_cn/develop/rendering/particles/creating-particles.md new file mode 100644 index 000000000..ca19f481d --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/rendering/particles/creating-particles.md @@ -0,0 +1,72 @@ +--- +title: 创建自定义粒子 +description: 学习如何使用 Fabric API 创建自定义粒子。 +authors: + - Superkat32 +--- + +# 创建自定义粒子{#creating-custom-particles} + +粒子是一种强大的工具, 可以为美丽的场景增添氛围,也可以为你的 boss 战添加紧张感。 让我们创建一个自定义粒子吧! + +## 注册自定义粒子{#register-a-custom-particle} + +我们会添加新的火花粒子,模仿末地烛的粒子移动。 + +首先,需要在你的[模组初始化器](./getting-started/project-structure#entrypoints)中,使用你有模组 id,注册 `ParticleType`。 + +@[code lang=java transcludeWith=#particle_register_main](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +小写字母“sparkle_particle”是粒子纹理的 JSON 路径。 稍后就会以这个名字,创建新的 JSON 文件。 + +## 客户端注册{#client-side-registration} + +在模组的初始化器中注册粒子后,还需要在客户端的初始化器中注册粒子。 + +@[code lang=java transcludeWith=#particle_register_client](@/reference/1.21/src/client/java/com/example/docs/FabricDocsReferenceClient.java) + +在这个例子中,我们在客户端注册我们的粒子。 使用末地烛粒子的 factory,给予粒子一些移动。 这意味着,我们的粒子就会像末地烛那样移动。 + +::: tip +You can see all the particle factories by looking at all the implementations of the `ParticleFactory` interface. This is helpful if you want to use another particle's behaviour for your own particle. + +- IntelliJ 的快捷键:Ctrl+Alt+B +- Visual Studio Code 的快捷键:Ctrl+F12 + ::: + +## 创建 JSON 文件并添加纹理{#creating-a-json-file-and-adding-textures} + +你需要在你的 `resources/assets//` 文件夹中创建两个文件夹。 + +| 文件夹路径 | 说明 | +| -------------------- | ----------------------------- | +| `/textures/particle` | `particle` 文件夹会包含你的所有粒子的纹理。 | +| `/particles` | `particle` 文件夹会包含你的所有 json 文件 | + +例如,我们在 `textures/particle` 中只有一个纹理,叫做 `sparkle_particle_texture.png`。 + +然后,在 `particles` 中创建新的 JSON 文件,名称与用于创建你的 ParticleType 的 JSON 路径相同。 例如,我们需要创建 `sparkle_particle.json`。 这个文件很重要,因为让 Minecraft 知道我们的粒子应该使用哪个纹理。 + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/particles/sparkle_particle.json) + +:::tip +可以给 `textures` 数组添加更多纹理以创建粒子动画。 粒子会在这个数组中循环纹理,以第一个纹理开始。 +::: + +## 测试新的粒子{#testing-the-new-particle} + +完成了 JSON 文件并保存你的作品后,就能够载入 Minecraft 并测试好一切了! + +可以输入以下命令,看看是否一切正常: + +```mcfunction +/particle :sparkle_particle ~ ~1 ~ +``` + +![粒子的展示](/assets/develop/rendering/particles/sparkle-particle-showcase.png) + +:::info +用这个命令,粒子会生成在玩家内。 你可能需要往后走才能实际看到。 +::: + +你也可以使用相同命令,用命令方块召唤粒子。 diff --git a/versions/1.21/translated/zh_cn/develop/sounds/custom.md b/versions/1.21/translated/zh_cn/develop/sounds/custom.md new file mode 100644 index 000000000..d9b345759 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/sounds/custom.md @@ -0,0 +1,63 @@ +--- +title: 创建自定义声音 +description: 了解如何通过注册表添加和使用新声音。 +authors: + - JR1811 +--- + +# 创建自定义声音{#creating-custom-sounds} + +## 准备音频文件{#preparing-the-audio-file} + +你的音频文件需要转化为特定格式。 OGG Vorbis 是一种用于音频等多媒体数据的开放式容器格式,Minecraft 的声音文件就使用了这种格式。 为了避免 Minecraft 处理声音传播距离的问题,你的音频必须只有单声道(Mono)。 + +许多现代 DAW(数字音频工作站)软件都可以使用这种格式导入和导出。 在下面的例子中,我们将使用免费开源软件“[Audacity](https://www.audacityteam.org/)”将音频文件转换成正确的格式,当然其他的 DAW 也可以做到。 + +![Audacity 中未准备好的音频文件](/assets/develop/sounds/custom_sounds_0.png) + +在本例中,将[哨声](https://freesound.org/people/strongbot/sounds/568995/)作为例子导入 Audacity。 这个声音目前保存为 `.wav` 文件,有两个音频通道(立体声)。 按照自己的需求编辑音频,并确保使用“音轨头”顶部的下拉元素删除其中一个音频通道。 + +![分割立体声轨](/assets/develop/sounds/custom_sounds_1.png) + +![删除一个音频通道](/assets/develop/sounds/custom_sounds_2.png) + +导出或渲染音频文件时,请确认选择的是 OGG 文件格式。 有些 DAW(如 REAPER)可能支持多种 OGG 音频层格式。 在这种情况下,选择 OGG Vorbis 即可。 + +![导出为 OGG 文件](/assets/develop/sounds/custom_sounds_3.png) + +另外,记住,音频文件可能显著增加你的模组的大小。 如有必要,在编辑和导出文件时适量压缩音频本身,以尽量减小导出的文件大小。 + +## 加载音频文件{#loading-the-audio-file} + +要在你的模组中使用音频文件,要添加新的 `resources/assets//sounds` 目录,并将导出的音频文件 `metal_whistle.ogg` 放入该目录中。 + +如果 `resources/assets//sounds.json` 文件还未生成,继续创建该文件,并将你的音效添加到音效条目中。 + +@[code lang=json](@/reference/1.21/src/main/resources/assets/fabric-docs-reference/sounds.json) + +字幕(subtitle)条目为玩家提供了更多的关于该声音的信息。 在 `resources/assets//lang` 目录下的语言文件中会用到声音文件,如果游戏内字幕设置已打开且正在播放自定义声音,则会显示这个字幕。 + +## 注册自定义声音{#registering-the-custom-sound} + +要将自定义声音添加到模组,在你的[模组的初始化器](./getting-started/project-structure#entrypoints)中注册 SoundEvent。 + +```java +Registry.register(Registries.SOUND_EVENT, Identifier.of(MOD_ID, "metal_whistle"), + SoundEvent.of(Identifier.of(MOD_ID, "metal_whistle"))); +``` + +## 整理整理{#cleaning-up-the-mess} + +根据注册表项的数量,入口点类可能很快就会变得十分杂乱。 为了避免这种情况,我们可以使用一个新的辅助类。 + +在新创建的辅助类中添加两个新方法: 一个用于注册所有声音,一个用于初始化该类。 之后就可以根据需要,添加新的自定义 `SoundEvent` 常量了。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/sound/CustomSounds.java) + +如此,模组的初始化器只需实现一行即可注册所有的自定义 SoundEvents。 + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/sound/FabricDocsReferenceSounds.java) + +## 使用自定义的 SoundEvent{#using-the-custom-soundevent} + +使用辅助类去访问自定义的 SoundEvent。 查看[播放声音事件(SoundEvent)](./using-sounds)页面,了解如何播放声音。 diff --git a/versions/1.21/translated/zh_cn/develop/sounds/using-sounds.md b/versions/1.21/translated/zh_cn/develop/sounds/using-sounds.md new file mode 100644 index 000000000..dc12228f7 --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/sounds/using-sounds.md @@ -0,0 +1,34 @@ +--- +title: 播放声音 +description: 学习如何播放声音事件(SoundEvent)。 +authors: + - JR1811 +--- + +# 播放声音{#playing-sounds} + +Minecraft 有大量的声音供您选择。 查看 `SoundEvents` 类以查看 Mojang 提供的所有原版声音事件实例。 + +## 在您的模组中使用声音{#using-sounds} + +使用声音时请确保在逻辑服务端执行 `playSound()` 方法。 + +在此示例中,自定义交互项的 `useOnEntity()` 和 `useOnBlock()` 方法用于播放“放置铜块”和掠夺者声音。 + +@[code lang=java transcludeWith=:::1](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +播放声音事件(SoundEvent) 只需要指定 SoundEvent、音量(volume)和音高(pitch)。 `playerSound()` 方法与 `LivingEntity` 对象一起使用。 只需要指定 SoundEvent、音量(volume)和音高(pitch)。 您还可以使用世界实例中的 `playSound()` 方法以获得更高级别的控制。 + +@[code lang=java transcludeWith=:::2](@/reference/1.21/src/main/java/com/example/docs/item/CustomSoundItem.java) + +### 声音事件与声音组(SoundCategory){#soundevent-and-soundcategory} + +播放声音事件(SoundEvent) 声音事件定义了播放哪个声音。 您也可以[注册您自己的声音事件](./custom)以包含您自己的声音。 + +Minecraft 在游戏设置中有多个音频滑块。 `SoundCategory` 枚举类用于确定哪个滑块可以调整您声音的音量。 + +### 音量和音调{#volume-and-pitch} + +音量参数可能有些误导。 在 `0.0f - 1.0f` 的范围内可以改变声音的实际音量。 如果数字大于这个范围,将使用 `1.0f` 的音量,并且仅调整声音能听到的距离。 通过 `volume * 16` 可以粗略算出方块距离。 + +音高参数会增加或减少音高数值,还会改变声音的持续时间。 在 `(0.5f - 1.0f)` 范围内,音高和速度会减小,而较大的数字会增加音高和速度。 `0.5f` 以下的数字将保持 `0.5f`。 diff --git a/versions/1.21/translated/zh_cn/develop/text-and-translations.md b/versions/1.21/translated/zh_cn/develop/text-and-translations.md new file mode 100644 index 000000000..fc62a887f --- /dev/null +++ b/versions/1.21/translated/zh_cn/develop/text-and-translations.md @@ -0,0 +1,132 @@ +--- +title: 文本和翻译 +description: Minecraft 处理格式化文本和翻译的全面文档。 +authors: + - IMB11 + - LordEnder-Kitty +--- + +# 文本和翻译{#text-and-translations} + +Minecraft 在游戏内显示文本,不论何时,都是使用 `Text` 对象定义的。 +使用这种自定义的类型而非 `String`,是为了允许更多高级的格式化,包括颜色、加粗、混淆和点击事件。 这样还能够容易地访问翻译系统,使得将任何 UI 元素翻译成不同语言都变得容易。 + +如果以前有做过数据包和函数,应该看到用于displayName、书、告示牌等内容的就是用的 json 文本格式。 不难猜到,这就是 `Text` 对象的 json 呈现,可以使用 `Text.Serializer` 互相转换。 + +制作模组时,最好直接在代码中构造你的 `Text` 对象,并随时利用翻译。 + +## 字面文本{#text-literals} + +这是创建 `Text` 对象最简单的方式,创建字面值。 这就是会照样显示的字符串,默认没有任何格式化。 + +这些是使用 `Text.of` 或 `Text.literal` 方法创建的,这两个行为有点不同。 `Text.of` 接受 null 输入,返回 `Text` 实例。 `Text.literal` 不同,不能有空输入,返回的是 `MutableText`,是 `Text` 的子类,可以轻易地格式化和连接。 这个后面会有更多。 + +```java +Text literal = Text.of("Hello, world!"); +MutableText mutable = Text.literal("Hello, world!"); +// Keep in mind that a MutableText can be used as a Text, making this valid: +Text mutableAsText = mutable; +``` + +## 可翻译文本{#translatable-text} + +给相同的文本字符串提供多个翻译时,可以使用 `Text.translatable` 方法,引用语言文件中的任意翻译键。 如果翻译键不存在,则字面转换翻译键。 + +```java +Text translatable = Text.translatable("my_mod.text.hello"); + +// Similarly to literals, translatable text can be easily made mutable. +MutableText mutable = Text.translatable("my_mod.text.bye"); +``` + +语言文件,`en_us.json`,看上去应该像这样: + +```json +{ + "my_mod.text.hello": "Hello!", + "my_mod.text.bye": "Goodbye :(" +} +``` + +如果想在翻译中使用变量(类似于在死亡消息中可以在翻译中使用涉及的玩家和物品),可以将这些变量作为参数添加进去。 想添加多少参数都可以。 + +```java +Text translatable = Text.translatable("my_mod.text.hello", player.getDisplayName()); +``` + +在翻译中,可以像这样引用这些变量: + +```json +{ + "my_mod.text.hello": "%1$s said hello!" +} +``` + +在游戏中,%1\$s 会被替换为你在代码中引用的玩家的名字。 使用 `player.getDisplayName()` 会使用鼠标悬停在聊天消息中的名字上时,以提示框形式出现实体的额外信息,相比之下使用 `player.getName()` 只会得到名字但不显示额外细节。 对物品堆也是类似,使用 `stack.toHoverableText()`。 + +至于 %1\$s 都是指什么,你要知道的就是数字对应的你尝试使用的哪个变量。 比如说你有使用三个变量。 + +```java +Text translatable = Text.translatable("my_mod.text.whack.item", victim.getDisplayName(), attacker.getDisplayName(), itemStack.toHoverableText()); +``` + +如果要引用,比如在这里是引用谁是攻击者,应该使用 %2\$s,因为这是我们传入的第二个变量。 类似地,%3\$s 引用的是物品堆。 有这些额外参数的翻译可能会像这样: + +```json +{ + "my_mod.text.whack.item": "%1$s was whacked by %2$s using %3$s" +} +``` + +## 序列化文本{#serializing-text} + + + +前面提到过,可以使用 text codec 将文本序列化为 JSON。 更多关于 codec 的信息,请看 [Codec](./codecs) 页面。 + +@[code transcludeWith=:::1](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +这会产生可用于数据包、命令和其他接受 JSON 格式文本而非字面或可翻译文本的地方的 JSON。 + +## 反序列化文本{#deserializing-text} + +要将 JSON 文本对象反序列化为 `Text` 类,还是使用 codec。 + +@[code transcludeWith=:::2](@/reference/1.21/src/client/java/com/example/docs/rendering/TextTests.java) + +## 格式化文本{#formatting-text} + +你应该熟悉 Minecraft 的格式化标准: + +可以对 `MutableText` 类使用 `Formatting` 枚举以应用这些格式。 + +```java +MutableText result = Text.literal("Hello World!") + .formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE); +``` + + + + + + + + + + + + + + + + + + + + + + + + + +
颜色名称聊天代码MOTD 代码十六进制代码
黑色(black)§0\u00A70#000000
深蓝色(dark_blue)§1\u00A71#0000AA
深绿色(dark_green)§2\u00A72#00AA00
深青色(dark_aqua)§3\u00A73#00AAAA
深红色(dark_red)§4\u00A74#AA0000
深紫色(dark_purple)§5\u00A75#AA00AA
金色(gold)§6\u00A76#FFAA00
灰色(gray)§7\u00A77#AAAAAA
深灰色(dark_gray)§8\u00A78#555555
蓝色(blue)§9\u00A79#5555FF
绿色(green)§a\u00A7a#55FF55
青色(aqua)§b\u00A7b#55FFFF
红色(red)§c\u00A7c#FF5555
淡紫色(light_purple)§d\u00A7d#FF55FF
黄色(yellow)§e\u00A7e#FFFF55
白色(white)§f\u00A7f#FFFFFF
重置§r
加粗§l
删除线§m
下划线§n
斜体§o
混淆§k
diff --git a/versions/1.21/translated/zh_cn/index.md b/versions/1.21/translated/zh_cn/index.md new file mode 100644 index 000000000..469c8c0c3 --- /dev/null +++ b/versions/1.21/translated/zh_cn/index.md @@ -0,0 +1,21 @@ +--- +title: Fabric 文档 +description: 为 Minecraft 的一个模组制作工具链 Fabric 精心撰写的官方文档。 +layout: home +hero: + name: Fabric 文档 + tagline: 为 Minecraft 的一个模组制作工具链 Fabric 精心撰写的官方文档。 +features: + - title: 玩家指南 + icon: 📚 + details: 您在考虑使用 Fabric 模组吗? 我们的玩家指南将全程为您服务。 这些指南将从 Fabric 模组的下载、安装、错误排除等方面帮助您。 + link: /zh_cn/players/ + linkText: 详情 + - title: 开发者指南 + icon: 🛠️ + details: 我们的社区编写的开发者指南,涵盖一切,从设置你的开发环境,到渲染和网络通信等高级话题。 + link: /zh_cn/develop/ + linkText: 快速上手 +--- + +如果想给 Fabric 文档做贡献,可以在 [GitHub](https://github.com/FabricMC/fabric-docs) 找到源代码,以及相关的[贡献指南](./contributing)。 diff --git a/versions/1.21/translated/zh_cn/players/faq.md b/versions/1.21/translated/zh_cn/players/faq.md new file mode 100644 index 000000000..dc02950e2 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/faq.md @@ -0,0 +1,29 @@ +--- +title: 玩家常见问题 +description: 玩家和服务器管理员有关 Fabric 的常见问题。 +--- + +# 常规问题 {#faq} + +有很多问题经常问到,因此我们在此整理了一份清单。 + +## Fabric 支持哪些 Minecraft 版本? {#what-minecraft-versions-does-fabric-support} + +Fabric 官方支持从快照 `18w43b` 和正式版 `1.14` 及以上的所有 Minecraft 版本。 + +## 在哪里可以下载已发布的 Fabric 模组? {#where-can-i-download-published-fabric-mods} + +:::info +您应始终检查模组是否来自可信的来源。 更多信息请查看[寻找可信的模组](./finding-mods)指南。 +::: + +大多数作者都会将自己的模组发布到 [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) 和 [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\\&gameVersionTypeId=4) 上,但也有一些作者会选择将模组上传到个人网站或其他平台,如 GitHub 仓库。 + +## 在哪里可以找到现成的 Fabric 整合包? {#where-can-i-find-premade-fabric-modpacks} + +您可以在各种平台上找到现成的 Fabric 整合包,例如 + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/zh_cn/players/finding-mods.md b/versions/1.21/translated/zh_cn/players/finding-mods.md new file mode 100644 index 000000000..a8c0078f3 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: 寻找可信的模组 +description: 本指南教你如何使用可信来源找到 Fabric 模组。 +authors: + - IMB11 +--- + +# 寻找可信的模组{#finding-mods} + +首先,信任是主观的,当下载模组时你应该始终根据自己的判断。 但是,有一些方法可以帮助你找到可信的模组。 + +## 1. 使用众所周知的可信来源{#trustworthy-source} + +大部分作者都将他们的模组发布在 [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) 和 [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\\&gameVersionTypeId=4) 上。 + +这些网站会检查模组是否为他们所说的,以及是否包含恶意代码。 你还可以向那些网站举报恶意模组,他们会较快地行动。 + +## 2. 与其他人讨论! {#with-others} + +如果要从并非已知可信的来源下载模组,应该先向他人询问,看看他们是否曾从你下载的地方下载过该模组,以及他们是否遇到过任何问题。 + +如遇问题,欢迎在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 频道提问。 + +## 3. 避免常见的恶意网站! {#avoid-malware} + +:::info +恶意软件网站并非人人都能辨别。 如果不确定,应征求他人的意见,或避免使用该网站,只依靠值得信赖的来源,例如 Modrinth 和 CurseForge。 +::: + +有很多网站声称它们收录 Minecraft 模组,但实际上只是恶意软件分发网站。 你应该尽量避免使用此类网站。 + +你可以使用 [Windows Defender](https://www.microsoft.com/en-us/windows/comprehensive-security) 或 [VirusTotal](https://www.virustotal.com/) 等杀毒软件或网站来检查下载的模组。 但是,不要完全依赖这些方法,因为有时可能不正确。 + +最后,如遇问题,欢迎在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 频道提问。 diff --git a/versions/1.21/translated/zh_cn/players/index.md b/versions/1.21/translated/zh_cn/players/index.md new file mode 100644 index 000000000..238a297ac --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/index.md @@ -0,0 +1,12 @@ +--- +title: 玩家指南 +description: 为玩家和服务器管理员制作的安装和使用 Fabic 的指南合集。 +--- + +# 玩家指南{#player-guides} + +这部分的 Fabric 文档是专门为玩家和服务器管理员准备的,旨在帮助他们学习如何安装、使用 Fabric 以及排除故障。 + +所有可用的指南列表请参见侧边栏。 + +如果遇到任何问题,请在 [GitHub 上](https://github.com/FabricMC/fabric-docs) 报告问题,或者在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 或 `#server-admin-support` 频道寻求帮助。 diff --git a/versions/1.21/translated/zh_cn/players/installing-fabric.md b/versions/1.21/translated/zh_cn/players/installing-fabric.md new file mode 100644 index 000000000..07803d324 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/installing-fabric.md @@ -0,0 +1,59 @@ +--- +title: 安装 Fabric +description: 如何安装 Fabric 的手把手指南。 +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# 安装 Fabric{#installing-fabric} + + + +本指南仅适用于官方的 Minecraft Launcher。 对于第三方启动器,应该参考它们的文档。 + +## 1. 下载 Fabric 安装器{#1-download-the-fabric-installer} + +可以从 [Fabric 网站](https://fabricmc.net/use/) 下载 Fabric 安装器。 + +如果使用 Windows,下载 `.exe` 版本 (`Download For Windows`),因为不需要你的系统已安装 Java, 而是使用官方启动器附带的 Java。 + +对于 macOS 和 Linux,您应该下载 `.jar` 版本。 有时,此步骤之前需要安装 Java。 + +## 2. 运行 Fabric 安装器{#2-run-the-fabric-installer} + +:::warning +在运行安装器之前,请先关闭 Minecraft 和 Minecraft Launcher。 +::: + +:::details macOS 用户须知 + +在 macOS 上,可能需要右键点击下载目录中的 `.jar`,然后点击 `Open` 来运行。 + +![Fabric 安装器中的 MacOS 上下文菜单](/assets/players/installing-fabric/macos-downloads.png) + +问到“Are you sure you want to open it?”时,再次点击 `Open`。 +::: + +打开安装器后,应该会看到这样的屏幕: + +![高亮 "Install" 的 Fabric 安装器](/assets/players/installing-fabric/installer-screen.png) + + + +要安装 Fabric,只需从下拉列表中选择您的游戏版本,然后单击 `Install`。 + +:::warning 重要 +确保选中“Create Profile”。 +::: + +## 3. 搞定! {#3-you-re-done} + +安装器完成后,可以打开 Minecraft Launcher,从左下角的下拉列表中选择 Fabric 配置文件,然后按下 `Play`! + +![选中了 Fabric 配置的 Minecraft Launcher](/assets/players/installing-fabric/launcher-screen.png) + +现在安装好了 Fabric,就可以向你的游戏添加模组了! 更多信息请查看[寻找可信的模组](./finding-mods)指南。 + +如果在遵循本指南时遇到任何问题,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 频道中寻求帮助。 diff --git a/versions/1.21/translated/zh_cn/players/installing-java/linux.md b/versions/1.21/translated/zh_cn/players/installing-java/linux.md new file mode 100644 index 000000000..95e7069af --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: 在 Linux 上安装 Java +description: 手把手指导如何在 Linux 上安装 Java。 +authors: + - IMB11 +--- + +# 在 Linux 上安装 Java{#installing-java-on-linux} + +这个指南将会指引您在 Linux 上安装 Java 21。 + +## 1. 检查 Java 是否已经安装{#1-check-if-java-is-already-installed} + +打开终端输入 `java -version` 并按下 `回车`。 + +![输入 "java -version" 的终端](/assets/players/installing-java/linux-java-version.png) + +:::warning +要使用 Minecraft 1.21,你需要安装至少 Java 21。 如果运行该命令后显示 Java 版本低于 21,你需要更新设备上现有 Java。 +::: + +## 2. 下载并安装 Java 21{#2-downloading-and-installing-java} + +我们推荐使用 OpenJDK 21,可以在大多数 Linux 发行版中可用。 + +### Arch Linux{#arch-linux} + +:::info +更多在 Arch Linux 上安装 Java 的信息可以参考 [Arch Linux 中文维基](https://wiki.archlinuxcn.org/wiki/Java)。 +::: + +您可以从官方仓库安装最新版 JRE: + +```sh +sudo pacman -S jre-openjdk +``` + +如果您正在运行服务器不需要图形用户界面,您可以安装无头版本: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +如果您计划开发模组,您需要安装 JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu{#debian-ubuntu} + +您可以用以下命令使用 `apt` 安装 Java 21: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora{#fedora} + +您可以用以下命令使用 `dnf` 安装 Java 21: + +```sh +sudo dnf install java-21-openjdk +``` + +如果不需要图形化界面,可以安装 headless 版本: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +如果您计划开发模组,您需要安装 JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### 其他 Linux 发行版{#other-linux-distributions} + +如果您的发行版未在上文列出,您可以从 [Adoptium](https://adoptium.net/zh-CN/temurin/) 下载最新版 JRE。 + +如果您计划开发模组,您应该参考您的发行版的替代指南。 + +## 3. 验证是否已安装 Java 21{#3-verify-that-java-is-installed} + +安装完成后,您可以打开终端并输入 `java -version` 来验证 Java 21 是否已安装。 + +如果命令成功执行,你可以看到类似前文所示的内容,Java 版本被显示出来: + +![输入 "java -version" 的终端](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/zh_cn/players/installing-java/windows.md b/versions/1.21/translated/zh_cn/players/installing-java/windows.md new file mode 100644 index 000000000..f5fe7b339 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: 在 Windows 上安装 Java +description: 在 Windows 上安装 Java 的逐步指南。 +authors: + - IMB11 +--- + +# 在 Windows 上安装 Java {#installing-java-on-windows} + +这个指南将会指引您在 Windows 上安装 Java 21。 + +Minecraft 启动器附带了自己的 Java 安装,因此这部分只在你想使用 Fabric 的 `.jar` 安装器,或者你想使用 Minecraft 服务器的 `.jar` 时有关。 + +## 1. 检查 Java 是否已经安装{#1-check-if-java-is-already-installed} + +要检查 Java 是否已安装,你首先必须打开命令提示符。 + +你可以通过按下 Win + R 并在出现的对话框中输入 `cmd.exe` 来实现它。 + +![Windows运行对话框中的「cmd.exe」](/assets/players/installing-java/windows-run-dialog.png) + +打开命令提示符后,输入 `java -version` 并按下 Enter 键。 + +如果命令成功运行,你会看到类似这样的内容。 如果命令运行失败,请继续进行下一步。 + +![命令提示符中输入了「java -version」](/assets/players/installing-java/windows-java-version.png) + +:::warning +要使用 Minecraft 1.21,你需要安装至少 Java 21。 如果运行该命令后显示 Java 版本低于 21,你需要更新设备上现有 Java。 +::: + +## 2. 下载 Java 21 安装程序{#2-download-the-java-installer} + +要安装 Java 21,你需要从 [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21) 下载安装程序。 + +你需要下载 `Windows Installer (.msi)` 版本: + +![Adoptium 下载页面,使用了 Windows 安装程序 (.msi)](/assets/players/installing-java/windows-download-java.png) + +如果你有 32 位操作系统,应该选择 `x86`;如果你有 64 位操作系统,则应该选择 `x64`。 + +现代大多数电脑都运行 64 位操作系统。 如果你不确定,请尝试使用 64 位的下载。 + +## 3. 运行安装程序! {#3-run-the-installer} + +按照安装程序的步骤安装 Java 21。 当你到达这个页面时,你应该将以下功能设置为「整个功能将安装在本机硬盘上」: + +- `Set JAVA_HOME environment variable` - 这将加入到你的PATH中。 +- `JavaSoft (Oracle) registry keys` + +![Java 21 安装程序,具有「Set JAVA\_HOME variable」和「JavaSoft (Oracle) registry keys」](/assets/players/installing-java/windows-wizard-screenshot.png) + +完成后,你可以按 `下一步` 继续安装。 + +## 4. 验证是否已安装 Java 21{#4-verify-that-java-is-installed} + +安装完成后,您可以打开命令提示符并输入 `java -version` 来验证 Java 21 是否已安装。 + +如果命令成功执行,你可以看到类似前文所示的内容,Java 版本被显示出来: + +![命令提示符中输入了「java -version」](/assets/players/installing-java/windows-java-version.png) + +--- + +如果遇到任何问题,你可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 频道中寻求帮助。 diff --git a/versions/1.21/translated/zh_cn/players/installing-mods.md b/versions/1.21/translated/zh_cn/players/installing-mods.md new file mode 100644 index 000000000..2d3808e68 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: 安装模组 +description: Fabric 模组安装的逐步指南 +authors: + - IMB11 +--- + +# 安装模组{#installing-mods} + +这个指南将引导你使用 Minecraft 启动器安装 Fabric 模组。 + +对于第三方启动器,应该参见这些第三方启动器的文档。 + +## 1. 下载模组{#1-download-the-mod} + +:::warning +你应该只从你信任的来源下载模组。 关于寻找模组的更多信息,请看[寻找可信的模组](./finding-mods)指南。 +::: + +大多数模组都需要 Fabric API,可从 [Modrinth](https://modrinth.com/mod/fabric-api) 或 [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api) 下载。 + +下载模组时,请确保: + +- 能在你想玩的 Minecraft 版本上运行。 例如,在 1.20 运行的模组在 1.20.2 可能无法运行。 +- 模组是用于 Fabric 的,而不是其他模组加载器。 +- 此外,适用于正确的 Minecraft(Java 版)的版本。 + +## 2. 将模组移到 `mods` 文件夹{#2-move-the-mod-to-the-mods-folder} + +各个操作系统中,模组文件夹的位置如下所示: + +你通常可以将这些路径粘贴到文件资源管理器的地址栏中,以快速导航到文件夹。 + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +找到 `mods` 文件夹后,就可以将模组 `.jar` 文件移入其中。 + +![已在模组文件夹中安装模组](/assets/players/installing-mods.png) + +## 3. 搞定! {#3-you-re-done} + +将模组移入 `mods` 文件夹后,你可以打开 Minecraft 启动器,从左下角的下拉菜单中选择 Fabric 配置文件,然后按下 `Play`! + +![选择了 Fabric 配置的官方启动器](/assets/players/installing-fabric/launcher-screen.png) + +## 疑难解答{#troubleshooting} + +如果在遵循本指南时遇到任何问题,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 频道中寻求帮助。 + +也可以尝试阅读疑难解答页面,尝试自己解决问题: + +- [崩溃报告](./troubleshooting/crash-reports) +- [上传日志](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/zh_cn/players/troubleshooting/crash-reports.md b/versions/1.21/translated/zh_cn/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..9d6adc100 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/troubleshooting/crash-reports.md @@ -0,0 +1,107 @@ +--- +title: 崩溃报告 +description: 学习如何处理崩溃报告以及如何阅读。 +authors: + - IMB11 +--- + +# 崩溃报告{#crash-reports} + +:::tip +如果在查找崩溃原因时遇到任何困难,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 或 `#server-admin-support` 频道中寻求帮助。 +::: + +崩溃报告是解决游戏或服务器问题的重要部分, 包含大量关于崩溃的信息,可以帮助你找到崩溃的原因。 + +## 寻找崩溃报告{#finding-crash-reports} + +崩溃报告存储在游戏目录中的 `crash-reports` 文件夹中。 如果是服务器,则存储在服务器目录中的 `crash-reports` 文件夹中。 + +对于第三方启动器,你应该参考其文档,了解在哪里可以找到崩溃报告。 + +以下位置能找到崩溃报告: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## 阅读崩溃报告{#reading-crash-reports} + +崩溃报告的篇幅很长,读起来可能十分费解, 然而包含大量关于崩溃的信息,可以帮助你找到崩溃的原因。 + +在本指南中,我们将以 [该崩溃报告](/assets/players/crash-report-example.txt) 为例。 + +:::details 显示崩溃报告 + +<<< @/public/assets/players/crash-report-example.txt{log} + +::: + +### 崩溃报告的各部分{#crash-report-sections} + +崩溃报告由几个部分组成,每个部分用标题分隔: + +- `---- Minecraft Crash Report ----`,报告的摘要。 该部分包含导致崩溃的主要错误原因、发生时间和相关堆栈跟踪。 这是崩溃报告中最重要的部分,因为堆栈跟踪通常会提及到导致崩溃的模组。 +- `-- Last Reload --`,这部分不太有用,除非崩溃发生在资源重载过程中(F3+T)。 该部分将包含上次重载的发生时间,以及重载过程中出现的任何错误的相关堆栈跟踪。 这些错误通常是由资源包引起的,可以忽略,除非是这些资源包导致的游戏出现问题。 +- `-- System Details --`,本部分包含有关系统的信息,如操作系统、Java 版本和分配给游戏的内存量。 该部分有助于确定你使用的 Java 版本是否正确,以及是否为游戏分配了足够的内存。 + - 在此部分中,Fabric 将插入一些自定义内容,其标题为 `Fabric Mods:`,后面是所有已安装模组的列表。 该部分有助于判断模组之间是否可能已发生冲突。 + +### 分解崩溃报告{#breaking-down-the-crash-report} + +既然已经知道崩溃报告的每个部分是什么,就可以开始分解崩溃报告并找出崩溃原因。 + +利用上面链接的崩溃示例,我们可以分析崩溃报告并找到崩溃原因,包括导致崩溃的模组。 + +在这个情形中,`---- Minecraft Crash Report ---- ` 部分中的堆栈跟踪最重要,因为包含导致崩溃的主要错误。 + +:::details 显示错误详情 + +<<< @/public/assets/players/crash-report-example.txt{7 log} + +::: + +堆栈跟踪中提到了大量模组,因此很难指出原因,不过,首先要做的是查找导致崩溃的模组。 + +在这里,导致崩溃的模组是 `snownee`,因为它是堆栈跟踪中提到的第一个模组。 + +不过,提到的模组有很多,可能意味着模组之间存在一些兼容性问题,导致崩溃的模组可能并不是出错的模组。 在这种情况下,最好向模组作者报告崩溃情况,让他们调查崩溃原因。 + +## Mixin 崩溃{#mixin-crashes} + +:::info +Mixin 是一种修改游戏而无需修改游戏的源代码的方式。 许多模组都用了 mixin,这对于开发者来说是非常强大的工具。 +::: + +当有 mixin 崩溃时,通常会在堆栈跟踪中提到该 mixin 类以及该 mixin 类修改的类。 + +方法 mixin 会在堆栈跟踪中包含 `modid$handlerName`,其中 `modid` 是模组的 ID,`handlerName` 是 mixin 处理器的名称。 + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +你可以使用此信息找到导致崩溃的模组,并向模组作者报告崩溃情况。 + +## 如何处理崩溃报告{#what-to-do-with-crash-reports} + +处理崩溃报告的最佳方法是将其上传到在线粘贴板网站,然后将链接分享给模组作者,可以是在他们的问题追踪器,或通过某种联系方式(Discord 等)。 + +这可以让模组作者调查崩溃、复现崩溃并解决导致崩溃的问题。 + +常用的崩溃报告粘贴网站有: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/zh_cn/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/zh_cn/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..42cdf78aa --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: 上传日志 +description: 如何上传日志以进行疑难解答。 +authors: + - IMB11 +--- + +# 上传日志{#uploading-logs} + +在进行疑难解答时,通常需要提供日志以帮助寻找问题的原因。 + +## 为什么我应该上传日志? {#why-should-i-upload-logs} + +上传日志可以让其他人更快地帮助您疑难解答,而不是简单地将日志粘贴到聊天或论坛帖子中, 还允许你与其他人分享你的日志,而无需复制和粘贴。 + +有些粘贴网站还为日志提供语法高亮,使日志更容易阅读,但可能会审查敏感信息,如用户名或系统信息。 + +## 崩溃报告{#crash-reports} + +游戏崩溃时会自动生成崩溃报告。 崩溃报告只包含崩溃信息,不包含游戏的实际日志。 崩溃报告位于游戏目录中的 `crash-reports` 文件夹中。 + +有关崩溃报告的更多信息,请参阅[崩溃报告](./crash-reports)。 + +## 找到日志{#locating-logs} + +本指南涵盖了官方 Minecraft 启动器(通常称为“原版启动器”),对于第三方启动器,你应该参阅其文档。 + +日志位于游戏目录下的 `logs` 文件夹中,游戏目录可以在以下位置找到,具体取决于你的操作系统: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +最新的日志文件名为 `latest.log`,先前的日志使用命名格式 `yyyy-mm-dd_number.log.gz`。 + +## 在线上传日志{#uploading-logs-online} + +日志可以上传到各种服务,例如: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/zh_cn/players/updating-fabric.md b/versions/1.21/translated/zh_cn/players/updating-fabric.md new file mode 100644 index 000000000..c284075f5 --- /dev/null +++ b/versions/1.21/translated/zh_cn/players/updating-fabric.md @@ -0,0 +1,41 @@ +--- +title: 更新 Fabric +description: 更新 Fabric 的手把手的指南 +authors: + - IMB11 + - modmuss50 +--- + +# 更新 Fabric{#updating-fabric} + +这篇指南将引导您在 Minecraft 启动器中更新 Fabric。 + +对于第三方启动器,应该参见这些第三方启动器的文档。 + +更新 Fabric 和安装 Fabric 的过程非常相似,所以该指南的一部分与 [安装 Fabric](./installing-fabric) 指南完全一致。 + +## 为什么应该更新 Fabric Loader? {#why-should-i-update-fabric-loader} + +新的模组可能需要新版本的 Fabric Loader 才能运行,所以保持更新很重要,从而确保能够使用最新的模组。 + + + +要更新 Fabric,简单地确认游戏版本和加载器版本是正确的,然后点击 `安装` 。 + +:::warning 重要 +**运行安装程序时,请确保没有选中“创建新的启动器配置”,否则将创建新的配置文件,而这种情况下我们不需要。** +::: + +## 3. 在 Minecraft 启动器中打开配置{#3-open-the-profile-in-the-minecraft-launcher} + +安装器完成后,可以打开 Minecraft 启动器并前往 `Installations(安装)` 选项。 您应当前往您的 Fabric 配置并打开编辑界面。 + +将该版本替换为刚才安装的 Fabric Loader 版本并点击 `保存`。 + +![在 Minecraft 启动器中更新 Fabric Loader 版本](/assets/players/updating-fabric.png) + +## 4. 搞定! {#4-you-re-done} + +完成这些步骤后,就可以回到 `Play` 选项卡,从左下角的下拉菜单中选择 Fabric 配置文件,然后按下启动按钮! + +如果在遵循本指南时遇到任何问题,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 频道中寻求帮助。 diff --git a/versions/1.21/translated/zh_cn/sidebar_translations.json b/versions/1.21/translated/zh_cn/sidebar_translations.json new file mode 100644 index 000000000..da44b5d45 --- /dev/null +++ b/versions/1.21/translated/zh_cn/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "玩家指南", + "players.faq": "常见问题", + "players.installingJava": "安装 Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "安装 Fabric", + "players.findingMods": "寻找可信的模组", + "players.installingMods": "安装模组", + "players.troubleshooting": "疑难解答", + "players.troubleshooting.uploadingLogs": "上传你的日志", + "players.troubleshooting.crashReports": "崩溃报告", + "players.updatingFabric": "更新 Fabric", + "develop.title": "开发者指南", + "develop.gettingStarted": "入门", + "develop.gettingStarted.introduction": "Fabric 和模组简介", + "develop.gettingStarted.devEnvSetup": "设置开发环境", + "develop.gettingStarted.creatingProject": "创建项目", + "develop.gettingStarted.projectStructure": "项目结构", + "develop.gettingStarted.launchGame": "启动游戏", + "develop.gettingStarted.solvingProblems": "基本问题解决", + "develop.items": "物品", + "develop.items.first-item": "创建你的第一个物品", + "develop.items.food": "食物物品", + "develop.items.custom-armor": "自定义盔甲", + "develop.items.custom-tools": "自定义工具", + "develop.items.custom-item-groups": "自定义物品组", + "develop.items.custom-item-interactions": "自定义物品交互", + "develop.items.potions": "药水", + "develop.items.custom-data-components": "自定义数据组件", + "develop.blocks": "方块", + "develop.blocks.first-block": "创建你的第一个方块", + "develop.blocks.blockstates": "方块状态", + "develop.entities": "实体", + "develop.entities.effects": "状态效果", + "develop.entities.damage-types": "伤害类型", + "develop.commands": "命令", + "develop.commands.basics": "创建命令", + "develop.commands.arguments": "参数", + "develop.commands.suggestions": "建议", + "develop.rendering": "渲染", + "develop.rendering.basicConcepts": "基本的渲染概念", + "develop.rendering.drawContext": "使用绘图上下文", + "develop.rendering.hud": "在 HUD 中渲染", + "develop.rendering.gui": "GUI 与界面", + "develop.rendering.gui.customScreens": "自定义界面", + "develop.rendering.gui.customWidgets": "自定义控件", + "develop.rendering.particles": "粒子", + "develop.rendering.particles.creatingParticles": "创建自定义的粒子", + "develop.misc": "杂项", + "develop.misc.codecs": "Codecs", + "develop.misc.events": "事件", + "develop.misc.text-and-translations": "文本和翻译", + "develop.misc.ideTipsAndTricks": "IDE 技巧和窍门", + "develop.misc.automatic-testing": "自动化测试", + "develop.sounds": "声音", + "develop.sounds.using-sounds": "播放声音", + "develop.sounds.custom": "创建自定义声音" +} diff --git a/versions/1.21/translated/zh_cn/website_translations.json b/versions/1.21/translated/zh_cn/website_translations.json new file mode 100644 index 000000000..f3c9a4c25 --- /dev/null +++ b/versions/1.21/translated/zh_cn/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "页面作者", + "authors.nogithub": "%s(不在 GitHub)", + "banner": "Fabric 文档仍在进展中,请在 %s 或 %s 报告问题。", + "description": "Minecraft 的模组开发工具链 Fabric 的全面文档。", + "download": "下载 %s", + "footer.next": "下一页", + "footer.prev": "上一页", + "github_edit": "在 GitHub 编辑此页", + "lang_switcher": "更改语言", + "last_updated": "上次更新于", + "mode_dark": "切换到深色主题", + "mode_light": "切换到浅色主题", + "mode_switcher": "外观", + "nav.contribute": "贡献", + "nav.contribute.api": "Fabric API", + "nav.download": "下载", + "nav.home": "首页", + "outline": "在本页", + "return_to_top": "回到顶部", + "search.back": "关闭搜索", + "search.button": "搜索", + "search.display_details": "显示详细列表", + "search.footer.close": "关闭", + "search.footer.close.key": "Escape", + "search.footer.down.key": "下箭头", + "search.footer.navigate": "导航", + "search.footer.up.key": "上箭头", + "search.footer.select": "选择", + "search.footer.select.key": "Enter", + "search.no_results": "没有以下的结果", + "search.reset": "重置搜索", + "sidebar_menu": "菜单", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Fabric 文档", + "version.reminder": "本页面基于这个版本编写:", + "version.switcher": "切换版本", + "404.code": "404", + "404.crowdin_link": "在 Crowdin 中本地化", + "404.crowdin_link.label": "打开 Crowdin 编辑器", + "404.english_link": "用英语阅读", + "404.english_link.label": "打开英文版", + "404.link": "返回主页", + "404.link.label": "前往主页", + "404.quote": "这个页面试图在熔岩里游泳", + "404.title": "未找到页面" +} diff --git a/versions/1.21/translated/zh_tw/contributing.md b/versions/1.21/translated/zh_tw/contributing.md new file mode 100644 index 000000000..72e423a88 --- /dev/null +++ b/versions/1.21/translated/zh_tw/contributing.md @@ -0,0 +1,179 @@ +# Fabric 文件貢獻指南 + +這個網站使用 [VitePress](https://vitepress.dev/) 來將各種 Markdown 檔案轉換成靜態 HTML。 這個網站使用 [VitePress](https://vitepress.dev/) 來從各種 Markdown 檔案轉換成靜態 HTML。 這個網站使用 [VitePress](https://vitepress.dev/) 來從各種 Markdown 檔案轉換成靜態 HTML。 這個網站使用 [VitePress](https://vitepress.dev/) 來從各種 Markdown 檔案轉換成靜態 HTML。 這個網站使用 [VitePress](https://vitepress.dev/) 來從各種 Markdown 檔案轉換成靜態 HTML。 你應該熟悉 VitePress 支援的 Markdown 擴充功能,詳細內容請參閱[這裡](https://vitepress.dev/guide/markdown#features)。 + +## 目錄 + +- [Fabric 文件貢獻指南](#fabric-documentation-contribution-guidelines) + - [如何貢獻](#how-to-contribute) + - [貢獻框架](#contributing-framework) + - [貢獻內容](#contributing-content) + - [格式指南](#style-guidelines) + - [擴充指南](#guidance-for-expansion) + - [內容驗證](#guidance-for-expansion) + - [清理](#cleanup) + - [翻譯文件](#translating-documentation) + +## 如何貢獻 + +我們建議每次送出合併請求時,都在你的儲存庫中新增一個分支。 這讓同時管理多個合併請求變得更加容易。 + +如果你想在本機預覽你的變更,你需要安裝 [Node.js 18+](https://nodejs.org/zh-tw/)。 + +在執行以下指令前,請先執行 `npm install` 來安裝所有相依項。 + +**正在執行程式開發伺服器:** + +這將讓你能在本機預覽你的變更,網址是 `localhost:3000`,並且在你進行變更時會自動重新載入頁面。 + +```sh +npm run dev +``` + +**建構網站:** + +這將把所有的 Markdown 檔案編譯成靜態 HTML 檔案,並將它們放置在 `.vitepress/dist` 資料夾中。 + +```sh +npm run build +``` + +**預覽已建置的網站:** + +這將在連接埠 3000 上啟動本機伺服器,提供在 `.vitepress/dist` 中找到的內容。 + +```sh +npm run preview +``` + +## 貢獻框架 + +框架指的是網站的內部結構,任何修改網站框架的合併請求應該標記為 `framework` 標籤。 + +在進行框架合併請求前,你應該先與 [Fabric Discord](https://discord.gg/v6v4pMv) 上的文件團隊諮詢,或者透過提出問題進行討論。 + +**備註:修改側邊欄檔案和導覽列配置不算作框架合併請求。** + +## 貢獻內容 + +貢獻內容是貢獻 Fabric 文件的主要方式。 + +所有內容應遵循我們的風格指南。 + +### 風格指南 + +所有 Fabric 文件網站上的頁面都應遵循風格指南。 所有 Fabric 文件網站上的頁面都應遵循風格指南。 如果你對任何事情感到不確定,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 或 GitHub 討論中提問。 所有 Fabric 文件網站上的頁面都應遵循風格指南。 所有 Fabric 文件網站上的頁面都應遵循風格指南。 如果你對任何事情感到不確定,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 或 GitHub 討論中提問。 所有 Fabric 文件網站上的頁面都應遵循風格指南。 所有 Fabric 文件網站上的頁面都應遵循風格指南。 如果你對任何事情感到不確定,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 或 GitHub 討論中提問。 所有 Fabric 文件網站上的頁面都應遵循風格指南。 如果你對任何事情感到不確定,可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 或 GitHub 討論中提問。 + +風格指南如下: + +1. 所有頁面必須在 frontmatter 中包含標題和描述。 + + ```md + --- + title: 這是頁面的標題 + description: 這是頁面的描述 + authors: + - GitHub 使用者名稱 + --- + ``` + +2. 如果你建立或修改包含程式碼的頁面,請將程式碼放置在參考模組的適當位置(位於儲存庫的 `/reference` 資料夾中)。 如果你建立或修改包含程式碼的頁面,請將程式碼放置在參考模組的適當位置(位於儲存庫的 `/reference` 資料夾中)。 接著,使用 VitePress 提供的 [程式碼片段功能](https://vitepress.dev/guide/markdown#import-code-snippets) 嵌入程式碼,或者如果你需要更大的控制範圍,可以使用 `markdown-it-vuepress-code-snippet-enhanced` 的 [轉入功能](https://github.com/fabioaanthony/markdown-it-vuepress-code-snippet-enhanced)。 + + **範例:** + + ```md + <<< @/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java{15-21 java} + ``` + + 這將在參考模組中嵌入 `FabricDocsReference.java` 檔案的第 15 至 21 行程式碼。 + + 產生的程式碼片段將如下所示: + + ```java + @Override + public void onInitialize() { + // 當 Minecraft 達到模組載入就緒的狀態時,這個程式碼將立即執行。 + // 但是,某些事物(如資源)可能仍未初始化。 + // 請小心謹慎地進行。 + + LOGGER.info("你好,Fabric 世界!"); + } + ``` + + **轉入範例:** + + ```md + @[code transcludeWith=#test_transclude](@/reference/.../blah.java) + ``` + + 這將嵌入標記為 `#test_transclude` 的 `blah.java` 檔案的部分。 + + 例如: + + ```java + public final String test = "再見,世界!"; + + // #test_transclude + public void test() { + System.out.println("你好,世界!"); + } + // #test_transclude + ``` + + 只有位於 `#test_transclude` 標籤之間的程式碼將被嵌入。 + + ```java + public void test() { + System.out.println("你好,世界!"); + } + ``` + +3. 所有的原始文件都會以英語撰寫,並遵循美式英語的文法規則。 你可以使用 [LanguageTool](https://languagetool.org/) 在輸入時檢查你的語法,但不要太擔心。 我們的文件團隊將在清理階段審查並更正文法錯誤。 然而,一開始就努力做到正確可以節省我們的時間。 我們的文件團隊將在清理階段審查並更正文法錯誤。 然而,一開始就努力做到正確可以節省我們的時間。 + +4. 如果你正在建立新章節,你應該在 `.vitepress/sidebars` 資料夾中建立一個新的側邊欄,並將其新增到 `config.mts` 檔案中。 如果你需要幫助,請在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#wiki` 頻道中提問。 如果你需要幫助,請在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#docs` 頻道中提問。 + +5. 當建立新頁面時,你應將其新增到 `.vitepress/sidebars` 資料夾中相關的側邊欄中。 同上,如果你需要幫助,請在Fabric Discord上的`#docs`頻道中提問。 + +6. 任何影像應該放置在 `/assets` 資料夾中的適當位置。 + +7. ⚠️ **連結其他頁面時,請使用相對連結。** ⚠️ + + 這是因為系統中存在的版本控制系統,該系統將處理連結以在前面新增版本號。 如果你使用絕對連結,則不會將版本號新增到連結中。 如果你使用絕對連結,則不會將版本號新增到連結中。 + + 例如,對於位於 `/players` 資料夾中的頁面,要連結到 `/players/installing-fabric.md` 中的 `installing-fabric` 頁面,你應該執行以下動作: + + ```md + [這是指向另一個頁面的連結](./installing-fabric) + ``` + + 你**不應該**執行以下動作: + + ```md + [這是指向另一個頁面的連結](/players/installing-fabric) + ``` + +所有內容貢獻經歷三個階段: + +1. 擴充指導(如果可能) +2. 內容驗證 +3. 清理(語法等) + +### 擴充指南 + +如果文件團隊認為你可以擴充你的合併請求,團隊成員將在你的合併請求中新增 `expansion` 標籤,並附上一則留言,解釋他們認為你可以擴展的內容。 如果你同意這個建議,你可以擴充你的合併請求。 + +**不要感到被迫擴充你的合併請求。**如果你不想擴充你的合併請求,你可以簡單地要求移除 `expansion` 標籤。 + +如果你不想擴展你的合併請求,但你願意讓其他人在以後擴展它,最好是在[議題頁面](https://github.com/FabricMC/fabric-docs/issues)上建立一個問題,並解釋你認為可以擴展的內容。 + +### 內容驗證 + +所有新增內容的合併請求都經過內容驗證,這是最重要的階段,因為它確保內容準確無誤並符合 Fabric 文件的風格指南。 + +### 清理 + +在這個階段,文件團隊將在合併之前修復任何文法問題並進行他們認為必要的任何其他變更! + +## 翻譯文件 + +如果想將文件翻譯成別的語言,你可以在[Fabric Crowdin](https://crowdin.com/project/fabricmc)頁面上翻譯。 diff --git a/versions/1.21/translated/zh_tw/develop/getting-started/creating-a-project.md b/versions/1.21/translated/zh_tw/develop/getting-started/creating-a-project.md new file mode 100644 index 000000000..497c3efa2 --- /dev/null +++ b/versions/1.21/translated/zh_tw/develop/getting-started/creating-a-project.md @@ -0,0 +1,68 @@ +--- +title: 建立專案 +description: 關於如何使用 Fabric 模組模板生成器來製作新的模組專案的逐步指南。 +authors: + - IMB11 +--- + +# 建立專案 {#creating-a-project} + +Fabric 提供了使用 Fabric 模組模板生成器創建新模組專案的簡單方法。 —— 如果你願意,也可以使用範例模組儲存庫手動創建一個新專案,請參閱 [手動創建專案](#manual-project-creation) 章節。 + +## 生成專案 {#generating-a-project} + +你可以使用 [Fabric Template Mod Generator](https://fabricmc.net/develop/template/) 來生成你的新模組專案 —— 你需要填寫必要的部分,比如套件名稱和模組名稱,還有你想開發的模組的 Minecraft 版本。 + +![Preview of the generator](/assets/develop/getting-started/template-generator.png) + +如果你想要使用 Kotlin 進行開發,或是想增加 data generators ,可以在 `Advanced Options` 部分勾選對應的選項。 + +![Advanced options section](/assets/develop/getting-started/template-generator-advanced.png) + +必要的部分輸入完成後,點擊 `Generate` 按鈕,生成器會以 zip 檔的形式產生新專案給你使用。 + +你需要把這個 zip 檔解壓縮到你想要的位置,然後從 IntelliJ IDEA 打開解壓縮後的資料夾: + +![Open Project Prompt](/assets/develop/getting-started/open-project.png) + +## 導入專案 {#importing-the-project} + +在 IntelliJ IDEA 打開專案後, IDE 會自動載入專案的 Gradle 配置並執行必要的初始化任務。 + +如果你收到了一個關於 Gradle 構建腳本的通知,你應該點擊 `Import Gradle Project` 按鈕: + +![Gradle Prompt](/assets/develop/getting-started/gradle-prompt.png) + +專案導入完成後,你就可以在專案資源管理器中看到專案的文件,就能開始開發你的模組了。 + +## 手動建立專案 {#manual-project-creation} + +:::warning +你會需要安裝 [Git](https://git-scm.com/) 來複製範例模組儲存庫。 +::: + +如果你無法使用 Fabric 模組模板生成器,可以按照以下步驟手動建立新專案。 + +首先,使用 Git 複製範例模組儲存庫: + +```sh +git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project +``` + +這會把儲存庫複製到一個叫 `my-mod-porject` 的新資料夾。 + +你應該從複製的存儲庫中刪除 `.git` 資料夾,然後在 IntelliJ IDEA 中打開專案。 如果 `.git` 資料夾沒有顯示,你應該在檔案總管中開啟 `顯示隱藏的項目` 。 + +在 IntelliJ IDEA 中打開專案後,它應該會自動載入專案的 Gradle 配置並執行必要的初始化任務。 + +再次強調,如果你收到了一個關於 Gradle 構建腳本的通知,你應該點擊 `Import Gradle Project` 按鈕。 + +### 修改模板 {#modifying-the-template} + +專案導入後,你應該修改專案的細節,以符合你的模組的資訊: + +- 修改專案中的 `gradle.properties` 檔案,把 `maven_group` 和 `archive_base_name` 修改成與你的模組的資訊相符。 +- 修改 `fabric.mod.json` 文件,將 `id`、`name` 和 `description` 屬性改為成與你的模組的資訊相符。 +- 請確保更新Minecraft的版本、映射、Loader和Loom的版本,你可以透過 https://fabricmc.net/develop/ 查詢這些資訊,以確保它們符合你希望的目標版本。 + +你也可以修改套件名稱和模組的主類別來符合你的模組的細節。 diff --git a/versions/1.21/translated/zh_tw/develop/getting-started/introduction-to-fabric-and-modding.md b/versions/1.21/translated/zh_tw/develop/getting-started/introduction-to-fabric-and-modding.md new file mode 100644 index 000000000..99955da0e --- /dev/null +++ b/versions/1.21/translated/zh_tw/develop/getting-started/introduction-to-fabric-and-modding.md @@ -0,0 +1,65 @@ +--- +title: Fabric 與模組簡介 +description: Minecraft Java 版中 Fabric 和模組開發的簡要介紹。 +authors: + - IMB11 + - itsmiir +authors-nogithub: + - basil4088 +--- + +# Fabric 與模組開發簡介 {#introduction-to-fabric-and-modding} + +## 先決條件 {#prerequisites} + +在開始之前,您應該具備 Java 開發的基礎知識,以及對物件導向程式設計 (OOP) 的理解。 + +如果您不熟悉這些概念,建議您在開始模組開發之前,先參考一些關於 Java 和 OOP 的教學資源,以下是一些您可以用來學習 Java 和 OOP 的資源: + +- [W3:Java 教學](https://www.w3schools.com/java/) +- [Codecademy:學習 Java](https://www.codecademy.com/learn/learn-java) +- [W3:Java OOP](https://www.w3schools.com/java/java_oop.asp) +- [Medium:OOP 簡介](https://medium.com/@Adekola_Olawale/beginners-guide-to-object-oriented-programming-a94601ea2fbd) + +### 術語 {#terminology} + +在我們開始之前,讓我們先來了解一些您在使用 Fabric 進行模組開發時會遇到的術語: + +- **模組 (Mod)**:對遊戲的修改,可以加入新功能或變更現有功能。 +- **模組載入器 (Mod Loader)**:將模組載入到遊戲中的工具,例如 Fabric Loader。 +- **Mixin**:一種在執行時修改遊戲程式碼的工具。想要了解更多資訊,可以參考 [Mixin 簡介](https://fabricmc.net/wiki/tutorial:mixin_introduction)。 +- **Gradle**:一種用於構建和編譯模組的構建自動化工具,Fabric 使用它來構建模組。 +- **映射 (Mappings)**:一組將混淆程式碼映射到人類可讀程式碼的映射。 +- **混淆 (Obfuscation)**:使程式碼難以理解的過程,Mojang 使用它來保護 Minecraft 的程式碼。 +- **重新映射 (Remapping)**:將混淆程式碼映射到人類可讀程式碼的過程。 + +## 什麼是 Fabric? {#what-is-fabric} + +Fabric 是一個輕量級的 Minecraft Java 版模組開發工具鏈。 + +它被設計成一個簡單易用的模組開發平台。 Fabric 是一個社群驅動的專案,並且是開源的,這表示任何人都可以為該專案做出貢獻。 + +您應該了解 Fabric 的四個主要組成部分: + +- **Fabric Loader**:一個靈活的、平台無關的模組載入器,專為 Minecraft 和其他遊戲和應用程式設計。 +- **Fabric Loom**:一個 Gradle 插件,使開發人員能夠輕鬆地開發和除錯模組。 +- **Fabric API**:一組供模組開發人員在建立模組時使用的 API 和工具。 +- **Yarn**:一組開放的 Minecraft 映射,任何人都可以在 Creative Commons Zero 授權條款下免費使用。 + +## 為什麼需要 Fabric 來修改 Minecraft? {#why-is-fabric-necessary-to-mod-minecraft} + +> 模組開發是指修改遊戲以改變其行為或添加新功能的過程。對於 Minecraft 來說,這涵蓋的範圍很廣,從加入新的物品、方塊或實體,到改變遊戲的機制或加入新的遊戲模式,都在其中。 + +Minecraft Java 版的程式碼被 Mojang 混淆,使得單獨修改變得困難。 然而,借助 Fabric 等模組開發工具,模組開發變得更加容易。 有幾個映射系統可以協助這個過程。 + +Loom 使用這些映射將混淆的程式碼重新映射為人類可讀的格式,使模組開發人員更容易理解和修改遊戲的程式碼。 Yarn 是一個流行且優秀的映射選擇,但也有其他的選擇。 每個映射專案可能有其自身的優勢或重點。 + +Loom 允許您輕鬆地針對重新映射的程式碼開發和編譯模組,而 Fabric Loader 允許您將這些模組載入到遊戲中。 + +## Fabric API 提供了什麼,為什麼需要它? {#what-does-fabric-api-provide-and-why-is-it-needed} + +> Fabric API 是一組供模組開發人員在建立模組時使用的 API 和工具。 + +Fabric API 提供了大量的 API,這些 API 建構在 Minecraft 現有功能的基礎上。例如,它為模組開發人員提供新的勾點和事件以供使用,或提供新的實用程式和工具以使模組開發更容易,例如可傳遞的存取擴展器 (Transitive Access Wideners) 以及存取內部登錄的能力,例如可堆肥物品登錄。 + +雖然 Fabric API 提供了強大的功能,但有些任務,例如基本的方塊登錄,可以使用原版 API 完成,而無需使用 Fabric API。 diff --git a/versions/1.21/translated/zh_tw/develop/getting-started/launching-the-game.md b/versions/1.21/translated/zh_tw/develop/getting-started/launching-the-game.md new file mode 100644 index 000000000..616a925f4 --- /dev/null +++ b/versions/1.21/translated/zh_tw/develop/getting-started/launching-the-game.md @@ -0,0 +1,72 @@ +--- +title: 啟動遊戲 +description: 了解如何利用各種啟動設定檔在即時遊戲環境中啟動和除錯您的模組。 +authors: + - IMB11 + - Tenneb22 +--- + +# 啟動遊戲 {#launching-the-game} + +Fabric Loom 提供了多種啟動配置檔案,以幫助你在實時遊戲環境中啟動模組和進行除錯。 本指南將介紹各種啟動配置檔案以及如何用它們來除錯和在遊戲中測試你的模組。 + +## 啟動配置檔案 {#launch-profiles} + +如果你使用的是 IntelliJ IDEA,你可以在視窗的右上角找到啟動配置檔案。 點擊下拉選單可以查看可用的啟動配置檔案。 + +應該有一個客戶端和伺服器端配置檔案,可以選擇正常執行或在除錯模式下執行它: + +![Launch Profiles](/assets/develop/getting-started/launch-profiles.png) + +## Gradle 任務 {#gradle-tasks} + +如果你使用的是命令行,則可以用以下 Gradle 指令啟動遊戲: + +- `./gradlew runClient` - 以客戶端啟動遊戲。 +- `./gradlew runServer` - 以伺服器端啟動遊戲。 + +這種方法的唯一問題是無法輕鬆為程式碼除錯。 如果想要進行程式碼除錯,你需要使用 IntelliJ IDEA 中的啟動配置檔案,或者通過你的 IDE 的 Gradle 集成來進行。 + +## 熱調換類別 {#hotswapping-classes} + +在除錯模式下運行遊戲時,可以熱調換你的類別而無需重啟遊戲。 這對於快速測試程式碼的更改很有用。 + +但你仍然會受到很大的限制: + +- 你無法新增或刪除函式 +- 你無法修改函式參數 +- 你無法添加或刪除字段 + +不過,透過使用 [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime) ,你可以避開大多數的限制,甚至可以增加或移除類別的函式。 這應該能夠讓大多數變更在不重新啟動遊戲的情況下生效。 + +不要忘記在你的 Minecraft 運行配置中的 VM Arguments 選項中新增以下內容: + +```:no-line-numbers +-XX:+AllowEnhancedClassRedefinition +``` + +## 熱調換 Mixins {#hotswapping-mixins} + +如果正在使用 Mixin,則可以熱調換 Mixin 類別而無須重啟遊戲。 這對於快速測試 Mixin 的更改很有用。 + +但是需要安裝 Mixin Java 代理才能正常用作。 + +### 1. 找到 Mixin 資料庫 Jar {#1-locate-the-mixin-library-jar} + +在 IntelliJ IDEA,你可以在 "Project" 部分的 "External Libraries" 部分找到 mixin 資料庫 jar: + +![Mixin Library](/assets/develop/getting-started/mixin-library.png) + +你需要複製 jar 的 "絕對路徑" 已供下一步使用。 + +### 2. 加入 `-javaagent` VM 參數 {#2-add-the--javaagent-vm-argument} + +在你的 "Minecraft Client" 和/或 "Minecraft Server" 啟動配置中,將以下內容加進 VM 參數選項: + +```:no-line-numbers +-javaagent:"此處為 mixin 資料庫 jar 的路徑" +``` + +![VM Arguments Screenshot](/assets/develop/getting-started/vm-arguments.png) + +現在,你應該能夠在除錯期間修改 mixin 函式的內容,並且無須重啟遊戲即可使修改生效。 diff --git a/versions/1.21/translated/zh_tw/develop/getting-started/project-structure.md b/versions/1.21/translated/zh_tw/develop/getting-started/project-structure.md new file mode 100644 index 000000000..26cf4dbcb --- /dev/null +++ b/versions/1.21/translated/zh_tw/develop/getting-started/project-structure.md @@ -0,0 +1,59 @@ +--- +title: 專案結構 +description: Fabric 模組專案結構概述 +authors: + - IMB11 +--- + +# 專案結構 {#project-structure} + +本頁將介紹 Fabric 模組專案的結構和專案中每個檔案和資料夾的用途。 + +## `fabric.mod.json` {#fabric-mod-json} + +`fabric.mod.json` 是向 Fabric Loader 描述你的模組的主要檔案。 這包含了模組的 ID、版本和前置等訊息。 + +`fabric.mod.json` 檔案中最重要的部分是: + +- `id`: 模組的ID,應該要是獨一無二的。 +- `name`: 模組的名稱。 +- `environment`: 模組運行環境,可以是 `client` ,可以是 `server`,或是 `*`。 +- `entrypoints`: 模組的進入點,例如 `main` 或 `client` 。 +- `depends`: 你的模組所需要的前置模組。 +- `mixins`: 模組提供的 Mixin。 + +下方是一個範例 `fabric.mod.json` 檔案 —— 這是此文檔網站的參考專案的 `fabric.mod.json` 檔案。 + +:::details 參考專案 `fabric.mod.json` +@[code lang=json](@/reference/1.21/src/main/resources/fabric.mod.json) +::: + +## Entrypoints {#entrypoints} + +如前所述,`fabric.mod.json` 檔案包含 —— 個名為 `entrypoints` 的欄位 - 這個欄位用來指定你的模組提供的進入點。 + +模板模組生成器預設會創建一個 `main` 和一個 `client` 進入點 —— `main` 進入點用於共用的程式碼,而 `client` 進入點則用於客戶端特定的程式碼。 這些進入點會在遊戲啟動時分別被調用。 + +@[code lang=java transcludeWith=#entrypoint](@/reference/1.21/src/main/java/com/example/docs/FabricDocsReference.java) + +上面是一個簡單的 `main` 進入點範例,在遊戲啟動時向控制台記錄一條訊息。 + +## `src/main/resources` {#src-main-resources} + +`src/main/resources` 資料夾用於儲存模組的資源檔案,例如材質、模型和音效。 + +它也是 `fabric.mod.json` 和模組使用的 Mixin 配置檔案存放的位置。 + +資源檔案儲存在與資源包結構相似的結構中-例如,方塊的材質會存放在 `assets/modid/textures/block/block.png` 中。 + +## `src/client/resources` {#src-client-resources} + +`src/client/resources` 資料夾用於儲存客戶端特定的資源檔案,例如僅在客戶端使用的材質、模型和音效。 + +## `src/main/java` {#src-main-java} + +`src/main/java` 資料夾用來存放模組的 Java 原始碼 —— 它存在於客戶端和伺服器端環境中。 + +## `src/client/java` {#src-client-java} + +`src/client/java` 資料夾用於存放特定於客戶端的 Java 原始碼 —— 例如渲染程式碼或客戶端邏輯,如方塊顏色提供程式。 diff --git a/versions/1.21/translated/zh_tw/develop/getting-started/setting-up-a-development-environment.md b/versions/1.21/translated/zh_tw/develop/getting-started/setting-up-a-development-environment.md new file mode 100644 index 000000000..c08ebd60e --- /dev/null +++ b/versions/1.21/translated/zh_tw/develop/getting-started/setting-up-a-development-environment.md @@ -0,0 +1,55 @@ +--- +title: 建置開發環境 +description: 關於建置 Fabric 開發環境的逐步指南。 +authors: + - IMB11 + - andrew6rant + - SolidBlock-cn + - modmuss50 + - daomephsta + - liach + - telepathicgrunt + - 2xsaiko + - natanfudge + - mkpoli + - falseresync + - asiekierka +authors-nogithub: + - siglong +--- + +# 建置開發環境 {#setting-up-a-development-environment} + +要開始用 Fabric 開發模組,需要使用 IntelliJ IDEA 建置開發環境。 + +## 安裝 JDK 21 {#installing-jdk-21} + +要開發 Minecraft 1.21 的模組,你需要 JDK 21。 + +如果你需要安裝 Java 的幫助,可以參考 [player guides section](../../players/index) 中的各種 Java 安裝指南。 + +## 安裝 IntelliJ IDEA {#installing-intellij-idea} + +:::info +你當然可以使用其他 IDE,如 Eclipse 或 Visual Studio Code,但本文檔站上的大多數頁面都假設你使用的是 IntelliJ IDEA。如果你使用其他 IDE,請參考該 IDE 的文檔。 +::: + +如果沒有安裝 IntelliJ IDEA,你可以從 [官網](https://www.jetbrains.com/idea/download/) 下載 - 按照你的作業系統的安裝步驟操作。 + +IntelliJ IDEA 的 Community 版本是免費且開源的,是使用 Fabric 開發模組的推薦版本。 + +你可能需要向下滑動才能找到 Community 版的下載連結 - 如下圖所示: + +![IDEA Community Edition Download Prompt](/assets/develop/getting-started/idea-community.png) + +## 安裝 IDEA 插件 {#installing-idea-plugins} + +雖然這些插件並不是必要的,但可以讓使用 Fabric 開發模組更加容易 - 你應該考慮安裝它們。 + +### Minecraft Development {#minecraft-development} + +Minecraft Development 插件提供對 Fabric 模組開發提供支援,是要安裝的最重要的插件。 + +你可以通過打開IntelliJ IDEA,然後前往 `File > Settings > Plugins > Marketplace Tab` - 在搜索欄中搜尋 `Minecraft Development`,然後點擊 `Install` 按鈕來安裝它。 + +或者你可以從 [plugin page](https://plugins.jetbrains.com/plugin/8327-minecraft-development) 下載它,然後點擊 `File > Settings > Plugins > Install Plugin From Disk` 來安裝。 diff --git a/versions/1.21/translated/zh_tw/index.md b/versions/1.21/translated/zh_tw/index.md new file mode 100644 index 000000000..c7e81cac9 --- /dev/null +++ b/versions/1.21/translated/zh_tw/index.md @@ -0,0 +1,21 @@ +--- +title: Fabric 文件 +description: Fabric 的官方精選文件,這是 Minecraft 的一個模組製作工具鏈。 +layout: home +hero: + name: Fabric 文件 + tagline: Fabric 的官方精選文件,這是 Minecraft 的一個模組製作工具鏈。 +features: + - title: 玩家指南 + icon: 📚 + details: 你是一位希望使用由 Fabric 驅動的模組的玩家嗎? 我們的玩家指南可以滿足你的需求。 這些指南將幫助你下載、安裝和疑難排解 Fabric 模組。 + link: /zh_tw/players/ + linkText: 閱讀更多 + - title: 開發人員指南 + icon: 🛠️ + details: 我們的社群編寫的開發人員指南涵蓋了從設定開發環境到繪製和網路等進階主題的所有內容。 + link: /zh_tw/develop/ + linkText: 開始使用 +--- + +如果你想為 Fabric 文件做出貢獻,你可以在 [GitHub](https://github.com/FabricMC/fabric-docs) 找到原始碼,以及相關的[貢獻指南](./contributing)。 diff --git a/versions/1.21/translated/zh_tw/navbar_translations.json b/versions/1.21/translated/zh_tw/navbar_translations.json new file mode 100644 index 000000000..7c6dde312 --- /dev/null +++ b/versions/1.21/translated/zh_tw/navbar_translations.json @@ -0,0 +1,8 @@ +{ + "title": "Fabric 文件", + "home": "主頁", + "download": "下載", + "contribute": "貢獻", + "contribute.api": "Fabric API", + "version_switcher": "切換版本" +} \ No newline at end of file diff --git a/versions/1.21/translated/zh_tw/players/faq.md b/versions/1.21/translated/zh_tw/players/faq.md new file mode 100644 index 000000000..c1d61c1f0 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/faq.md @@ -0,0 +1,29 @@ +--- +title: 玩家常見問題 +description: 關於 Fabric 的玩家和伺服器管理員常見問題解答手冊。 +--- + +# 常見問題 {#faq} + +有很多問題經常被詢問,所以我們在這裡整理了一個清單。 + +## Fabric 支援哪些 Minecraft 版本? {#what-minecraft-versions-does-fabric-support} + +官方支援的 Fabric 版本包括從 `18w43b` 開始的所有快照版本,以及 `1.14` 及以上的正式版本。 + +## 我在哪裡可以下載已發布的 Fabric 模組? {#where-can-i-download-published-fabric-mods} + +:::info +您應該始終檢查模組是否來自可信的來源。 參閱[尋找可信賴的模組](./finding-mods)指南以取得更多資訊。 +::: + +大部分作者會將他們的模組發布到 [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) 和 [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4),但有些人可能選擇將它們上傳到他們的個人網站,或其他平台,例如 GitHub 存儲庫。 + +## 我在哪裡可以找到預製的 Fabric 模組包? {#where-can-i-find-premade-fabric-modpacks} + +你可以在各種平台上找到預製的 Fabric 模組包,例如: + +- [Modrinth](https://modrinth.com/modpacks?g=categories:%27fabric%27) +- [CurseForge](https://www.curseforge.com/minecraft/search?class=modpacks\\&gameVersionTypeId=4) +- [Feed The Beast](https://www.feed-the-beast.com/ftb-app) +- [Technic](https://www.technicpack.net/modpacks) diff --git a/versions/1.21/translated/zh_tw/players/finding-mods.md b/versions/1.21/translated/zh_tw/players/finding-mods.md new file mode 100644 index 000000000..1d3a99af2 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/finding-mods.md @@ -0,0 +1,34 @@ +--- +title: 尋找可信賴的模組 +description: 本指南教你如何使用可信賴的來源找到 Fabric 模組。 +authors: + - IMB11 +--- + +# 尋找可信任的模組 {#finding-mods} + +首先,信任是主觀的,當下載模組時你應該始終根據自己的判斷。 但是,有一些方法可以幫助您找到可信任的模組。 + +## 1. 使用眾所周知的可信任來源 + +大部分作者會將他們的模組發布到 [Modrinth](https://modrinth.com/mods?g=categories:%27fabric%27) 和 [CurseForge](https://www.curseforge.com/minecraft/search?class=mc-mods\&gameVersionTypeId=4)。 + +這些網站會檢查模組是否符合其宣稱,並且不含有惡意程式碼。 你也可以在這些網站上回報惡意模組,他們會相對迅速地採取行動。 + +## 2. 與其他人確認! {#with-others} + +如果你從不被認為是可信任的來源下載模組,你應該與他人討論,看看他們是否曾經從你下載的位置下載過模組,以及他們是否遇到過任何問題。 + +如果你有疑問,歡迎在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 頻道中詢問。 + +## 3. 避免常見的惡意軟體網站! {#avoid-malware} + +:::info +惡意軟體網站對於每個人來說可能不是很明顯。 如果您不確定,你應該向他人尋求意見,或者完全避免該網站,僅依賴於可信任的來源,例如 Modrinth 和 CurseForge。 +::: + +有許多聲稱提供 Minecraft 模組的網站,實際上只是惡意軟體網站。 你應該盡量避免這些網站。 + +你可以使用防病毒軟體和像 [Windows Defender](https://www.microsoft.com/zh-tw/windows/comprehensive-security) 或 [VirusTotal](https://www.virustotal.com/) 這樣的網站來檢查下載的模組。 但是,不要完全依賴這些方法,因為有時候它們可能不準確。 + +同樣地,如果你有疑問,歡迎在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 頻道中尋求意見。 diff --git a/versions/1.21/translated/zh_tw/players/index.md b/versions/1.21/translated/zh_tw/players/index.md new file mode 100644 index 000000000..47819dbf5 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/index.md @@ -0,0 +1,12 @@ +--- +title: 玩家指南 +description: 一系列的指南,供玩家和伺服器管理員安裝和使用Fabric。 +--- + +# 玩家指南 + +這部分 Fabric 文件專門為想要學習如何安裝、使用和疑難排解 Fabric 的玩家和伺服器管理員而設。 + +你可以參考側邊欄中提供的所有指南清單。 + +如果你遇到任何問題,請在 [GitHub](https://github.com/FabricMC/fabric-docs) 上回報問題,或在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 或 `#server-admin-support` 頻道中尋求幫助。 diff --git a/versions/1.21/translated/zh_tw/players/installing-fabric.md b/versions/1.21/translated/zh_tw/players/installing-fabric.md new file mode 100644 index 000000000..778aeed83 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/installing-fabric.md @@ -0,0 +1,55 @@ +--- +title: 安裝 Fabric +description: 安裝 Fabric 的逐步指南。 +authors: + - IMB11 + - Benonardo + - modmuss50 +--- + +# 安裝 Fabric {#installing-fabric} + +這個指南將引導你在官方 Minecraft 啟動器上安裝 Fabric。 + +對於第三方啟動器,你應該參考它們的文件。 + +## 1. 下載 Fabric 安裝程式 {#1-download-the-fabric-installer} + +你可以從 [Fabric 官網](https://fabricmc.net/use/)下載 Fabric 安裝程式。 + +如果你使用 Windows 作業系統,請下載 `.exe` 版本(`Download For Windows`),因為它不需要在你的系統上安裝 Java。 它改為使用官方啟動器附帶的 Java。 + +對於 macOS 和 Linux 使用者,你應該下載 `.jar` 版本。 有時,在進行這個步驟之前,你需要安裝 Java。 + +## 2. 執行 Fabric 安裝程式 {#2-run-the-fabric-installer} + +:::warning +在安裝前,請先關閉 Minecraft 和 Minecraft 啟動器。 +::: + +:::details 對於 macOS 使用者的資訊 + +在 macOS 上,你可能需要在下載目錄中對 `.jar` 檔案按下右鍵,然後選擇 `打開` 才能執行它。 + +Fabric 安裝程式上的 macOS 右鍵選單 + +當詢問「你確定要打開它嗎?」時,請再次按下「打開」。 +::: + +開啟安裝程式後,你應該會看到以下視窗: + +![Fabric 安裝程式,「安裝」按鈕已醒目顯示](/assets/players/installing-fabric/installer-screen.png) + +要安裝 Fabric,只需從下拉式選單中選擇你的遊戲版本,然後點選 `安裝`。 + +**確保已勾選「建立設定檔」。** + +## 3. 你完成了! {#3-you-re-done} + +安裝程式完成後,你可以開啟 Minecraft 啟動器,並從左下方的下拉式選單中選擇 Fabric 設定檔,然後按下「開始遊戲」! + +![選擇 Fabric 設定檔的 Minecraft 啟動器](/assets/players/installing-fabric/launcher-screen.png) + +現在你已經安裝了 Fabric,你可以將模組新增到你的遊戲中! 參閱[尋找可信賴的模組](./finding-mods)指南以取得更多資訊。 + +如果你在依照本指南操作時遇到任何問題,你可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 頻道中尋求幫助。 diff --git a/versions/1.21/translated/zh_tw/players/installing-java/linux.md b/versions/1.21/translated/zh_tw/players/installing-java/linux.md new file mode 100644 index 000000000..dee73b627 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/installing-java/linux.md @@ -0,0 +1,91 @@ +--- +title: 在 Linux 上安裝 Java +description: 在 Linux 上安裝 Java 的逐步指南。 +authors: + - IMB11 +--- + +# 在 Linux 上安裝 Java + +本指南將引導你在 Linux 上安裝 Java 21。 + +## 1. 檢查 Java 是否已安裝 {#1-check-if-java-is-already-installed} + +開啟終端機,輸入 `java -version`,然後按下 Enter 鍵。 + +![終端機中輸入了「java -version」](/assets/players/installing-java/linux-java-version.png) + +:::warning +要使用 Minecraft 1.21,你至少需要安裝 Java 21。 如果這個指令顯示任何低於 21 的版本,則需要更新現有的 Java 安裝。 +::: + +## 2. 下載和安裝 Java 21 {#2-downloading-and-installing-java} + +我們建議使用 OpenJDK 21,它適用於大部分 Linux 發行版。 + +### Arch Linux + +:::info +有關在 Arch Linux 上安裝 Java 的更多資訊,請參閱 [Arch Linux Wiki](https://wiki.archlinuxcn.org/wiki/Java)。 +::: + +你可以從官方儲存庫安裝最新的 JRE: + +```sh +sudo pacman -S jre-openjdk +``` + +如果你在沒有圖形化介面的伺服器上執行,則可以安裝無頭版本: + +```sh +sudo pacman -S jre-openjdk-headless +``` + +如果你打算開發模組,則需要 JDK: + +```sh +sudo pacman -S jdk-openjdk +``` + +### Debian/Ubuntu + +你可以使用 `apt` 執行以下指令來安裝 Java 21: + +```sh +sudo apt update +sudo apt install openjdk-21-jdk +``` + +### Fedora + +你可以使用 `dnf` 執行以下指令來安裝 Java 21: + +```sh +sudo dnf install java-21-openjdk +``` + +如果你不需要圖形化介面,則可以安裝無頭版本: + +```sh +sudo dnf install java-21-openjdk-headless +``` + +如果你打算開發模組,則需要 JDK: + +```sh +sudo dnf install java-21-openjdk-devel +``` + +### 其他 Linux 發行版 {#other-linux-distributions} + +如果你的發行版未在上述清單中,你可以從 [Eclipse Temurin](https://adoptium.net/temurin/) 下載最新的 JRE。 + +如果你打算開發模組,你應參考另一個指南。 + +## 3. 驗證 Java 21 是否已安裝 {#3-verify-that-java-is-installed} + +安裝完成後,你可以透過開啟終端機並輸入 `java -version` 來驗證 Java 21 是否已安裝。 + +如果這個命令成功執行,你將看到類似於以前顯示的內容,其中顯示了 Java 版本: + +![終端機中輸入了「java -version」](/assets/players/installing-java/linux-java-version.png) diff --git a/versions/1.21/translated/zh_tw/players/installing-java/windows.md b/versions/1.21/translated/zh_tw/players/installing-java/windows.md new file mode 100644 index 000000000..006e281f2 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/installing-java/windows.md @@ -0,0 +1,65 @@ +--- +title: 在 Windows 上安裝 Java +description: 在 Windows 上安裝 Java 的逐步指南。 +authors: + - IMB11 +--- + +# 在 Windows 上安裝 Java {#installing-java-on-windows} + +這個指南將引導你在 Windows 上安裝 Java 21。 + +Minecraft 啟動器附帶了自己的 Java 安裝,因此這部分只在你想使用 Fabric 的 `.jar` 安裝程式,或者你想使用 Minecraft 伺服器的 `.jar` 時相關。 + +## 1. 檢查 Java 是否已安裝 {#1-check-if-java-is-already-installed} + +要檢查 Java 是否已安裝,你首先必須開啟命令提示字元。 + +你可以透過按下 Win + R 並在出現的對話方塊中輸入 `cmd.exe` 來執行這項操作。 + +![Windows執行對話方塊中的「cmd.exe」](/assets/players/installing-java/windows-run-dialog.png) + +開啟命令提示字元後,輸入 `java -version` 並按下 Enter 鍵。 + +如果命令成功執行,你會看到類似這樣的內容。 如果命令失敗,請繼續進行下一步。 + +![命令提示字元中輸入了「java -version」](/assets/players/installing-java/windows-java-version.png) + +:::warning +要使用 Minecraft 1.21,你至少需要安裝 Java 21。 如果這個指令顯示任何低於 21 的版本,則需要更新現有的 Java 安裝。 +::: + +## 2. 下載Java 21安裝程式 {#2-download-the-java-installer} + +要安裝Java 21,你需要從 [Adoptium](https://adoptium.net/en-GB/temurin/releases/?os=windows\&package=jdk\&version=21) 下載安裝程式。 + +你需要下載 `Windows Installer (.msi)` 版本: + +![Adoptium 下載頁面,突顯了 Windows 安裝程式 (.msi)](/assets/players/installing-java/windows-download-java.png) + +如果你有 32 位元作業系統,應該選擇 `x86`;如果你有 64 位元作業系統,則應該選擇 `x64`。 + +現代大多數電腦都執行 64 位元作業系統。 如果你不確定,請嘗試使用 64 位元的下載。 如果你不確定,請嘗試使用 64 位元的下載。 要檢查 Java 是否已安裝,你首先必須開啟命令提示字元。 + +## 3. 執行安裝程式! {#3-run-the-installer} + +依照安裝程式中的步驟安裝Java 21。 當你到達這個頁面時,你應該將以下功能設為「整個功能將安裝在本機硬碟上」: + +- `設定 JAVA_HOME 變數` - 這將加入到你的 PATH 中。 +- `JavaSoft (Oracle) 登錄機碼` + +![Java 21 安裝程式,其中「設定 JAVA\_HOME 變數」和「JavaSoft (Oracle) 登錄機碼」已醒目提示](/assets/players/installing-java/windows-wizard-screenshot.png) + +完成後,你可以按 `下一步` 繼續安裝。 + +## 4. 驗證 Java 21 是否已安裝 {#4-verify-that-java-is-installed} + +安裝完成後,你可以再次開啟命令提示字元,並輸入 `java -version` 來驗證 Java 21 是否已安裝。 + +如果這個命令成功執行,你將看到類似於以前顯示的內容,其中顯示了 Java 版本: + +![命令提示字元中輸入了「java -version」](/assets/players/installing-java/windows-java-version.png) + +--- + +如果遇到任何問題,你可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 頻道中尋求幫助。 diff --git a/versions/1.21/translated/zh_tw/players/installing-mods.md b/versions/1.21/translated/zh_tw/players/installing-mods.md new file mode 100644 index 000000000..1f9ec3782 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/installing-mods.md @@ -0,0 +1,67 @@ +--- +title: 安裝模組 +description: Fabric 模組安裝的逐步指南 +authors: + - IMB11 +--- + +# 安裝模組 {#installing-mods} + +這個指南將引導你使用 Minecraft 啟動器安裝 Fabric 模組。 + +對於第三方啟動器,您應該查閱他們的文件。 + +## 1. 下載模組 {#1-download-the-mod} + +:::warning +你應該只從你信任的來源下載模組。 如需更多關於尋找模組的資訊,請參閱[尋找模組](./finding-mods.md)指南。 +::: + +大部分的模組都需要 Fabric API,它可以從 [Modrinth](https://modrinth.com/mod/fabric-api) 或 [CurseForge](https://curseforge.com/minecraft/mc-mods/fabric-api)下載。 + +下載模組時,請確保: + +- 它們能在你想玩的 Minecraft 版本上執行。 例如,一個在 1.20 上執行的模組可能無法在 1.20.2 上執行。 +- 它是為 Fabric 製作,而不是其他模組載入器。 +- 此外,它們適用於正確的 Minecraft 版本(Java 版)。 + +## 2. 將模組移動到 `mods` 資料夾 {#2-move-the-mod-to-the-mods-folder} + +各個作業系統中,模組資料夾的位置如下所示: + +您可以將這些路徑貼上到檔案總管的路徑列中,以便快速導航到該資料夾。 + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\mods +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/mods +``` + +```:no-line-numbers [Linux] +~/.minecraft/mods +``` + +::: + +找到 `mods` 資料夾後,您可以將模組 `.jar` 檔案移動到其中。 + +![mods 資料夾中已安裝的模組](/assets/players/installing-mods.png) + +## 3. 你完成了! {#3-you-re-done} + +將模組移動到 `mods` 資料夾後,您可以開啟 Minecraft 啟動器,並從左下方的下拉式選單中選擇 Fabric 設定檔,然後按下開始遊戲! + +![已選擇 Fabric 設定檔的 Minecraft 啟動器](/assets/players/installing-fabric/launcher-screen.png) + +## 疑難排解 {#troubleshooting} + +如果你在依照本指南操作時遇到任何問題,你可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 頻道中尋求幫助。 + +您也可以嘗試透過閱讀疑難排解頁面自行解決問題: + +- [崩潰報告](./troubleshooting/crash-reports) +- [上傳記錄檔](./troubleshooting/uploading-logs) diff --git a/versions/1.21/translated/zh_tw/players/troubleshooting/crash-reports.md b/versions/1.21/translated/zh_tw/players/troubleshooting/crash-reports.md new file mode 100644 index 000000000..f939fb1fb --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/troubleshooting/crash-reports.md @@ -0,0 +1,105 @@ +--- +title: 崩潰報告 +description: 了解如何處理崩潰報告,以及如何閱讀它們。 +authors: + - IMB11 +--- + +# 處理崩潰報告 + +:::tip +如果你在尋找崩潰原因時遇到任何困難,你可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 或 `#server-admin-support` 頻道中尋求幫助。 +::: + +崩潰報告是排解遊戲或伺服器問題的非常重要的一部分。 它們包含了關於崩潰的大量資訊,可以幫助你找到崩潰的原因。 + +## 尋找崩潰報告 {#finding-crash-reports} + +崩潰報告儲存在遊戲目錄中的 crash-reports 資料夾中。 如果您正在使用伺服器,則它們儲存在伺服器目錄中的 `crash-reports` 資料夾中。 如果您正在使用伺服器,則它們儲存在伺服器目錄中的 `crash-reports` 資料夾中。 如果您正在使用伺服器,則它們儲存在伺服器目錄中的 `crash-reports` 資料夾中。 如果您正在使用伺服器,則它們儲存在伺服器目錄中的 `crash-reports` 資料夾中。 + +對於第三方啟動器,你應參考它們的文件以找到崩潰報告的位置。 + +崩潰報告可以在以下位置找到: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft\crash-reports +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft/crash-reports +``` + +```:no-line-numbers [Linux] +~/.minecraft/crash-reports +``` + +::: + +## 閱讀崩潰報告 + +崩潰報告非常長,且讀起來可能會很困難。 然而,它們包含了許多關於崩潰的資訊,可以幫助你找出崩潰的原因。 + +在本指南中,我們將使用[這個崩潰報告作為範例](https://github.com/FabricMC/fabric-docs/blob/main/public/assets/players/crash-report-example.txt)。 + +:::details 崩潰報告 + +崩潰報告是排解遊戲或伺服器問題的非常重要的一部分。 它們包含了關於崩潰的大量資訊,可以幫助你找到崩潰的原因。 + +::: + +### 崩潰報告部分 + +崩潰報告由幾個部分組成,每個部分都使用標題分隔: + +- `---- Minecraft Crash Report ----`,報告的摘要。 這個部分包含導致崩潰的主要錯誤、發生時間以及相關的堆疊追蹤。 這是崩潰報告中最重要的部分,因為堆疊追蹤通常包含導致崩潰的模組的參考。 這個部分包含導致崩潰的主要錯誤、發生時間以及相關的堆疊追蹤。 這是崩潰報告中最重要的部分,因為堆疊追蹤通常包含導致崩潰的模組的參考。 這個部分包含導致崩潰的主要錯誤、發生時間以及相關的堆疊追蹤。 這是崩潰報告中最重要的部分,因為堆疊追蹤通常包含導致崩潰的模組的參考。 這個部分包含導致崩潰的主要錯誤、發生時間以及相關的堆疊追蹤。 這是崩潰報告中最重要的部分,因為堆疊追蹤通常包含導致崩潰的模組的參考。 +- `-- Last Reload --`,這個部分除非崩潰發生在資源重新載入期間(F3 T),否則沒有什麼用。 這個部分將包含上次重新載入的時間以及重新載入過程中發生的任何錯誤的相關堆疊追踪。 這些錯誤通常是由資源包引起的,除非它們對遊戲造成問題,否則可以忽略。 +- `-- System Details --`,這個部分包含有關你系統的資訊,例如作業系統、Java 版本和配置給遊戲的記憶體。 這個部分對於確定你是否使用正確的 Java 版本以及是否為遊戲配置足夠的記憶體很有用。 這個部分對於確定你是否使用正確的 Java 版本以及是否為遊戲配置足夠的記憶體很有用。 這個部分對於確定你是否使用正確的 Java 版本以及是否為遊戲配置足夠的記憶體很有用。 這個部分對於確定你是否使用正確的 Java 版本以及是否為遊戲配置足夠的記憶體很有用。 + - 在這一部分,Fabric 將包括一個自訂行,其中說明了 `Fabric Mods:`,後面跟著您安裝的所有模組的清單。 這個部分對於確定模組之間是否可能發生衝突很有用。 + +### 分解崩潰報告 + +現在我們知道崩潰報告的每個部分是什麼,我們可以開始分解崩潰報告,找出崩潰的原因。 + +使用上面連結的範例,我們可以分析崩潰報告,找出崩潰的原因,包括導致崩潰的模組。 + +崩潰報告是排解遊戲或伺服器問題的非常重要的一部分。 它們包含了關於崩潰的大量資訊,可以幫助你找到崩潰的原因。 `---- Minecraft Crash Report ----` 部分中的堆棧跟踪在這種情況下最重要,因為它包含導致崩潰的主要錯誤。 在這個案例中,錯誤是 `java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2248.method_9539()" because "net.minecraft.class_2248.field_10540" is null`。 在這個案例中,錯誤是 `java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2248.method_9539()" because "net.minecraft.class_2248.field_10540" is null`。 在這個案例中,錯誤是 `java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2248.method_9539()" because "net.minecraft.class_2248.field_10540" is null`。 + +由於堆疊追蹤中提到了大量的模組,要指出責任者可能有些困難,但首先要做的是尋找導致崩潰的模組。 + + + +<<< @/public/assets/players/crash-report-example.txt{8-9,14-15 log} + +在這種情況下,導致崩潰的模組是 `snownee`,因為它是堆疊追蹤中首先提到的模組。 + +然而,由於堆疊追蹤中提到了大量的模組,這可能表示模組之間存在一些相容性問題,並且導致崩潰的模組可能不是真正的問題所在。 在這種情況下,最好將崩潰報告提交給模組作者,並讓他們調查崩潰。 + +## Mixin 崩潰 + +:::info +Mixin 是一種讓模組無需修改遊戲原始碼即可修改遊戲的方法。 它們被許多模組使用,是模組開發人員非常強大的工具。 它們被許多模組使用,是模組開發人員非常強大的工具。 它們被許多模組使用,是模組開發人員非常強大的工具。 它們被許多模組使用,是模組開發人員非常強大的工具。 +::: + +當 mixin 崩潰時,堆疊追蹤通常會提到 mixin 和被修改的類。 + +方法 mixin 將在堆疊追蹤中包含 `modid$handlerName`,其中 `modid` 是模組的 ID,`handlerName` 是 mixin 處理程序的名稱。 + +```:no-line-numbers +... net.minecraft.class_2248.method_3821$$$modid$handlerName() ... // [!code focus] +``` + +你可以使用這個資訊找到導致崩潰的模組,並將崩潰報告提交給模組作者。 + +## 如何處理崩潰報告 {#what-to-do-with-crash-reports} + +處理崩潰報告的最佳方法是將它上傳至文字分享網站,並將連結分享給模組作者、錯誤追蹤器或透過某種形式的交流(Discord 等)。 + +這將使模組作者能夠調查崩潰,可能重現它並解決導致崩潰的問題。 + +常見的文字分享網站為: + +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) +- [Pastebin](https://pastebin.com/) diff --git a/versions/1.21/translated/zh_tw/players/troubleshooting/uploading-logs.md b/versions/1.21/translated/zh_tw/players/troubleshooting/uploading-logs.md new file mode 100644 index 000000000..278550e08 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/troubleshooting/uploading-logs.md @@ -0,0 +1,54 @@ +--- +title: 上傳記錄檔 +description: 如何上傳記錄檔以進行疑難排解。 +authors: + - IMB11 +--- + +# 上傳記錄檔 {#uploading-logs} + +在進行疑難排解時,通常需要提供記錄檔以幫助尋找問題的原因。 + +## 為什麼我應該上傳記錄檔? {#why-should-i-upload-logs} + +上傳記錄檔而不是只在論壇貼文中貼上記錄檔,讓其他人更快地解決你的問題。 它還允許你與他人分享你的記錄檔,而無需複製和貼上它們。 + +某些文字分享網站還會對記錄檔進行語法突顯,使其更易於閱讀,並且可能會對敏感資訊(例如你的使用者名稱或系統資訊)進行審查。 + +## 崩潰報告 + +當遊戲崩潰時,會自動產生崩潰報告。 它們只包含崩潰資訊,而不包含遊戲的實際記錄檔。 它們位於遊戲目錄中的 `crash-reports` 資料夾中。 它們只包含崩潰資訊,而不包含遊戲的實際記錄檔。 它們位於遊戲目錄中的 `crash-reports` 資料夾中。 + +有關崩潰報告的更多資訊,請參閱[崩潰報告](./crash-reports)。 + +## 尋找記錄檔 {#locating-logs} + +本指南涵蓋了官方 Minecraft 啟動器(通常稱為「原版啟動器」),對於第三方啟動器,你應該參閱其文件。 + +記錄檔位於遊戲目錄中的 logs 資料夾中,遊戲目錄可以在以下位置找到,具體取決於你的作業系統: + +::: code-group + +```:no-line-numbers [Windows] +%appdata%\.minecraft +``` + +```:no-line-numbers [macOS] +~/Library/Application Support/minecraft +``` + +```:no-line-numbers [Linux] +~/.minecraft +``` + +::: + +最新的記錄檔名為 `latest.log`,以及先前的記錄檔使用命名模式 `yyyy-mm-dd_number.log.gz`。 + +## 將記錄檔上傳至線上服務 {#uploading-logs-online} + +記錄檔可以上傳到各種服務,例如: + +- [Pastebin](https://pastebin.com/) +- [GitHub Gist](https://gist.github.com/) +- [mclo.gs](https://mclo.gs/) diff --git a/versions/1.21/translated/zh_tw/players/updating-fabric.md b/versions/1.21/translated/zh_tw/players/updating-fabric.md new file mode 100644 index 000000000..5b795e399 --- /dev/null +++ b/versions/1.21/translated/zh_tw/players/updating-fabric.md @@ -0,0 +1,43 @@ +--- +title: 更新 Fabric +description: 有關如何更新 Fabric 的逐步指南。 +authors: + - IMB11 + - modmuss50 +--- + +# 更新 Fabric {#updating-fabric} + +這個指南將引導你在 Minecraft 啟動器上更新 Fabric。 + +對於第三方啟動器,您應該查閱其說明文件。 + +更新 Fabric 的過程與安裝 Fabric 非常相似,因此本指南的某些部分將與[安裝 Fabric](./installing-fabric) 指南相同。 + +## 為什麼我應該更新 Fabric 載入器? {#why-should-i-update-fabric-loader} + +較新的模組可能需要較新版本的 Fabric 載入器才能運作,因此保持最新狀態以確保您可以使用最新的模組非常重要。 + + + + + +要更新 Fabric,只需確保遊戲版本和載入器版本正確,然後按一下 `安裝`。 + +:::important +執行安裝程式時,請務必取消勾選「建立設定檔」,否則它將建立新的設定檔,在這種情況下我們不需要。 +::: + +## 3. 在 Minecraft 啟動器中開啟設定檔 {#3-open-the-profile-in-the-minecraft-launcher} + +安裝程式完成後,您可以開啟 Minecraft 啟動器並前往 `安裝檔` 頁籤。 您應該前往您的 Fabric 設定檔並開啟編輯畫面。 + +將版本替換為您剛才安裝的新版 Fabric 載入器,然後按下 `儲存`。 + +![在 Minecraft 啟動器中更新 Fabric 載入器版本](/assets/players/updating-fabric.png) + +## 4. 你完成了! {#4-you-re-done} + +完成這些步驟後,您可以返回 `開始遊戲` 頁籤,從左下方的下拉式選單中選擇 Fabric 設定檔,然後按下「開始遊戲」! + +如果您在遵循本指南時遇到任何問題,您可以在 [Fabric Discord](https://discord.gg/v6v4pMv) 的 `#player-support` 頻道中尋求幫助。 diff --git a/versions/1.21/translated/zh_tw/sidebar_translations.json b/versions/1.21/translated/zh_tw/sidebar_translations.json new file mode 100644 index 000000000..739a3d798 --- /dev/null +++ b/versions/1.21/translated/zh_tw/sidebar_translations.json @@ -0,0 +1,60 @@ +{ + "players.title": "玩家指南", + "players.faq": "常見問題", + "players.installingJava": "安裝 Java", + "players.installingJava.windows": "Windows", + "players.installingJava.macOS": "macOS", + "players.installingJava.linux": "Linux", + "players.installingFabric": "安裝 Fabric", + "players.findingMods": "尋找可信賴的模組", + "players.installingMods": "安裝模組", + "players.troubleshooting": "疑難排解", + "players.troubleshooting.uploadingLogs": "上傳你的記錄檔", + "players.troubleshooting.crashReports": "崩潰報告", + "players.updatingFabric": "更新 Fabric", + "develop.title": "開發人員指南", + "develop.gettingStarted": "開始使用", + "develop.gettingStarted.introduction": "Fabric 和模組簡介", + "develop.gettingStarted.devEnvSetup": "設定開發環境", + "develop.gettingStarted.creatingProject": "建立一個專案", + "develop.gettingStarted.projectStructure": "專案結構", + "develop.gettingStarted.launchGame": "啟動你的遊戲", + "develop.gettingStarted.solvingProblems": "基本問題解決", + "develop.items": "物品", + "develop.items.first-item": "建立你的第一個物品", + "develop.items.food": "食物物品", + "develop.items.custom-armor": "自訂盔甲", + "develop.items.custom-tools": "自訂工具", + "develop.items.custom-item-groups": "自訂物品組", + "develop.items.custom-item-interactions": "自訂物品互動", + "develop.items.potions": "藥水", + "develop.items.custom-data-components": "自訂資料元件", + "develop.blocks": "方塊", + "develop.blocks.first-block": "建立你的第一個方塊", + "develop.blocks.blockstates": "方塊狀態", + "develop.entities": "實體", + "develop.entities.effects": "狀態效果", + "develop.entities.damage-types": "傷害類型", + "develop.commands": "指令", + "develop.commands.basics": "建立指令", + "develop.commands.arguments": "指令引數", + "develop.commands.suggestions": "指令建議", + "develop.rendering": "繪製", + "develop.rendering.basicConcepts": "基礎的繪製概念", + "develop.rendering.drawContext": "使用繪圖上下文", + "develop.rendering.hud": "在 HUD 中繪製", + "develop.rendering.gui": "圖形使用者介面和畫面", + "develop.rendering.gui.customScreens": "自訂畫面", + "develop.rendering.gui.customWidgets": "自訂小工具", + "develop.rendering.particles": "粒子", + "develop.rendering.particles.creatingParticles": "建立自訂粒子", + "develop.misc": "雜項頁面", + "develop.misc.codecs": "解編碼器", + "develop.misc.events": "事件", + "develop.misc.text-and-translations": "文字和翻譯", + "develop.misc.ideTipsAndTricks": "IDE 使用技巧", + "develop.misc.automatic-testing": "自動化測試", + "develop.sounds": "音效", + "develop.sounds.using-sounds": "播放音效", + "develop.sounds.custom": "建立自訂音效" +} diff --git a/versions/1.21/translated/zh_tw/website_translations.json b/versions/1.21/translated/zh_tw/website_translations.json new file mode 100644 index 000000000..74a73da41 --- /dev/null +++ b/versions/1.21/translated/zh_tw/website_translations.json @@ -0,0 +1,48 @@ +{ + "authors.heading": "本頁作者", + "authors.nogithub": "%s(不在 GitHub)", + "banner": "Fabric 文件仍在持續更新中。如有任何問題,請在 %s 或 %s 上回報。", + "description": "Minecraft 的模組製作工具鏈 Fabric 的全面文件。", + "download": "下載 %s", + "footer.next": "下一頁", + "footer.prev": "上一頁", + "github_edit": "在 GitHub 上編輯這個頁面", + "lang_switcher": "變更語言", + "last_updated": "上次更新時間", + "mode_dark": "切換至深色主題", + "mode_light": "切換至淺色主題", + "mode_switcher": "外觀", + "nav.contribute": "貢獻", + "nav.contribute.api": "Fabric API", + "nav.download": "下載", + "nav.home": "首頁", + "outline": "本頁內容", + "return_to_top": "返回頂部", + "search.back": "關閉搜尋", + "search.button": "搜尋", + "search.display_details": "顯示詳細清單", + "search.footer.close": "關閉", + "search.footer.close.key": "Esc", + "search.footer.down.key": "↓ 鍵", + "search.footer.navigate": "導覽", + "search.footer.up.key": "↑ 鍵", + "search.footer.select": "選取", + "search.footer.select.key": "Enter", + "search.no_results": "找不到", + "search.reset": "重設搜尋", + "sidebar_menu": "選單", + "social.discord": "Discord", + "social.github": "GitHub", + "title": "Fabric 文件", + "version.reminder": "這個頁面適用於以下版本:", + "version.switcher": "切換版本", + "404.code": "404", + "404.crowdin_link": "在 Crowdin 上翻譯", + "404.crowdin_link.label": "開啟 Crowdin 編輯器", + "404.english_link": "閱讀英文版", + "404.english_link.label": "開啟英文版", + "404.link": "返回首頁", + "404.link.label": "前往首頁", + "404.quote": "這個頁面試圖在熔岩裡游泳", + "404.title": "找不到頁面" +}