Giter Site home page Giter Site logo

pyrofab / cardinal-components-api Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ladysnake/cardinal-components-api

0.0 1.0 1.0 498 KB

Component API for data-driven development

Home Page: https://minecraft.curseforge.com/projects/318449

License: MIT License

Java 100.00%

cardinal-components-api's Introduction

Cardinal-Components-API

A components API for Fabric that is easy, modular, and fast.

Adding the API to your buildscript (loom 0.2.5):

Note: as no 2.0 version of Cardinal Components API is available on the main maven, this fork offers an alternative using Jitpack

repositories {
    maven {
        name = "JitPack"
        url "https://jitpack.io"
    }
}

dependencies {
    // Replace modImplementation with modApi if you expose components in your own API
    modImplementation "com.github.Pyrofab:Cardinal-Components-API:<VERSION>"
}

The include configuration will not work with JitPack and the master jar! See how to include individual modules below.

You can find the current version of the API in the releases tab of the repository on Github.

Cardinal Components API is split into several modules. The main artifact bundles every module, but often all are not required for a project. To depend on a specific module, use the dependency string com.github.Pyrofab.Cardinal-Components-API:<MODULE>:<VERSION>. Module names can be found below.

Example:

// Adds an API dependency on the base cardinal components module
modApi "com.github.Pyrofab.Cardinal-Components-API:cardinal-components-base:<VERSION>"
// Includes the base module as a Jar-in-Jar dependency (optional)
include "com.github.Pyrofab.Cardinal-Components-API:cardinal-components-base:<VERSION>"

Usage

To get started, you only need 2 things: an interface extending Component, and a class implementing this interface.

Minimal code example:

interface IntComponent extends Component {
    int getValue();
}

class RandomIntComponent implements IntComponent {
    private int value = (int) (Math.random() * 20);
    @Override public int getValue() { return this.value; }
    @Override public void fromTag(CompoundTag tag) { this.value = tag.getInt("value"); }
    @Override public CompoundTag toTag(CompoundTag tag) { tag.putInt("value", this.value); return tag; }
}

All that is left is to actually use that component.

Components are provided by various objects through the ComponentProvider interface. To interact with those, you need to register your component type, using ComponentRegistry.registerIfAbsent; the resulting ComponentType instance is used as a key for component providers.

public static final ComponentType<IntComponent> MAGIK = 
        ComponentRegistry.INSTANCE.registerIfAbsent(new Identifier("mymod:magik"), IntComponent.class);

public static void useMagik(ComponentProvider provider) {
    // Retrieve a provided component
    int magik = MAGIK.get(provider).getValue();
    // Or, if the provider is not guaranteed to provide that component:
    int magik = MAGIK.maybeGet(provider).map(IntComponent::getValue).orElse(0);
    // ...
}

Note: a component class can be reused for several component types

Cardinal Components API offers component provider implementations for a few vanilla types, each in its own module:

Entities

Components can be added to entities of any type (modded or vanilla) by registering an EntityComponentCallback. Entity components are saved automatically with the entity. Synchronization must be done either manually or with help of the SyncedComponent and EntitySyncedComponent interfaces. Cardinal Components also provides mechanisms for handling player respawns. By default, components get copied when players return from the End, but mods can customize that behaviour through RespawnCopyStrategy and PlayerCopyCallback to copy all or part of the component data.

Example:

// Add the component to every instance of PlayerEntity
EntityComponentCallback.event(PlayerEntity.class).register((player, components) -> components.put(MAGIK, new RandomIntComponent()));
// Ensure the component's data is copied when keepInventory is enabled (Optional)
EntityComponents.registerRespawnCopyStrat(MAGIK, RespawnCopyStrategy.INVENTORY);

module: cardinal-components-entity

Item Stacks

Components can be added to stacks of any item (modded or vanilla) by registering an ItemComponentCallback. Item stack components are saved and synchronized automatically.

Notes:

  • ItemStack equality: stack equality methods areTagsEqual and isEqualIgnoreDamage are modified to check component equality. If you have issues when attaching components to item stacks, it usually means you forgot to implement a proper equals check on your component.
  • Empty ItemStack: empty item stacks never expose any components, no matter what was originally attached to them.

Example:

// Add the component to every stack of wasted diamonds
ItemComponentCallback.event(Items.DIAMOND_HOE).register((stack, components) -> components.put(MAGIK, new RandomIntComponent()));

module: cardinal-components-item

Worlds

Components can be added to any world by registering a WorldComponentCallback. World components are saved automatically with the world. Synchronization must be done either manually or with help of the SyncedComponent and WorldSyncedComponent interfaces.

Example:

// Add the component to every world
WorldComponentCallback.EVENT.register((world, components) -> components.put(MAGIK, new RandomIntComponent()));

module: cardinal-components-world

Levels

Components can be added to LevelProperties objects by registering a LevelComponentCallback. Level properties are shared between every world in a server, making them useful to store global data. Level components are saved automatically with the global state. Synchronization must be done either manually or with help of the SyncedComponent and LevelSyncedComponent interfaces.

Example:

// Add the component to level properties
LevelComponentCallback.EVENT.register((levelProperties, components) -> components.put(MAGIK, new RandomIntComponent()));

module: cardinal-components-level

Chunks

Components can be added to chunks by registering a ChunkComponentCallback. Chunk components are saved automatically with the chunk. Synchronization must be done either manually or with help of the SyncedComponent and ChunkSyncedComponent interfaces.

Notes:

  • EmptyChunk: empty chunks never expose any components, no matter what was originally attached to them. As such, when chunk components are queried on the client, one should make sure the chunk is loaded, or use ComponentType#maybeGet to retrieve a component.

Example:

// Add the component to every chunk in every world
ChunkComponentCallback.EVENT.register((chunk, components) -> components.put(MAGIK, new RandomIntComponent()));

module: cardinal-components-chunk

Blocks

Blocks actually implement the BlockComponentProvider interface instead of the regular ComponentProvider. Custom blocks may re-implement that interface themselves to provide components independently of the presence of a BlockEntity. Usually the block simply proxies its Block Entity, however the Block Entity does not need to implement BlockComponentProvider if the block already has a custom implementation. Block components can be slightly less convenient to provide as they require their own implementations, but several utility classes are available to help.

Components are entirely compatible with LibBlockAttributes' attributes. Since Component is an interface, any attribute instance can easily implement it. Conversely, making an Attribute for an existing Component is as simple as calling Attributes.create(MyComponent.class).

module: cardinal-components-block

Test Mod

A test mod for the API is available in this repository, under src/testmod. It makes uses of most features from the API. Its code is outlined in a secondary readme.

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.