Mod

Fallen Lib

Quick rating

Fallen Lib

No reviews yet

A library providing runtime extension utilities

No Theme
No Genre
Mod Addon
API/Library
Mod Loaders
Forge
Minecraft

Community voices

Reviews

Versions
Loading versions…
Match includes

Click once to include, again to exclude, again to clear

Rating Any
Any 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
Min
Max
Play Status
Reviews
Time Played
hrs+
Verified developers only
Has developer response
List view
Grid view
Compact view
Sort by
Date
Rating
Helpful
Unhelpful
Edited
Sort ascending
Delete this review?

This removes your review from the project. You can write a new review after.

Review submitted for moderation

Your review has been sent to moderators, who will check that it meets our guidelines before it appears publicly.

No reviews yet. Be the first to review this project!

Get it on

Available Platforms

About

Project Details

Type
Mod
Latest Version
fallen_lib-1.4.4.jar
Authors

For authors

Embed Badge

If you're the author of this project, you can embed a live badge anywhere that supports HTML or Markdown. It updates automatically whenever ratings change.

Custom banner text
ModDex rating badge preview

Use HTML for any page that supports it, or Markdown for README files and Markdown-based descriptions.

Identifiers

Platform IDs

CurseForge ID

Resources

External Links

Source Issues Wiki Discord

About

Description

Fallen Lib is a small developer utility library.
It is currently used during development of Fallen Gems & Affixes.

For Fallen Gems & Affixes 2.0.7 and below, please use verison 1.2.0-hotfix 

This mod provides some ASM realted APIs and also runtime utilities for mod development.
It does not add any gameplay content and is not intended for normal players.

Development environment

When running in an IDEA, please use the both JARs suffixed with `core` and 'runtime' (It's in the Additional Files section).

For normal gameplay or distribution, use the normal JAR.

Features

FallenPatch

A delegating API for patching mod classes.

It can hook exact classes or all subclasses,
which helps reduce repeated patches when extending mod behavior.

To use the API, you must implement the `IFallenPatch` interface, then the class must have the annotation `@FallenPatch` with correct parameters.

For example: 

@FallenPatch(
        priority = 1000,
        targets = @Targets(
                exact = {SomeClass.class},
                subclass = {SuperClass.class}),
        inserters = {FallenInserters.class})
public class FallenPatch implements IFallenPatch {
    private final IPatchDescriptor desc;
    // Here you must provide a constructor like this.
    public FallenPatch(IFallenPatchCtorContext iFallenPatchCtorContext) {
        desc = iFallenPatchCtorContext.currentPatch();
    }

    @Override
    public void apply(ClassNode cn, IFallenPatchContext iFallenPatchContext) {
        MethodInsnNode hook = iFallenPatchContext.getFallenInserter(
                InserterKey.of("xxx.xxx.FallenInserters",
                        "hook",
                        InserterType.STANDARD_VOID));
        for (MethodNode method : cn.methods) {
            InsnList insns = method.instructions;
            if (insns == null) continue;
            PatchUtil.insertMethodHook(cn,
                    method,
                    m -> m instanceof MethodInsnNode mn
                            && mn.owner.equals("xxx.xxx.ClassName")
                            && mn.name.equals("methodName")
                            && mn.desc.startsWith("(Ljava/lang/Object;")
                            && Type.getReturnType(mn.desc).getSort() != Type.VOID,
                    InserterType.STANDARD_VOID,
                    hook,
                    false,
                    false);
        }
    }
}

The `inserters` targets a class which has at least 1 method with `@FallenInserter` annotation.
For example the `FallenInserters.class`:

public class FallenInserters {
    @FallenInserter(type = InserterType.STANDARD_VOID)
    public static void hook(IInserterContext<Object, Object> ctx, Object... args) {
Object rec = ctx.receiver(); } }
Then there should have an `xxx.fallen.json` file in your resource root.
Fomated as: 
{
  "required": true,
  "min_version": "1.2.0",
  "package": "xxx.package.name",
  "fallen_patches": [
    "FallenPatch",
    "PatchClassName"
  ]
}

Currently, FallenPatch only supports patching mod classes.
Further support may be added in the future.

FallenInserter

Along with FallenPatch, use `@FallenInserter` on a method with correct parameter types and return type,

There are now 2 types of InserterType:

`InserterType.STANDARD` 

`InserterType.STANDARD_VOID`

the default is standard, which should be like following formats: 

@FallenInserter(type = InserterType.STANDARD)
public static Object hook(IInserterContext<Object, Object> ctx, Object... args) {
    return ctx.ret();
}
@FallenInserter(type = InserterType.STANDARD_VOID)
public static void hook(IInserterContext<Object, Object> ctx, Object... args) {
}


the `ctx` has `ctx.receiver()` and `ctx.ret()` methods, which gives you the `this(may be null)` and return Object of the method you inserted, if it has return value and `replaceReturn` flag is `true` in the method, the return will replace the return value of orginal method, you can try following util `ObjectModifierFactory` to modify the numeric fields of this Object and return.

the `args` is an `Object[]` which contains all parameters of the method you inserted, `InserterType.STANDARD` is invoked after the method, so they are just a view, do not change them.

If you correctly configured and implement the IFallenPatch interface with correct annotation and then you can 

 MehtodInsnNode hookMethod = iFallenPatchContext.getFallenInserter(
                InserterKey.of("your.class.name", 
                               "methodName", 
                               InserterType));

To get your hookMethod (if they have correct parameter types and return type, they will be buit by fallen lib)

Then use

PatchUtil.insertMethodHook()

To make easier patch (not as easy as mixin tho).


RuntimeUtility

Some runtime utilities.

`ObjectModifierFactory`

Copies an object

Modifies numeric fields

Uses cache and field name filters

For example: 

public class FallenInserters {
// this needs a Predicate<String>
  private static final ObjectModifierFactory FACTORY = new ObjectModifierFactory(s -> {
String filedName = s.toLowerCase();
if (name.contains("xxx")) return true;
return false;});   @FallenInserter(type = InserterType.STANDARD) public static Object hook(IInserterContext<Object, Object> ctx, Object... args) {
Object ret = ctx.ret()
return FACTORY.doSomething(ret); } }

This is mainly used for runtime adjustments without modifying the original object.

`Delegated Mixin Connector Registry`: (above verison 1.3.2)

A service like registry, this makes you able to test in IDEA with conditionally loaded mixins configs by implementing the official IMixinConnector class in your mod.

Use like below, target a class that implements IMixinConnector, then config with a json in resources root with following format

{
  "required": true,
  "min_version": "1.3.2",
  "mixin_connector": "net.kayn.apotheotic_hostility.FGAMixinConnector"
}

the key "mixin_connector" should be your class reference.


Apotheosis Addon (Apotheosis installed only)

Extra Gem Bonus

You can now register extra gem bonuses in apotheosis 1.20.1 with a datapack just like 1.21.1

the structure should be `resources/namespace/extra_gem_bonuses/somegembonus.json


Notes

This project has reached a usable state,
but APIs may still change as development continues.

Screenshots

Gallery

This project has no gallery images yet.

Versions

Files

Relations

Project Relations

More like this

Similar Mods

Suggestions use data such as tags, dependencies, dependents, descriptions, titles, and more to rank how much they overlap with this mod.

On ModDex

Community snapshot

0
Ratings
0
Followers
0
In stacks

By the numbers

Statistics

~200,000
Downloads
Last Updated
Created
Last synced
When ModDex last fetched and imported data for this project from CurseForge or Modrinth. High-traffic and active projects are checked more often.
Next pipeline sync