跳转至内容

[原创][KubeJS][Mod]如何在1.21.1NeoForge编写一个KubeJS的附属Mod

已移动 魔改早教
11 6 475 2
  • 为什么你的目录和我的目录不一样咩?

  • 萌新第一次写,有什么不对的地方请指导()

  • 怎么没介绍event的extra怎么写

  • 怎么没介绍event的extra怎么写

    @忆然 因为懒()这篇只是基础的介绍bb3d6541-e6ff-4a6e-8d40-b97ce10d2cb7-image.png

  • 呜呜,我当时写keybindjs找extra怎么写找了半天
    苦呀西

  • 呜呜,我当时写keybindjs找extra怎么写找了半天
    苦呀西

    @忆然 大蛇教教我,这个我也不会啊喵QAQ

  • @忆然 大蛇教教我,这个我也不会啊喵QAQ

    @LirxOwO 虾头栗子,看我keybindjs仓库去

  • 草莓呜咩B 草莓呜咩 中的 研刊 移动了该主题
  • 缺少标签,现已补齐

  • KubeJS 模组附属开发指南 (NeoForge 1.21.1)

    目录

    简介

    KubeJS是一个允许玩家使用JavaScript修改Minecraft游戏的模组,为其开发附属模组可以进一步扩展其功能,为JavaScript脚本提供更多的API,让开发者拥有更多的操作可能性,例如偷走你的钱包

    项目结构

    一个标准的KubeJS附属模组项目结构如下(1.21.1 NeoForge),导入模组不用多说了吧。。。
    你都写KubeJS附属了,还不会搭环境?
    依赖的模组为KubeJS和Rhino蠢牛(1.21.1):

    src/main/
    ├── java/
    │   └── com/example/kubejsaddon/
    │       ├── YourAddonPlugin.java (主插件类)
    │       ├── YourAddonEvents.java (自定义事件)
    │       └── utils/
    │           ├── SomeUtils.java (实用工具类)
    │           └── ...其他Event类
    ├── resources/
    │   ├── kubejs.plugins.txt (KubeJS插件声明)---最重要!!
    │   ├── youraddon.mixins.json (可选的Mixin配置)
    │   └── META-INF/
    │       └── neoforge.mods.toml (模组信息)
    └── templates/
        └── META-INF/
            └── neoforge.mods.toml (模板文件)
    

    核心组件

    主插件类

    主插件类是KubeJS附属模组的入口点,需要implements KubeJSPlugin接口,相较于1.20.1为 extend kubeJSPlugin

    package com.example.kubejsaddon;
    
    import dev.latvian.mods.kubejs.plugin.KubeJSPlugin;
    import dev.latvian.mods.kubejs.script.BindingRegistry;
    import dev.latvian.mods.kubejs.event.EventGroupRegistry;
    
    public class YourAddonPlugin implements KubeJSPlugin {
        
        @Override
        public void init() {
            // 初始化代码,会在KubeJS加载时执行
            System.out.println("YourAddon Plugin initialized!");
        }
        
        @Override
        public void registerEvents(EventGroupRegistry registry) {
            // 注册自定义事件组
            registry.register(YourAddonEvents.GROUP);
        }
        
        @Override
        public void registerBindings(BindingRegistry bindings) {
            // 绑定Java类和对象到JS环境
            bindings.add("YourUtils", YourUtils.class);
            
            // 绑定Minecraft原生类
            bindings.add("SomeMinecraftClass", net.minecraft.SomeClass.class);
        }
    }
    

    事件系统

    KubeJS使用事件系统来允许JavaScript脚本响应游戏中的各种事件。要创建自定义事件,需要定义事件组和事件处理器:

    package com.example.kubejsaddon;
    
    import dev.latvian.mods.kubejs.event.EventGroup;
    import dev.latvian.mods.kubejs.event.EventHandler;
    import dev.latvian.mods.kubejs.event.KubeEvent;
    
    public interface YourAddonEvents {
        
        // 创建事件组
        EventGroup GROUP = EventGroup.of("YourAddonEvents");
        
        // 定义启动时事件
        EventHandler STARTUP_EVENT = GROUP.startup("customStartup", () -> CustomStartupEvent.class);
        
        // 定义服务器事件
        EventHandler SERVER_EVENT = GROUP.server("customServer", () -> CustomServerEvent.class);
        
        // 定义客户端事件
        EventHandler CLIENT_EVENT = GROUP.client("customClient", () -> CustomClientEvent.class);
    }
    
    // 自定义事件类
    class CustomStartupEvent implements KubeEvent {
        private final String message;
        
        public CustomStartupEvent(String message) {
            this.message = message;
        }
        
        public String getMessage() {
            return message;
        }
    }
    

    在JavaScript中使用自定义事件:

    // 在startup_scripts目录下的JS文件中
    YourAddonEvents.customStartup(event => {
        console.log("Custom startup event received: " + event.message)
    })
    
    // 在server_scripts目录下的JS文件中
    YourAddonEvents.customServer(event => {
        console.log("Custom server event with data: " + event.data)
    })
    

    触发自定义事件的Java代码:

    // 在适当的时机触发事件
    YourAddonEvents.STARTUP_EVENT.post(new CustomStartupEvent("Hello from Java!"));
    

    工具类编写

    为了向JavaScript环境提供有用的功能,通常需要创建各种工具类,丰富自己在开发时有更多的工具选择,而不局限于KubeJS提供的Utils

    package com.example.kubejsaddon.utils;
    
    import dev.latvian.mods.kubejs.typings.Info;
    
    public class YourUtils {
        
        // 使用@Info注解提供JavaScript文档
        //使用ProbeJS补全时会显示该方法调用时是用于什么
        @Info("一个简单的方法描述")
        public static String doSomething(String input) {
            return "Processed: " + input;
        }
        
        @Info("另一个带有参数说明的方法")
        public static int calculate(int a, int b) {
            return a + b;
        }
        
        // 静态内部类也可以被暴露给JavaScript
        public static class InnerHelper {
            @Info("内部类的方法")
            public static boolean check(String value) {
                return value != null && !value.isEmpty();
            }
        }
    }
    

    配置文件

    kubejs.plugins.txt

    src/main/resources/kubejs.plugins.txt文件中声明你的KubeJS插件,这个txt非常重要,这是你KubeJS Plugins能被运行的重要文件之一!如果缺失,KubeJS将无法检测到你的附属Mod:

    # KubeJS插件声明
    # 格式:完整类名 [依赖模组ID] or [client]
    
    # 主插件类
    com.example.kubejsaddon.YourAddonPlugin
    
    # 如果有客户端专用插件
    # com.example.kubejsaddon.YourAddonClientPlugin client
    
    # 如果依赖其他模组
    # com.example.kubejsaddon.IntegrationPlugin some_mod_id
    

    编写完后就可以build为jar,放到生产环境中测试,建议搭配 ProbeJS 食用你自己编写的第一个KubeJS Plugins,在游戏中使用/probejs dump来检测ProbeJS是否能将你的方法导出为ts文件,并在vscode中补全,编写一些方法来测试你的附属是否有效。如果上述都成功实现了,那么恭喜你成功开发了一个KubeJS附属!

    @LirxOwO[原创][KubeJS][Mod]如何在1.21.1NeoForge编写一个KubeJS的附属Mod 中说:

    Override

    装饰器的at符号渲染爆掉了?

  • Override被爆掉确实很奇怪…


相关推荐


  • [原创][KubeJS]简单的以tick实现的嘲讽

    灵感大王 kubejs
    3
    2 赞同
    3 帖子
    86 浏览
    稽塔Gui_tarJ
    我必须先攻击拥有嘲讽的随从
  • [原创][1.21.X][Neoforge][modding]CodecCodec你的!

    已移动 魔改早教 模组开发
    2
    3 赞同
    2 帖子
    217 浏览
    AnNingUIA
    受益颇多
  • 美食再就业:用紫颂果慕斯进行定点传送

    灵感大王 kubejs 物品
    1
    3 赞同
    1 帖子
    50 浏览
    草莓呜咩B
    美食们可不止能饱腹而已! 紫颂果慕斯既然是紫颂果做的,就和传送脱不了关系? 现在可以将它在铁砧上改名为坐标,逗号间隔,吃了就可以传送到该坐标,是不是很方便呀。 不过还是要消耗一点点经验呢。 ItemEvents.foodEaten("kitchenkarrot:chorus_mousse", event => { let position = event.player.mainHandItem.displayName.getString().slice(1, -1).split(","); if (event.player.xpLevel < 3) event.player.statusMessage = "经验等级不足, 需要三级经验!"; else if (position.length == 3) { event.player.setPosition(position[0], position[1], position[2]); event.player.addXPLevels(-3); } }); 那么草莓慕斯会是什么效果呢?要是能召唤草莓军团就太帅了!