GithubHelp home page GithubHelp logo

fabricmc / fabric Goto Github PK

View Code? Open in Web Editor NEW
2.1K 39.0 381.0 9.26 MB

Essential hooks for modding with Fabric.

License: Apache License 2.0

Java 99.98% mcfunction 0.01% GLSL 0.02%
fabric java minecraft hacktoberfest

fabric's Introduction

Fabric API

Essential hooks for modding with Fabric.

Fabric API is the library for essential hooks and interoperability mechanisms for Fabric mods. Examples include:

  • Exposing functionality that is useful but difficult to access for many mods such as particles, biomes and dimensions
  • Adding events, hooks and APIs to improve interopability between mods.
  • Essential features such as registry synchronization and adding information to crash reports.
  • An advanced rendering API designed for compatibility with optimization mods and graphics overhaul mods.

Also check out Fabric Loader, the (mostly) version-independent mod loader that powers Fabric. Fabric API is a mod like any other Fabric mod which requires Fabric Loader to be installed.

For support and discussion for both developers and users, visit the Fabric Discord server.

Using Fabric API to play with mods

Make sure you have installed fabric loader first. More information about installing Fabric Loader can be found here.

To use Fabric API, download it from CurseForge, GitHub Releases or Modrinth.

The downloaded jar file should be placed in your mods folder.

Using Fabric API to develop mods

To set up a Fabric development environment, check out the Fabric example mod and follow the instructions there. The example mod already depends on Fabric API.

To include the full Fabric API with all modules in the development environment, add the following to your dependencies block in the gradle buildscript:

Groovy DSL

modImplementation "net.fabricmc.fabric-api:fabric-api:FABRIC_API_VERSION"

Kotlin DSL

modImplementation("net.fabricmc.fabric-api:fabric-api:FABRIC_API_VERSION")

Alternatively, modules from Fabric API can be specified individually as shown below (including module jar to your mod jar):

Groovy DSL

// Make a collection of all api modules we wish to use
Set<String> apiModules = [
    "fabric-api-base",
    "fabric-command-api-v1",
    "fabric-lifecycle-events-v1",
    "fabric-networking-api-v1"
]

// Add each module as a dependency
apiModules.forEach {
    include(modImplementation(fabricApi.module(it, FABRIC_API_VERSION)))
}

Kotlin DSL

// Make a set of all api modules we wish to use
setOf(
    "fabric-api-base",
    "fabric-command-api-v1",
    "fabric-lifecycle-events-v1",
    "fabric-networking-api-v1"
).forEach {
    // Add each module as a dependency
    modImplementation(fabricApi.module(it, FABRIC_API_VERSION))
}

Instead of hardcoding version constants all over the build script, Gradle properties may be used to replace these constants. Properties are defined in the gradle.properties file at the root of a project. More information is available here.

Contributing

See something Fabric API doesn't support, a bug or something that may be useful? We welcome contributions to improve Fabric API. Make sure to read the development guidelines.

Modules

Fabric API is designed to be modular for ease of updating. This also has the advantage of splitting up the codebase into smaller chunks.

Each module contains its own README.md* explaining the module's purpose and additional info on using the module.

* The README for each module is being worked on; not every module has a README at the moment

fabric's People

Contributors

alphamode avatar apple502j avatar asiekierka avatar cheatercodes avatar deirn avatar dexman545 avatar draylar avatar errorcraft avatar frqnny avatar grondag avatar haykam821 avatar i509vcb avatar juuxel avatar kevinthegreat1 avatar lambdaurora avatar liach avatar madis0 avatar maityyy avatar modmuss50 avatar peppercode1 avatar qouteall avatar sfplayer1 avatar shartte avatar shedaniel avatar shnupbups avatar squiddev avatar syst3ms avatar technici4n avatar telepathicgrunt avatar triphora avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fabric's Issues

Container issues

So it seems that if you attempt to open a Container (Menu) that is registered to Fabrics registry instead of directly to the vanilla one, it will open the player's Container (Menu) on the server; resulting in various issues such as the clicking on a slot with an id of greater than 44 causing an OOD Exception on the slotList of the Container (Menu), slots 1-8 (hotbar) not being interactable, and other things that result from such desyncs.

EntityPickInteractionAware is not respected in most cases

If you inspect MinecraftClient#doItemPick closely, you will see that the path for HitResult.Type.ENTITY returns early if the entity does not match any of the hardcoded types or has no spawn egg, so EntityPickInteractionAware is not respected.

Adding fuel times to items

Vanilla hardcodes fuel times in AbstractFurnaceBlockEntity.getBurnTimeMap. Fabric could have a hook to add custom fuel times.

There's also some room for optimization since the map is generated on each call to getBurnTimeMap.

I'm probably going to work on a PR for this.

Event wishlist

please provided as much info as you possibly can,
like the classes to look at for mixins, which arguments are important
and link to a separate issue if it gets too much

  • chat event | String message, ServerPlayerEntity player | #26
  • death event | DamageSource damageSource, ServerPlayerEntity player, String deathMessage
  • connect event | player
  • disconnect event | player, disconnectReason
  • achievement/progress event
  • dimension change event | ServerPlayerEntity player, fromDimension, toDimension

very rough list of things i (might) require for future features

Redo pick block events

OF COURSE WE MESSED THEM UP

  1. ClientPickGatherCallback -> bails on first ItemStack found; used before the real doItemPick is called to check if we have a Fabric-provided stack
  2. ClientPickApplyCallback -> allows you to modify the ItemStack, as well as disable the default behaviour of adding the BlockEntityTag on CTRL+creative if you wish to do so; but is only called if any were found
  3. Deprecate ClientPickBlockCallback, remove in 0.3.0, pretend it "works"

[Suggestion] Wrapper for Material.Builder

net.minecraft.block.Material.Builder hides some of its methods using private (setFlag5) and protected (setFlag3, burnable, destroyedByPiston, blocksPistons), so a wrapper would help when making a custom material.

Attempting to register sprites using SpriteEvent causes NPEs

log of crash here

I'm trying to register sprites using the SpriteEvent, but it causes an NPE crash. Still occurs when putting a break point on SpriteAtlasTexture.reload and on SpriteAtlasTexture.build. Interesting to note: the traceback references at net.minecraft.client.texture.SpriteAtlasTexture.handler$reload$zbn000(SpriteAtlasTexture.java:589), but SpriteAtlasTexture.java only has 268 lines.

Minecraft: 18w50a
Mappings: yarn 18w50a.27
Loader: fabric-loader 0.2.0.64
API: fabric 0.1.1.55

Code being used:

public class InfraRedstoneClient implements ClientModInitializer {
	private SpriteProvider provider;

	@Override
	public void onInitializeClient() {
		SpriteEvent.PROVIDE.register(provider);
		BlockEntityRendererRegistry.INSTANCE.register(DiodeBlockEntity.class, new DiodeRender());
	}
}
class SpriteProvider implements SpriteEvent.Provider {
	@Override
	public void registerSprites(SpriteRegistry registry) {
		registry.register(new Identifier("infraredstone:block/diode_glow"));
	}
}

Hooks/events for hiding (parts of) the ingame HUD

I.e. allow selectively skipping bits of InGameHud.draw, such as quickbar, boss health bar, player health/air/hunger, etc.

My usecase is wanting to hide most of that stuff while a specific GUI is open (which I currently solve by mixing in a simple early exit, but I can easily imagine cases where more control is desired, e.g. for HUD manipulating mods).

Some question

Hey I'm new so I have some questions for this new modloader/api:
Is it the modding api that we all have been waiting for?
When forge catches up, will it still be updated?
Does it want to replace forge or just be an alternative?
Are there any tutorials how to do the basic stuff like blocks? I want to recreate my current mod for fabric.
How easy is it to upgrade my mod when changing Minecraft version? Do thinks break all the time or is it more like spigot that works across multiple versions?

Thanks.

Custom Dimensions

Custom Dimensions

After messing around with dims for the last day or so I have found a few places that might be a good candidate to be handled by fabric.

TL;DR at bottom of this issue

Creation of the SecondaryServerWorld

In MinecraftServer.createWorlds, SecondaryServerWorld's are created for the end and the neather. As well as adding them to the MinecraftServer.worlds map. This would be an easy thing to patch. An API would need to be created to allow modders to register their DimensionType's to be created

Creating a new DimensionType

Currently DimensionType has a protected constructor, I think the best solution to this is to create a builder (similar to the item groups) This builder would take an identifier and handle some things the modder shouldn't need to touch such as the saveDir

One possible idea would be to remove the need to speicfy a unique dim id, this needs to be looked into some more as the dim id's would need to be synced from the server to the client on connection. The id's seem to be used in very few places so I think this could be feasible without too much work.

ChunkGeneratorType

ChunkGeneratorType is used by the Dimension to create generate chunks, easy enough. ChunkGeneratorType.register could do with an AT, this is the least of the issues however.

ChunkGeneratorFactory is package private, this makes creating ChunkGeneratorType's a pain, to work around this I moved this code into the net.minecraft.world.gen.chunk package, however this is bad on a few levels, and will not work outside of dev. This class should be AT'ed to be public.

Entity Teleportation and Portal Creation (Very WIP)

One area that I think would befit from an API in fabric would be allowing a way to bypass the code located in class_1946. class_1946 is currently hard coded to handle the nether portal, however it gets called when traveling to custom dimensions.

To slove this issue I came up with the following interface: (Very rough API and bad java docs)

public interface PlayerPlacementHandler {

	/**
	 *
	 * This is used to create a portal if needed, as well as set the player location in the new dim
	 *
	 * when you return true no other placement handlers will be called when the player is moving
	 *
	 * @param entity the entity that is traveling between 2 dims
	 * @param previousWorld the world that the entity is traveling from
	 * @param newWorld the world that the entity is traveling true
	 * @return if the placement handler handled this movement
	 */
	boolean placeInPortal(Entity entity, ServerWorld previousWorld, ServerWorld newWorld);

	//TODO move out of this?
	default void setEntityLocation(Entity entity, BlockPos pos){
		if (entity instanceof ServerPlayerEntity) {
			((ServerPlayerEntity)entity).networkHandler.method_14363(pos.getX(), pos.getY(), pos.getZ(), 0, 0);
			((ServerPlayerEntity)entity).networkHandler.method_14372();
		} else {
			entity.setPositionAndAngles(pos.getX(), pos.getY(), pos.getZ(), 0, 0);
		}
	}

}

The placeInPortal method is called whenever an entity changes dimension (including vanilla), this idea is to allow mods to handle teleporting to and from their own dims, as well enabling mods to replace the functionality of telporting to vanilla dims if required.

The setEntityLocation is added as a helper method to set the player's location correctly, this was based of the code found in class_1946

Bellow is the example mixin targeting PlayerManager to implement PlayerPlacementHandler

@Mixin(PlayerManager.class)
public class MixinPlayerManager {

	@Inject(method = "method_14558", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Profiler;begin(Ljava/lang/String;)V", shift = At.Shift.BEFORE), cancellable = true)
	public void method_14558(Entity entity, DimensionType dimensionType, ServerWorld previousWorld, ServerWorld newWorld, CallbackInfo info) {
		for (PlayerPlacementHandler playerPlacementHandler : DimAPI.playerPlacementHandlerList) {
			if (playerPlacementHandler.placeInPortal(entity, previousWorld, newWorld)) {

				newWorld.spawnEntity(entity);
				newWorld.method_8553(entity, false);
				entity.setWorld(newWorld);

				info.cancel();
				break;
			}
		}

	}

}

Issues with this idea:

If a mod does not handle the teleportation it will pass it onto class_1946 and the game will most likely crash. Do we need an API that holds the hand of the modder a bit more? (For example requiring them to handle all teleport to their dim?)

TL;DR

  • Patch MinecraftServer.createWorlds to handle the creation of SecondaryServerWorld

  • Create a builder around DimensionType, and possibly handle auto dim id assigning?

  • Add some AT's to ChunkGeneratorType and ChunkGeneratorFactory to make them easily accessible

  • Create an API in fabric to allow modder's to handle entity location and portal creation. Possibly find a way to stop it crashing if not handled correctly?

Conclusion

I think there are a few places where Fabric can help with the creation of modded dims, however im not sure if all of these places should be handled by fabric, or handled by the mods (Mainly thinking about the places I suggest AT'ing when possible)

One of the things that I think needs more thinking over is the placement / teleportation code as right now it is very easy to get it wrong and crash the game.

Finally, all feedback will be greatly appreciated, thanks for spending your time reading this.

Add a compound resource pack entry for "Fabric Mods"

when I was updating my personal resource pack to 1.14 I noticed that whenever I tried to replace textures from fabric mods they would stubbornly stay the same despite recreating the filestructure (ex. assets/modid/textures/blocks) and was wondering if this is a larger issue with fabric

Global datapacks

There should be a mechanism for having global datapacks, not just copying them every time into the world.

Move from impl-packages to an api-package for modder-friendly stuff

  • All new APIs going forward should be placed in .api, and expose as few non-modder-accessible methods as possible.
  • Most likely coinciding with the first snapshot of 2019, we will move all existing APIs to .api, which is a highly breaking one-time change (thus the delay!)

Opening up hardcoded block/item lists

  • Block.isNaturalDirt/isNaturalStone -> turn them into tags (fabric:natural_dirt, fabric:natural_stone)
  • ToolItem effective block lists/mining levels -> ???

Modded server connection management/versioning

  • Implement version checking (MAJOR.MINOR checked, unless 0.x.y or prerelease in which case whole string checked)
  • Make sure mods can opt out of version checking (with proper "side" etc.)
  • Kick vanilla clients out

Add a bunch of global tags

For stuff like iron_ingots, iron_blocks, etc.

What namespace to use? Unfortunately, unless we use the forge namespace, eventual compat with Forge mods will be a bit difficult, but not impossible. I'm sure we could somehow link the equivalent forge tags to fabric ones somehow.

I'd suggest the namespace global, however I can definitely see a mod named Global happening so idk...

On backwards-compatible event implementations

The current HandlerRegistry<...> route has the downside of requiring to create a new field (say, ATTACK_BLOCK_V2, ATTACK_BLOCK_V3...) every time we want to change an interface in a backwards-compatible manner - and such a reason already popped up in 19w03a.

Instead, I'm proposing something with a bit more boilerplate - to have singleton classes for every event (say, AttackBlockEvent), with functional interfaces as inner (V1, V2, ...), and a .register(V1 eventHandler) method, as well as possibly, in the future, .emit(args...) methods that possibly also handle things like cancelling/proxying return values/etc.

Am I being reasonable?

Crashes while loading saves, build 74

Fabric Mods:
Fabric API: 0.1.4 (fabric-0.1.4.74.jar)
Launched Version: MultiMC5
LWJGL: 3.1.6 build 14
OpenGL: GeForce GTX 1060 6GB/PCIe/SSE2 GL version 4.6.0 NVIDIA 417.71, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.

Using VBOs: Yes
Is Modded: Definitely; Client brand changed to 'fabric'
Type: Client (map_client.txt)
Resource Packs: 
Current Language: English (US)
CPU: 8x Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz

#@!@# Game crashed! Crash report saved to: #@!@# C:\MultiMC\instances\Fabric.minecraft\crash-reports\crash-2019-01-16_23.09.17-client.txt
AL lib: (EE) alc_cleanup: 1 device not closed
Process exited with code -1.

Simple API for getting info about a block/item/etc.

Nikky mentioned this in the Discord, and I think it would be a good idea to have an API that does a general information dump of a target ItemStack, BlockState, Mob, or anything else that can have some sort of information with it. While it originally came up due to all the WAILA mods popping up, having a way to get an information dump should be general-purpose enough that a variety of mods could make use of it.

Custom advancement criterion registry

I am unable to determine how to add custom advancement criteria that I can trigger.

net.minecraft.advancement.criterion.CriterionCriterions has a registration function but it is private. Unlike other registers, criterion do not have their own register yet.

Hooks for chunk unload and world unload

Hooks/events for these two are (among other things) useful to allow BlockEntities to have a guaranteed "dispose" callback, e.g. in case they hold some unmanaged resource (such as GL memory). Relying on finalizers for this is suboptimal. Maybe even implement them as an interface BlockEntities can implement. Might be fine to just call invalidate, even, that'd need some proper thinking about tho.

My quick and dirty mixins currently look like this for world unload (which is really just the set world in MinecraftClient, does not handle actual world unloading on server e.g., mostly because I couldn't figure out if that even happens in vanilla MC or if dim unloading was just a Forge thing), and like this for chunk unloading, which is bad if every mod has to mixin the loop themselves.

Chat API related thing

I need the following chat related things:

  • player sent chat message (Mixin: Lnet/minecraft/server/network/ServerPlayNetworkHandler;onChatMessage(Lnet/minecraft/server/network/packet/ChatMessageServerPacket;)V)
  • a way to detect /say usage

sending chat messages works via getting a instance of MinecraftDedicatedServer which gives the DedicatedPlayerManager

but would it be possible to get that server instance from FabricAPI too ?
or maybe through the loader.. it is getting constructed before the mods are loaded
so it could be passed in onInitializeServer

Side-aware Block.getPickStack

For some blocks it is necessary to know the side when trying to get the ItemStack via middle-click to return the expected result. Thinking one step further, the hit information or at least x/y/z offset might be nice, as well, I guess. Possibly an interface Blocks can implement?

My current (as I've been told evil) mixin looks like this. Will try to get rid of the @Redirect at least, until this makes it in...

Improved Info Wishlist

This issue is a wishlist of improved information about the game that I think Fabric should provide.

  • Version of the Fabric API printed to console. Currently no way to tell without looking at the jar or installing mod menu.
  • Error message when an invalid recipe is loaded.

I am going to add more as I find them, and if other people have things they want they can put them in the comments and I can add them to this list too.

I cannot set up a development environment without it erroring

Effectively, whenever I do anything after setting up the example mod as an idea project it refuses to load with the only error message being "failed to provide" it seems to generally happen after I add a second mod to the run folder generated after ./gradlew runClient is first run, after this error message shows in the console, it never seems to work ever again. any help would be appreciated,
thanks in advance

Recipe remainders

  1. There is no way to control the construction of ItemStacks for recipe remainders. This could be useful for recipes where items take damage during crafting.

  2. There is no non-hacky way to make an item have itself as a crafting remainder.

A Function<ItemStack, ItemStack> as part of the Item.Builder might be a good idea.

API to allow for adding additional Creative Tabs

Vanilla MC can only handle 12 creative tabs (the already existing ones). There's no support for additional ones, which a lot of mods will surely want to add.

Implementing the logic should be relatively easy, there needs to be a method to create a new ItemGroup which also resizes the ItemGroup.GROUPS array (it's only 12 in size by default) to allow storing the newly created group. That should be everything that's needed to get this part to work.

Creative inventory UI will be a bit more difficult. There's a couple approaches I've thought of that can be taken:

  • The Forge approach:
    Just add two buttons that switch between the creative tabs currently displayed, like Forge does. This is kind of ugly imo, since the two buttons don't fit into the rest of the GUI.

  • Scroll bar:
    Move all the creative tab buttons (except search & inventory ones) into a list on one side of the inventory gui, and add a scroll bar to it. This would look way nicer, and would be more user friendly in my opinion (dragging the mouse lets you scroll way faster to search for a tab than clicking a button a gajillion times, depending on how many mods are installed). Something like this would do the trick, I think. (I haven't moved the three tabs that are special, the search, saved items, and player inventory tab, these could either stay where they are, move to either the top or bottom completely, or just get added into the list too, which would probably be the easiest to handle.)

Thoughts? :P

Datapack tags always replace, even when they should append

API version: 0.1.4.71

Description:
My mod adds new walls. So I have to add these new walls to the vanilla block tag minecraft:walls.
With a "false" value in the "replace" field, my walls should append to the vanilla ones. But instead, they replace them.

Event Listener Priority

For events, it is useful to have a priority system. The general idea is that listeners can tell Fabric they want to be invoked earlier or later than the average listener. This is mainly useful for things like CraftTweaker or GameStage type mods where you need to prevent things from happening, or modify the initial context of the event.

The Forge Approach - In this approach there are 5 levels, highest, high, normal, low, lowest. The higher the priority the sooner the listener is called. This system is not 100% perfect, but it does work for the vast majority of cases and has been used in Forge for a very long time without any major substantial complaints.

Other Approaches - I don't know the specifics. Will update as people weigh in on the discussion.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.