#Leaf (forked from FabricMC/fabric)

1 messages ยท Page 3 of 1

jagged scarab
#

No

floral sluice
#

class name cant be the same as the other mixins btw, have to be unique

#

and it needs to also be added to the mixins json file

rare mural
#

I think you need to take the cir variable

#

And if it's cancelable, you need to either call cir.cancel() or set the return value.

#

But it's a void function.

#

So probably don't need to set cancelable

jagged scarab
floral sluice
#

having CallbackInfoReturnable is only useful if the original function returns something and you want to capture or manipulate it

rare mural
#

just CallbackInfo ci

#

yea

jagged scarab
#

Okay the game starts let's see if it print hello world when a game start

#

Yess
LOG : Mod f:0, t:1755352169599> The game starts!

#

Let's pop a new NewWindow in this context

#

No window poped

#

How can I run my own thread loop function?

#

Or redirect the OnRender/OnTick function to call mine?

rare mural
#

just making the window wont do it

#

you need to add it to the UIManager

floral sluice
#

when in doubt, do it how the game does it

#

search for familiar strings/classes/functions in the decompile and see where it takes you

jagged scarab
rare mural
#

no

jagged scarab
#

I'm grepping that

rare mural
#

the UIManager is a static class

#

you need to write another mixin

#

where you define an invoker

#

then from your other mixin you use that invoker

jagged scarab
rare mural
#
@Mixin(UIManager.class)
public interface UIManagerInvoker {
  @Invoker("AddUI")
  public static void invokeAddUI(UIElementInterface uiElementInterface) {
    throw new AssertionError();
  }
}
#

Whole new mixin

#

make sure to register it in the mod config

#

Then from your original mixin, do

UIManagerInvoker.invokeAddUI(theNewWindowInstance);
#

Might work, might not. You might need to create an invoker on the constructor of NewWindow and use that to construct it, not sure.

jagged scarab
jagged scarab
#

UIManagerInvoker.invokeAddUI(uiElement);

#

Lets retry

#
@Mixin(UIManager.class)
public interface UIManagerInvoker {
    @Invoker("AddUI")
    public static void invokeAddUI(UIElementInterface uiElementInterface) {
        //throw new AssertionError();
        UIManager.AddUI(uiElementInterface);
    }
}```
#

Black screen after loading the game. Inputs generates exceptions

#
STACK TRACE
-----------------------------------------
Callframe at: isClimbingRope
function: ChangeClimbDirection -- file: CFarming_Interact.lua line # 384 | Vanilla
#

Wtf

#
LOG  : Mod          f:0, t:1755353686193> The game starts!
DEBUG: Leaf         f:0, t:1755353686202> NativeMethodAccessorImpl.invoke0 (Native Method)> Generating mapped inner class zombie/gameStates/IngameState$Anonymous$57f40be3686240ed8a4b46a9bbc89f53 (originally com/example/mixin/ExampleMixin$1)
ERROR: General      f:0, t:1755353686247> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: Mixin transformation of com.example.mixin.UIManagerInvoker failed at KnotClassDelegate.getPostMixinClassByteArray(KnotClassDelegate.java:579).
    Stack trace:
        dev.aoqia.leaf.loader.impl.launch.knot.KnotClassDelegate.getPostMixinClassByteArray(KnotClassDelegate.java:579)
#
dev.aoqia.leaf.loader.impl.launch.knot.KnotClassDelegate.tryLoadClass(KnotClassDelegate.java:460)
        dev.aoqia.leaf.loader.impl.launch.knot.KnotClassDelegate.loadClass(KnotClassDelegate.java:322)
        dev.aoqia.leaf.loader.impl.launch.knot.KnotClassLoader.loadClass(KnotClassLoader.java:118)
        java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
        knot//zombie.gameStates.IngameState.handler$zza000$modid$enter(IngameState.java:2104)
        knot//zombie.gameStates.IngameState.enter(IngameState.java:846)
        knot//zombie.gameStates.GameStateMachine.update(GameStateMachine.java:133)
        knot//zombie.GameWindow.logic(GameWindow.java:382)
        knot//zombie.GameWindow.frameStep(GameWindow.java:916)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)
    Caused by: org.spongepowered.asm.mixin.transformer.throwables.IllegalClassLoadError: Illegal classload request for accessor mixin com.example.mixin.UIManagerInvoker. The mixin is missing from modid.mixins.json which owns package com.example.mixin.* and the mixin has not been applied.
        org.spongepowered.asm.mixin.transformer.MixinProcessor.applyMixins(MixinProcessor.java:323)
        org.spongepowered.asm.mixin.transformer.MixinTransformer.transformClass(MixinTransformer.java:237)
        org.spongepowered.asm.mixin.transformer.MixinTransformer.transformClassBytes(MixinTransformer.java:202)
        dev.aoqia.leaf.loader.impl.launch.knot.KnotClassDelegate.getPostMixinClassByteArray(KnotClassDelegate.java:572)
        ... 12 more
jagged scarab
# floral sluice is this ytour mixin?
package com.example.mixin;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import zombie.ui.UIElementInterface;
import zombie.ui.UIManager;

@Mixin(UIManager.class)
public interface UIManagerInvoker {
    @Invoker("AddUI")
    public static void invokeAddUI(UIElementInterface uiElementInterface) {
        //throw new AssertionError();
        UIManager.AddUI(uiElementInterface);
    }
}```
floral sluice
#

it literally says the error in the log you posted

#

did you read it?

jagged scarab
#

Yes

#
ERROR: General      f:0, t:1755353686247> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: Mixin transformation of com.example.mixin.UIManagerInvoker failed at KnotClassDelegate.getPostMixinClassByteArray(KnotClassDelegate.java:579).
    Stack trace:```
#

modid.mixins.json

#

Where is this damn file

#
/leaf-example-mod/build/resources/main/modid.mixins.json
/leaf-example-mod/src/main/resources/modid.mixins.json
#
{
    "required": true,
    "package": "com.example.mixin",
    "compatibilityLevel": "JAVA_17",
    "mixins": [
        "ExampleMixin",
        "UIManagerInvoker" ///// <<<< THIS
    ],
    "injectors": {
        "defaultRequire": 1
    },
    "overwrites": {
        "requireAnnotations": true
    }
}```
#

Same boring black screen

#

The game +intellij just crash while I was trying to minimize the game....

floral sluice
jagged scarab
#

Okay now

java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "zombie.ui.UIElementInterface.isFollowGameWorld()" is null at UIManager.update(UIManager.java:673).
#

I messed with the UIManager now everything breaks

floral sluice
#

the throw new AssertionError() is there to make sure the invokeAddUI is there for a reason, im pretty sure it's to make sure that you dont call the wrong thing on accident

#

you dont do any code in there, you want to use the invoker like a proxy method

jagged scarab
#

Yes but the proxy must call the right method like so?

//throw new AssertionError();
UIManager.AddUI(uiElementInterface);
floral sluice
#

So you would use your invoker like UIManagerInvoker.AddUI(iface) not do UIManager.AddUI in the invoker method

jagged scarab
#

Aaaah

#

simply like that ?

@Mixin(UIManager.class)
public interface UIManagerInvoker {
    @Invoker("AddUI")
    public static void invokeAddUI(UIElementInterface uiElementInterface) {
        throw new AssertionError();
    }
}```
floral sluice
#

yes keep it that

#

then you call your invokeAddUI from another mixin or entrypoint or wherever you want

rare mural
jagged scarab
#

I must repeat the Mixin process for every call I make ?

rare mural
#

To game code? Yes.

#

You only have to write the invoker once, but then you can now call that method as much as you want.

#

You have to "expose" game things in order for your code to interact with it.

jagged scarab
#

Nice

jagged scarab
#

Same errors, game crashe

#

The logs are polluted with the same Exception

rare mural
#

which is what

jagged scarab
#

Which is

LOG  : Mod          f:0, t:1755355205701> The game starts!
DEBUG: Leaf         f:0, t:1755355205706> NativeMethodAccessorImpl.invoke0 (Native Method)> Generating mapped inner class zombie/gameStates/IngameState$Anonymous$135f0306fc854a75a7897f96ee601c84 (originally com/example/mixin/ExampleMixin$1)
ERROR: General      f:0, t:1755355206849> ExceptionLogger.logException> Exception thrown
    java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "zombie.ui.UIElementInterface.isFollowGameWorld()" is null at UIManager.update(UIManager.java:673).
    Stack trace:
        knot//zombie.ui.UIManager.update(UIManager.java:673)
        knot//zombie.GameWindow.logic(GameWindow.java:326)
        knot//zombie.GameWindow.frameStep(GameWindow.java:916)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)
#

an error that don't seems to be corelated to the code I'm editing which turn the developement very hard

rare mural
#

It seems related

#

What it's saying is, that when UIManager.update was called by the main loop

jagged scarab
rare mural
#

It ried to call .isFollowGameWorld() on something and that returned null, when it should be a boolean

#

it's perfectly enough information..

#

you just have to read...

#

and give yourself a chance to understand

#

again

#

when UIManager.update is called

#

it's doing some work on its children

#

it goes to called isFollowGameWorld on that object, and it reutrns null instead of boolean

#

This is probably your NewWindow instance, which is probably broken

jagged scarab
#

I understand the error message but the question is what I did wrong in MY code not .isFollowGameWorld() ?

rare mural
#

read what i said three or four more times

floral sluice
#

its not 1 class per method thankfully

rare mural
#

hehe

jagged scarab
rare mural
#

the short of it seems to be that you are successfully adding something to UIManager but it doesn't like it

#

what?

#

then what are you adding to the UIManager?

jagged scarab
rare mural
#

yes.. the window instance

jagged scarab
rare mural
#

i don't know what you are saying

#

show all the code

jagged scarab
#

ExampleMod.java

package com.example;

import dev.aoqia.leaf.api.ModInitializer;

import zombie.debug.DebugLog;
import zombie.debug.DebugLogStream;

//import zombie.ui.NewWindow;

public class ExampleMod implements ModInitializer {
    public static final String MOD_ID = "modid";
    public static final DebugLogStream LOGGER = DebugLog.Mod;

    public static final String GAME_VERSION_CHANGED_EVENT = "GameVersionChanged";

    @Override
    public void onInitialize() {
        System.out.println("Hello Leaf World!!! >w<");
        //NewWindow window;
        //window = new NewWindow(0, 0, 500, 500, true);
        //window.render();
    }
}
rugged fog
#

Coming in late, but is there a benefit to using Java for UI? I thought the Lua exposure for UI is one of the few near 100% cases.

floral sluice
#

It's probably due to UIElementInterface.isFollowGameWorld() probably returns a field.booleanValue() or something and field is null because you instantiated the class wrong OR the field not set for some other reason or something

floral sluice
rugged fog
#

I remember, but UI?

rare mural
rugged fog
#

Ooh

jagged scarab
#

UIManagerInvoker.java

package com.example.mixin;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import zombie.ui.UIElementInterface;
import zombie.ui.UIManager;

@Mixin(UIManager.class)
public interface UIManagerInvoker {
    @Invoker("AddUI")
    public static void invokeAddUI(UIElementInterface uiElementInterface) {
        throw new AssertionError();
    }
}
rare mural
#

Are you using the minecraft plugin? You're not using the right syntax for the method names etc I think

floral sluice
#

lol thats why

#

you're literally returning null in the method you override

rare mural
#

what is that

floral sluice
#

please tell me you have some java experience going into this, you're not gonna like it if you dont, especially for a mod this size going that far into the engine

rare mural
#

There's no reason to use UIElementInterface directly, it's an interface!

jagged scarab
rare mural
#

This is why I said do more simple stuff first. I can barely fathom of more technically challenging goals if I tried.

rare mural
#

Make a window

#

Pass it to AddUI

rare mural
#

literally everywhere

#
@Override
            public Boolean isCapture() {
                return null;
            }
#

return type Boolean

returns null anyway

floral sluice
#

in the interface you override..

rare mural
#

I'm surprised it even compiles, new on an interface?

#

the hell does that even do.

#

maybe java interfaces are not like other languages

#

ยฏ_(ใƒ„)_/ยฏ

floral sluice
#

test

#

why did my messag edelete

#

its the same as if you were to implement an interface

rare mural
#

huh?

#

like viewport there is a class object?

floral sluice
#

you know how you can create a class to implement an interface

rare mural
#

sure, statically

jagged scarab
# rare mural literally everywhere

Everywhere in which file?
I'm trying

    @Inject(method = "enter", at = @At("RETURN"), cancellable = false)
    private void enter(CallbackInfo ci) {
        LOGGER.println("The game starts!");
        NewWindow viewport;
        viewport = new NewWindow(0, 0, 500, 500, true);
        UIManagerInvoker.invokeAddUI(viewport);
    }
floral sluice
#

thats what its doing basically but I think its anonymous class or something

floral sluice
#

much more

#

but NewWindow is still the problem child ๐Ÿ˜‚

#

waiot nvm thats the same mixin, all is well

jagged scarab
#

A small window appear in the upper right corner but not a 500*500 one

#

And there are errors in cascade

rare mural
#

what is cascade

jagged scarab
#

The ESC key doesn't work anymmore and produce errors

jagged scarab
#

I mean collateral ?

rare mural
#

dunno, but you can share the errors

jagged scarab
#
LOG  : General      f:148, t:1755356939703> -----------------------------------------
STACK TRACE
-----------------------------------------
function: updateTooltip -- file: ISScrollingListBox.lua line # 375 | Vanilla
function: prerender -- file: ISScrollingListBox.lua line # 520 | Vanilla

ERROR: General      f:148, t:1755356939704> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: attempted index: isMouseOver of non-table: zombie.ui.NewWindow@54bd31ff at KahluaThread.tableget(KahluaThread.java:1530).
    Stack trace:
        knot//se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1530)
        knot//se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:502)
        knot//se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:174)
        knot//se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1826)
        knot//se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1668)
        knot//se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:38)
        knot//zombie.ui.UIElement.render(UIElement.java:1990)
        knot//zombie.ui.UIElement.render(UIElement.java:2000)
        knot//zombie.ui.UIElement.render(UIElement.java:2000)
        knot//zombie.ui.UIManager.render(UIManager.java:419)
        knot//zombie.gameStates.IngameState.renderFrameUI(IngameState.java:1331)
        knot//zombie.gameStates.IngameState.renderframeui(IngameState.java:1317)
        knot//zombie.gameStates.IngameState.renderInternal(IngameState.java:1456)
        knot//zombie.gameStates.IngameState.render(IngameState.java:1406)
        knot//zombie.gameStates.GameStateMachine.render(GameStateMachine.java:28)
        knot//zombie.GameWindow.renderInternal(GameWindow.java:468)
        knot//zombie.GameWindow.frameStep(GameWindow.java:940)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)
rare mural
#

hmm

jagged scarab
#

And also for the ESC key

LOG  : General      f:3105, t:1755357010553> -----------------------------------------
STACK TRACE
-----------------------------------------
function: setVisibleAllUI -- file: ISUIHandler.lua line # 15 | Vanilla
function: ToggleEscapeMenu -- file: MainScreen.lua line # 2060 | Vanilla

ERROR: General      f:3105, t:1755357010553> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: attempted index: isVisible of non-table: zombie.ui.NewWindow@54bd31ff at KahluaThread.tableget(KahluaThread.java:1530).
    Stack trace:
        knot//se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1530)
        knot//se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:502)
        knot//se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:174)
        knot//se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1826)
        knot//se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1653)
        knot//se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66)
        knot//se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139)
        knot//zombie.Lua.Event.trigger(Event.java:72)
        knot//zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:315)
        knot//zombie.input.GameKeyboard.update(GameKeyboard.java:64)
        knot//zombie.GameWindow.logic(GameWindow.java:308)
        knot//zombie.GameWindow.frameStep(GameWindow.java:916)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)
rare mural
#

That makes sense I guess

jagged scarab
#

But the NewWindow poped !

#

But it do not refresh and the layout is weird

#

With a close button in the middle...

#

I will go soon for an hour or so

rare mural
#

NewWindow doesn't call the super constructor

jagged scarab
#

I will be back

jagged scarab
#

Also why

rare mural
#

The base classe of NewWindow, UIElement is the thing that sets the lua table

jagged scarab
#

interesting

rare mural
#

try

#

viewport.set_table(LuaManager.platform.newTable())

#

though you'll probably need an invoker heh

jagged scarab
#

set_table method not found

rare mural
#

setTable

jagged scarab
#

No build error with LuaManager.platform.newTable()

#

I try to launch the game and see what appen

rare mural
#

I think you need an ISUIElementWrapper... ๐Ÿค”

jagged scarab
#

Tell me all your knowledge about the UI please.

#

I must go, see you later

rare mural
spark plinth
#

Figured it out. Was trying to run example mod from workshop. Only when i run the game using leaf-loader repo via runClient task it gave me an error Mod 'Example mod' (modid) 1.0.0 requires version 1.2.0 or later of leafloader, which is missing! i don't know why it wasn't logging using real game client
Anyhow, (my leaf loader version was 1.4.1) rebuilding mod via specifying letest version of loader did the trick and now it loads ๐ŸŽ‰

floral sluice
#

but yeah generally you want to update the example mod depending on the loader's version as well, or use * which means any version

floral sluice
spark plinth
#

No error both in GUI and logs

floral sluice
#

hmm weird

#

Not even in logs is weirder, but I am assuming that it didn't show in the log for some reason because the GUI was supposed to show...

#

Did it work for you in the IDE, even when the loader dependency was set to >=1.2.0

rare mural
floral sluice
#

not really

#

you can use it, but it's limited to client for now, because I need to figure out how im going to edit the server scripts for each platform

#

They made a launcher for the client but no the server ๐Ÿ™ wheres the love lol

#

Anyway, im trying to take breaks over the weekends to prevent burnout, because if I don't like I have been, it's really annoying to work on anything

rare mural
floral sluice
#

uh it should work unless I'm forgetting something

rare mural
#

Remember you were like "Just launch it from the IDE" something about not being able to find mappings in prod

floral sluice
#

there are no mappings used in prod

#

I assume you were talking about that one time where in prod the log just ended after only a few lines, which I couldn't replicate at all

rare mural
#

@floral sluice I mean this

#

I don't think we ever resolved it. You recommened I just launch from IDE and I've been doing that ever since.

dull stirrup
#

first KEE npcs with Leaf

stray rock
#

I think this has great potential

#

Me and Snejk are looking into this

valid nova
#

๐Ÿ‘€

#

Yooooo

#

Let's go

#

@floral sluice that's quite a huge leap forward

dull stirrup
#

although, they don't move in the metaverse and procedural generation doesn't work

#

but it was at least able to load the classes into JVM and expose them through Lua, so all of the Lua scripts are working fine

rare mural
#

I would really love to be involved in java NPC modding. Are you guys working out of github?

stray rock
rare mural
#

I think I did ask in the past. If there's no room for other people, no worries

jagged scarab
#

Hello @floral sluice @rare mural sorry for yesterday I didn't relog

rare mural
#

I wanted to see if I could surprise you but I got stuck polishing my own project's UI

jagged scarab
#

I'm reading UIManager:update

rare mural
#

I think you need to use the wrapper class

#

It sets up the associated lua table

#

I'm not positive

#

but the ISUIElementWrapper seems to maintain a lua table that is wanted by UIManager

jagged scarab
#

@rare mural I think I will search for the existing UI buttons to see how they achieve the display of a new window

#

Like the health button

#

Maybe in NewHealthPanel

#

extends NewWindow

#

Okay let's copy past this class to do my own window class

rare mural
#

eh i dunno

#

seems like NewHealthPanel is exposed to the lua via the LuaManager.Exposer

#

and it's probably created in the lua

#

@jagged scarab what was the error you were getting yesterday

#

from UIManager

#

Reading the UIManager it really feels like you should be able to create something extending UIElementInterface and call UIManager.AddUI

jagged scarab
rare mural
#

what exactly was it though

jagged scarab
#
STACK TRACE
-----------------------------------------
function: updateTooltip -- file: ISScrollingListBox.lua line # 375 | Vanilla
function: prerender -- file: ISScrollingListBox.lua line # 520 | Vanilla

ERROR: General      f:52, t:1755357871100> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: attempted index: isMouseOver of non-table: zombie.ui.NewWindow@6e5a2c3 at KahluaThread.tableget(KahluaThread.java:1530).
    Stack trace:
        knot//se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1530)
        knot//se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:502)
        knot//se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:174)
        knot//se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1826)
        knot//se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1668)
        knot//se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:38)
        knot//zombie.ui.UIElement.render(UIElement.java:1990)
        knot//zombie.ui.UIElement.render(UIElement.java:2000)
        knot//zombie.ui.UIElement.render(UIElement.java:2000)
        knot//zombie.ui.UIManager.render(UIManager.java:419)
        knot//zombie.gameStates.IngameState.renderFrameUI(IngameState.java:1331)
        knot//zombie.gameStates.IngameState.renderframeui(IngameState.java:1317)
        knot//zombie.gameStates.IngameState.renderInternal(IngameState.java:1456)
        knot//zombie.gameStates.IngameState.render(IngameState.java:1406)
        knot//zombie.gameStates.GameStateMachine.render(GameStateMachine.java:28)
        knot//zombie.GameWindow.renderInternal(GameWindow.java:468)
        knot//zombie.GameWindow.frameStep(GameWindow.java:940)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)
#

LUA Error

rare mural
#

scrolling list box..?

jagged scarab
#

Yes it's the render function of UIManager

rare mural
#

oh i see

#

I see!

jagged scarab
#

Look what I'm creating

#
package com.example;

import zombie.ui.NewWindow;

public /*final*/ class UIViewport
        extends NewWindow {
    public static UIViewport instance;
    private static int UI_BORDER_SPACING;

    public UIViewport(int n, int n2) {
        super(n, n2, 10, 10, true);
        this.ResizeToFitY = false;
        this.visible = false;
        instance = this;
        this.width = 300 + UI_BORDER_SPACING;
        this.height = 270 + this.titleRight.getHeight() + 5;
    }

    @Override
    public void render() {
    }

    @Override
    public void update() {
        if (!this.isVisible()) {
            return;
        }
        super.update();
    }

    static {
        UI_BORDER_SPACING = 10;
    }
}```
#

'titleRight' is not public in 'zombie.ui.NewWindow'. Cannot be accessed from outside package

floral sluice
rare mural
#

The issue is that UIElement introduces this.table which its render and other logic depend on.

#

While NewWindow inherits UIElement, neither do anything to setup this.table

floral sluice
rare mural
#

UIElement() has a constructor which takes the table if one's already available. And it also has a setTable method for setting it after construction.

#

Inside ISUIElementWrapper you can see that it does things:

    protected void instantiate() {
        UIElement uIElement = new UIElement(this.table);
        this.table.rawset("javaObject", uIElement);
        uIElement.setX(LuaHelpers.castDouble(this.table.rawget("x")));
        uIElement.setY(LuaHelpers.castDouble(this.table.rawget("y")));
        uIElement.setHeight(LuaHelpers.castDouble(this.table.rawget("height")));
        uIElement.setWidth(LuaHelpers.castDouble(this.table.rawget("width")));
        uIElement.setAnchorLeft(LuaHelpers.castBoolean(this.table.rawget("anchorLeft")));
        uIElement.setAnchorRight(LuaHelpers.castBoolean(this.table.rawget("anchorRight")));
        uIElement.setAnchorTop(LuaHelpers.castBoolean(this.table.rawget("anchorTop")));
        uIElement.setAnchorBottom(LuaHelpers.castBoolean(this.table.rawget("anchorBottom")));
        uIElement.setWantKeyEvents(LuaHelpers.castBoolean(this.table.rawget("wantKeyEvents")));
        uIElement.setWantExtraMouseEvents(LuaHelpers.castBoolean(this.table.rawget("wantExtraMouseEvents")));
        uIElement.setForceCursorVisible(LuaHelpers.castBoolean(this.table.rawget("forceCursorVisible")));
        LuaHelpers.callLuaClass(this.table.getMetatable().getString("Type"), "createChildren", this.table);
    }
floral sluice
rare mural
#

Well in lua I think you often need to call instantiate and initialise right?

floral sluice
#

Yes

rare mural
#

This is likely the implementation of those

#
    public void initialise() {
        this.table.rawset("children", LuaManager.platform.newTable());
        KahluaTable tablex = (KahluaTable)LuaManager.env.rawget("ISUIElement");
        double double0 = LuaHelpers.castDouble(tablex.rawget("IDMax"));
        this.table.rawset("ID", double0);
        tablex.rawset("IDMax", double0 + 1.0);
    }
floral sluice
#

and when you create your own UI in Lua, you add your own render, update, functions too

#

But its not required though like initialise is

#

I'm not sure if instantiate is needed (in lua) but I would use it anyway

#

Also what is the point of creating a lua ui on the first place?

#

Lua is slow ๐Ÿ™

rare mural
#

Not the goal, he's trying to add something related to NewWindow to the UIManager but it ends up with the exception above

#

UIElement (base class of NewWindow) calls into lua during its java render

#

Once in the lua, it blows up because the UIElement's table is not properly configured

#

Once execution goes into lua though you don't get any useful information out of the stack trace:

        knot//se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1530)
        knot//se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:502)
        knot//se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:174)
        knot//se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1826)
        knot//se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1668)
        knot//se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:38)
        knot//zombie.ui.UIElement.render(UIElement.java:1990)
jagged scarab
#

Game crashed ........

rare mural
#

no doubt

jagged scarab
#

No error messages, just a raw crash

rare mural
#

i wouldn't expect the stuff you're doing above to work

jagged scarab
#

Why

rare mural
#

I doubt that you can just extend game classes like that... Maybe you can? Dunno..

#

Thinking about it you probably can?

floral sluice
#

You know, if you really need lua, you can create a submod and write Lua like a normal mod to extend your UI thing

rare mural
#

I think it's just the dependence on UIElement that's the issue

#

UIElementInterface is all you technically need

#

So I would probably take a good look at UIElement and see how I can remove anything not needed (like all the lua stuff) and then focus on learning how to use SpriteRenderer to render my own window square, etc

jagged scarab
rare mural
#

UIManager only cares that you're a UIElementInterface that you have a .render() method etc, it's only UIElement that cares about this.table

#

i think you're gonna do it tonight

jagged scarab
#

Okey it does not even accept my new class

#

It constantly crash

rare mural
#

always show the code

jagged scarab
#
package com.example;

import zombie.ui.NewWindow;

public class UIViewport
        extends NewWindow {
    //public static UIViewport instance;
    private static int UI_BORDER_SPACING;

    public UIViewport(int n, int n2) {
        super(n, n2, 10, 10, true);
        this.ResizeToFitY = false;
        this.visible = false;
        //instance = this;
        this.width = 300 + UI_BORDER_SPACING;
        this.height = 270;
    }

    @Override
    public void render() {
        //this.DrawTexture(this.BodyOutline, n - 123 + 2, n2 - 302 + 2, this.alpha);
        //this.Hand_L.render();
    }

    @Override
    public void update() {
        if (!this.isVisible()) {
            return;
        }
        super.update();
    }

    static {
        UI_BORDER_SPACING = 10;
    }
}```
#
    @Inject(method = "enter", at = @At("RETURN"), cancellable = false)
    private void enter(CallbackInfo ci) {
        LOGGER.println("The game starts!");
        UIViewport viewport;
        viewport = new UIViewport(10, 10);
        viewport.setTable(LuaManager.platform.newTable());
        UIManagerInvoker.invokeAddUI(viewport);
    }```
#

In fact it crash always now ?

#

I tried to remove everything from my project and it keep crashing

#
WARN : General      f:0, t:1755420752524> AnimationAssetManager.loadCallback  > Failed to load asset: AssetPath{ "bob/bob_bandagelowerbody.x.loomhash" }
WARN : General      f:0, t:1755420752580> AnimationAssetManager.loadCallback  > Failed to load asset: AssetPath{ "bob/bob_bandagerightarm.x.loomhash" }
WARN : General      f:0, t:1755420752580> AnimationAssetManager.loadCallback  > Failed to load asset: AssetPath{ "bob/bob_bandagerightleg.x.loomhash" }
LOG  : General      f:0, t:1755420752594> SandboxOptions.load() end
LOG  : General      f:0, t:1755420752594> ItemPickerJava.Parse() start

Is the last lines of log before the game crash

rare mural
#

dunno

jagged scarab
#

It's not due to my code apparently help me

#

how the fuck I'm I supposed to develop my mod

rare mural
#

hehe not sure what advice to give, maybe aoqia does?

jagged scarab
#

Game broke by itself it's lovely

#

How can I reset the cached game?

#

Just by deleting the run/ folder?

floral sluice
#

ye

floral sluice
jagged scarab
#

I didn't modify the game itself

#

And I dunno how to reset the game to an anterior working one

#

Cause it brokes itself

#

Yesterday it worked as a charm and now it crashes constantly and I didnt touch anything

#

How the fuck this can append in a deterministic machine?

#

Bugs and corruption don't grow in the night like weed

floral sluice
#

You can verify your game files and delete the leaf-loom gradle cache if you really want

floral sluice
jagged scarab
floral sluice
#

I explained most of this ages ago

floral sluice
#

You're starting off the first introduction of leaf to you with a time consuming project idea, even more so than the already complex mods like NPCs and the like, so it's no wonder you're having issues. Most of the issues you're having aren't even with leaf but just writing code for the game

#

Barring that first issue that was some unexplained shit with NIO file channels

jagged scarab
#

I just need to learn and get used to java/leaf/mixin modding

#

But this issue is not due to my code

jagged scarab
floral sluice
#

I fucking knew it was going to be a bandaid fix

#

it's because of the option I added yesterday to force loom attribute files

#

the game's trying to parse those as animations and some other shit

jagged scarab
floral sluice
#

im not quite sure what to do with this

#

because literally every other person on a windows machine (and even people on Linux**) didn't have this issue with extended file attributes

#

and even only 1 person in Fabric had this issue

jagged scarab
#

gradlew.bat genSource failed because Intellij is open (?)

#

The error do not come from the sources......

#

It's the game and there is no clue to debug

#

apparently it works now after genSource wich failed

#
STACK TRACE
-----------------------------------------
function: updateTooltip -- file: ISScrollingListBox.lua line # 375 | Vanilla
function: prerender -- file: ISScrollingListBox.lua line # 520 | Vanilla

ERROR: General      f:73, t:1755425748504> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: attempted index: isMouseOver of non-table: com.example.UIViewport@3e67dec8 at KahluaThread.tableget(KahluaThread.java:1530).
    Stack trace:
        knot//se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1530)
        knot//se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:502)
        knot//se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:174)
        knot//se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1826)
        knot//se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1668)
        knot//se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:38)
        knot//zombie.ui.UIElement.render(UIElement.java:1990)
#

What should I add to my UIViewport class?
attempted index: isMouseOver of non-table: com.example.UIViewport@3e67dec8

floral sluice
#

idk, see what sets isMouseOver

#

oh wait, doesnt that mean the table itself is null?

#

anyway, im not sure, I've never tried doing what youre doing before

jagged scarab
floral sluice
#

It's expecting a lua function I think?

#

If you create a java function but don't add it to the lua table, it won't exist from the lua context

#

Most people do UI in lua lol (including the game)

jagged scarab
#

how to add to the LUA table? The patch does not qwork

#

I just forgot
this.visible = true;

valid nova
#

Yea why are you doing Lua UI inside Java ๐Ÿ˜…

jagged scarab
#

Now it display but I can't get rid of the errors

valid nova
#

Combine both instead if you need to do Lua UI alongside custom Java stuff I think

#

Wait isMouveOver returns an int ?

jagged scarab
#

idk

#

I tried a random add

valid nova
#

But yea I really really don't think you should be doing an Lua UI stuff inside the Java

#

This is going to seriously limit modding capabilities of your mod, especially since you're forced to use Lua functions anyway, so simply define them in the Lua

#

For Java specific UI, you don't use the Lua UI anyway, so no reasons to do Lua UI inside the Java, unless you have specific limitations I suppose like not being able to expose your custom Java stuff to the Lua ?

floral sluice
#

The point I want to get across to people is to use Java to enhance the experience of mod making in Lua mainly.

#

Obviously doing stuff in Java is a no brainer when it comes to performance, but for example with @dull stirrup and the NPC mod. They could add the NPC logic in Java, and then control certain things in Lua, to possibly allow for custom NPC implementations by other mods. Exposing NPC logic such as pathfinding and emotion state for example

#

It's not meant to be a "do everything in Java" unless you don't need to interact with the end user who writes Lua mods

#

Though it depends on what type of mod you are making

jagged scarab
valid nova
#

Native Java stuff most likely due to how performance heavy it'll get

jagged scarab
#
@Override
    public void render() {
        this.DrawTexture(this.viewport, 0, 0, 0);
    }

How can I call the super method render?

super.render();
```?
floral sluice
#

I'm going to paste this here for you to read

#

To start modding Minecraft using Fabric, it's strongly recommended to know Java.
Minecraft, in its codebase, and mods, using Fabric API, use more advanced Java concepts like lambdas, generics and polymorphism.
If you don't know all of these concepts, you may have some difficulties modding.

Here are some online resources that will help learning Java
JetBrains Academy (free online course): https://www.jetbrains.com/academy/
Codecademy (free online course): https://www.codecademy.com/learn/learn-java
University of Helsinki (free online course): https://java-programming.mooc.fi/
Basic Java Tutorials: https://docs.oracle.com/javase/tutorial/
Introduction to Programming using Java by David J. Eck (free online textbook): http://math.hws.edu/javanotes/

#

This is from Fabric's helper discord bot, but it applies to leaf too

rare mural
#

(then add an instance of this new class to UIManager with AddUI)

jagged scarab
rare mural
#

you're totally confused

#

oh sorry my bad I misread the code

#

it's 7AM I've been up all night

#

you'd have to share more of the code

jagged scarab
#

And adapt?

rare mural
#

change the .setParent method first

#

actually

#

you can't really support that stuff

#

you'll just have to delete anything involving other uiElements because they wont really be usable with your custom windowing stuff

#

but that's OK because you don't really need child ui elements because you're just gonna draw textures to your square during render

#

yeah?

rare mural
#

nah

jagged scarab
rare mural
#

we're not trying to inherit all of UIElement's stuff, it uses lua tables and other stuff

#

he just wants the part of UIElement that makes it a valid UIElementInterface implementation

#

so it can be passed to UIManager.AddUI and he implements totally custom .render() method

#

(instead of the stuff UIElement does to render child nodes, etc)

valid nova
#

Didn't follow the whole thing sorry

rare mural
#

np catching ya up ๐Ÿ™‚

#

@jagged scarab basically you need all the stuff from UIElement that you also see on UIElementInterface

#

at minimum

#

most everything else from UIElement can be tossed away

jagged scarab
#

Ok so AddChild and his friend methods implementing UIElement goes to trash?

rare mural
#

yeaha because that's related to UIElement's support for nesting child elements and stuff

jagged scarab
#
    public void bringToTop() {
        UIManager.pushToTop(this);
        if (this.Parent != null) {
            this.Parent.addBringToTop(this);
        }
    }```
But these ?
`'pushToTop(zombie.ui.UIElementInterface)' is not public in 'zombie.ui.UIManager'. Cannot be accessed from outside package`
#

Okay I remove this....

public zombie.ui.UIElement Parent = null;
rare mural
#

Is bringToTop in UIElementInterface?

jagged scarab
#

no

jagged scarab
#

What to do with the render function? It does not display anything

rare mural
#

you'll need to implement it all yourself

#

probably with SpriteRendrerer

jagged scarab
#

yes but

#

there is no window frame nothing

rare mural
#

right, it's all on you

jagged scarab
#

But I kept the original render function

#

So why it does not display

rare mural
#

you're gonna delete what's inside

#

because it has no children etc

#

this is UIElement not UIWindow

jagged scarab
#
public void render() {
        Object object;
        Object object2;
        if (!this.enabled) {
            return;
        }
        if (!this.isVisible().booleanValue()) {
            return;
        }
        if (this.getTable() != null && (object2 = UIManager.tableget(this.table, "prerender")) != null) {
            try {
                LuaManager.caller.pcallvoid(UIManager.getDefaultThread(), object2, (Object)this.table);
            }
            catch (Exception exception) {
                boolean bl = false;
            }
        }
        for (int i = 0; i < this.getControls().size(); ++i) {
            this.getControls().get(i).render();
        }
        if (this.getTable() != null && (object = UIManager.tableget(this.table, "render")) != null) {
            LuaManager.caller.pcallvoid(UIManager.getDefaultThread(), object, (Object)this.table);
        }
        if (Core.bDebug && DebugOptions.instance.UIRenderOutline.getValue()) {
            if (this.table != null && "ISScrollingListBox".equals(UIManager.tableget(this.table, "Type"))) {
                this.repaintStencilRect(0.0, 0.0, (int)this.width, (int)this.height);
            }
            Double d = -this.getXScroll().doubleValue();
            Double d2 = -this.getYScroll().doubleValue();
            double d3 = 1.0;
            if (this.isMouseOver().booleanValue()) {
                d3 = 0.0;
            }
            double d4 = this.maxDrawHeight == -1 ? (double)this.height : (double)this.maxDrawHeight;
            this.DrawTextureScaledColor(null, d, d2, 1.0, d4, d3, 1.0, 1.0, 0.5);
            this.DrawTextureScaledColor(null, d + 1.0, d2, (double)this.width - 2.0, 1.0, d3, 1.0, 1.0, 0.5);
            this.DrawTextureScaledColor(null, d + (double)this.width - 1.0, d2, 1.0, d4, d3, 1.0, 1.0, 0.5);
            this.DrawTextureScaledColor(null, d + 1.0, d2 + d4 - 1.0, (double)this.width - 2.0, 1.0, d3, 1.0, 1.0, 0.5);
        }
    }
rare mural
#

you added an instance of this to UIManager.AddUI?

jagged scarab
#

yes

rare mural
#

well read the code

#

it doesn't render a window

jagged scarab
#
    @Inject(method = "enter", at = @At("RETURN"), cancellable = false)
    private void enter(CallbackInfo ci) {
        LOGGER.println("The game starts!");
        UIViewport viewport;
        viewport = new UIViewport(300, 280);
        viewport.setTable(LuaManager.platform.newTable());
        UIManagerInvoker.invokeAddUI(viewport);
    }
jagged scarab
rare mural
#

you don't need to do setTable

#

you're deleting that stuff

jagged scarab
#

ok

rare mural
#

the last block in the render function

#

i think draws a square around the dimensions of the element

jagged scarab
rare mural
#

just search for it

#

it and uses

#

you gotta up your search game

#

look at this part:

if (Core.bDebug && DebugOptions.instance.UIRenderOutline.getValue()) {
            if (this.table != null && "ISScrollingListBox".equals(UIManager.tableget(this.table, "Type"))) {
                this.repaintStencilRect(0.0, 0.0, (int)this.width, (int)this.height);
            }
            Double d = -this.getXScroll().doubleValue();
            Double d2 = -this.getYScroll().doubleValue();
            double d3 = 1.0;
            if (this.isMouseOver().booleanValue()) {
                d3 = 0.0;
            }
            double d4 = this.maxDrawHeight == -1 ? (double)this.height : (double)this.maxDrawHeight;
            this.DrawTextureScaledColor(null, d, d2, 1.0, d4, d3, 1.0, 1.0, 0.5);
            this.DrawTextureScaledColor(null, d + 1.0, d2, (double)this.width - 2.0, 1.0, d3, 1.0, 1.0, 0.5);
            this.DrawTextureScaledColor(null, d + (double)this.width - 1.0, d2, 1.0, d4, d3, 1.0, 1.0, 0.5);
            this.DrawTextureScaledColor(null, d + 1.0, d2 + d4 - 1.0, (double)this.width - 2.0, 1.0, d3, 1.0, 1.0, 0.5);
        }
#

if you remove the if

#

it should run all that code

#

remove the bit at the start about this.table and stuff

jagged scarab
rare mural
#

and everything else should result in a square being drawn

jagged scarab
#

cool

rare mural
#

did it work?

jagged scarab
rare mural
#

remove this part

            if (this.table != null && "ISScrollingListBox".equals(UIManager.tableget(this.table, "Type"))) {
                this.repaintStencilRect(0.0, 0.0, (int)this.width, (int)this.height);
            }
#

since we dont' (or wont) have this .table

jagged scarab
#

I kept the call

#

?

rare mural
#

eh it might work

#

probably not

#

just remove that part too

#

and restart

jagged scarab
#

ok ok

#

I'm trying

#

(5 minutes later ....)

rare mural
#

we need a mod that has an empty map

#

that's super tiny

#

load instantly

jagged scarab
#

you mean to test faster ?

rare mural
#

yeah

jagged scarab
#

it works

rare mural
#

๐Ÿ™‚

jagged scarab
#

a white 300*300 square appeared

#

just the frame

rare mural
#

nice preserverence

#

@floral sluice ^

jagged scarab
#
this.DrawTextureScaledColor(null, d, d2, 1.0, d4, d3, 1.0, 1.0, 0.5);

I must understand the drawing methods

rare mural
#

it's a method on your class

floral sluice
rare mural
#

he got the custom java ui rendering

floral sluice
#

nice

rare mural
#
    public void DrawTextureScaled(Texture tex, double _x, double _y, double _width, double _height, double alpha) {
        if (this.isVisible()) {
            double double0 = _x + this.getAbsoluteX();
            double double1 = _y + this.getAbsoluteY();
            SpriteRenderer.instance
                .renderi(tex, (int)(double0 + this.xScroll), (int)(double1 + this.yScroll), (int)_width, (int)_height, 1.0F, 1.0F, 1.0F, (float)alpha, null);
        }
    }

@jagged scarab

jagged scarab
#

thank you

#

I need to implement a Texture viewport; (?)

rare mural
#

i'm just showing you the method

#

look at SpriteRenderer to see what it supports

#

but yeah you'll probably need to render into a texture and then blitting that to your window

#

how making the texture will work

#

if you end up having to make the texture on the cpu it'll be very very slow

jagged scarab
#

alpha must be 1 ?

#

i dont remember

rare mural
#

alpha 1 just means fully opaque

#

not gonna lie this is probably not the way to go

#

you're probably gonna want to write a shader

#

but honestly you're getting to the point where you're on your own XD

jagged scarab
#
viewport = new Texture(w, h, 1);
...
this.DrawTextureScaled(this.viewport, 0, 0, (double)this.width, (double)this.height, 1);
rare mural
#

no

#

what are you trying to do???

#

the view port is already getting rendered

jagged scarab
#

It's the inner viewport/canva

#

Texture is not the thing to do?

rare mural
#

it wont be efficient to manipulate a texture and then blit it

#

you have to start thinking about how you actually want to render

#

like what do you want to see on screen

#

and the logic for drawing it

#

i don't mean texture vs shader i mean like what you visually wanna see and how will the viewport/rendering work

#

depending on that decision you chose cpu textures or gpu shaders

#

if you are making like a 2D tile-based game, then cpu textures are fine

#

if you're trying to make a low res raytracer, you might get away with CPU

#

anything more than that you're gonna want to use a shader

jagged scarab
#

Okay so I replace Texture by shader

rare mural
#

no idea how shaders are used

rare mural
#

it wouldn't

#

the texture has no data

jagged scarab
#

How to blit a Shader object

#

And how to manipulate it?

#
m_floorRenderShader = new Shader("floorTile");

in IsoCell.java interesting

#

Can I use IndieGL.StartShader withoud doing a new Mixin class?

#

Does nothing

#

How to fill up a Shader ?

#

I must create a Texture to edit the Shader? How to access it fast?

#
private Texture m_tex;

Shaders hold Texture. Why I should use a Shader instead of Texture so?

#

Can I access the SpriteRenderer without Mixin class?

floral sluice
#

reading opengl docs will help you here

jagged scarab
#
SpriteRenderer.instance.render(this.viewport2,
                0,//d13 += this.getAbsoluteX() + d,
                0,//d14 += this.getAbsoluteY() + d2,
                this.width,//d15 += this.getAbsoluteX() + d,
                this.height,//d16 += this.getAbsoluteY() + d2,
                this.width,//d17 += this.getAbsoluteX() + d,
                this.height,//d18 += this.getAbsoluteY() + d2,
                this.width,//d19 += this.getAbsoluteX() + d,
                this.height,//d20 += this.getAbsoluteY() + d2,
                0,//(float)d4,
                0,//(float)d5,
                0,//(float)d6,
                0,//(float)d7,
                0,//(float)d4,
                0,//(float)d5,
                0,//(float)d6,
                0,//(float)d7,
                0,//(float)d4,
                0,//(float)d5,
                0,//(float)d6,
                0,//(float)d7,
                0,//(float)d4,
                0,//(float)d5,
                0,//(float)d6,
                0,//(float)d7,
                null);

Pain

#

Also not working

#

What is the use of all thoses parameters?

#

If your function have +8 argument it's a design issue...

floral sluice
#

you'll find that often in the code

jagged scarab
#

How do you edit Textures ?

#

It doesn't display anything

jagged scarab
#

I'm trying to

viewport2.setData(byteBuffer); // <---- GAME CRASH

And in render

this.DrawTexture(this.viewport2, 0.0, 0.0, 1);

But the game crash

#
viewport2 = new Texture(w, h, "3dviewport", 0);
        viewport2.setWidth(w);
        viewport2.setHeight(h);
        ByteBuffer byteBuffer = ByteBuffer.allocate(4 * (w * h));
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                int index = (i * w + j) * 4;
                if (i > h / 2) {
                    byteBuffer.put(index, (byte)255);
                    byteBuffer.put(index + 1, (byte)0);
                    byteBuffer.put(index + 2, (byte)0);
                    byteBuffer.put(index + 3, (byte)255);
                }
                else
                {
                    byteBuffer.put(index, (byte)255);
                    byteBuffer.put(index + 1, (byte)255);
                    byteBuffer.put(index + 2, (byte)255);
                    byteBuffer.put(index + 3, (byte)255);
                }
            }
        }
#

Assuming it's RGBA ?

jagged scarab
jagged scarab
#
        ByteBuffer byteBuffer = MemoryUtil.memAlloc((int)(w * h * 4));
        for (int i = 0; i < w * h * 4; ++i) {
            byteBuffer.put((byte)-1);
        }
        byteBuffer.flip();
        GL11.glTexImage2D((int)3553, (int)0, (int)6408, w, h, (int)0, (int)6408, (int)5121, (ByteBuffer)byteBuffer);
        MemoryUtil.memFree((ByteBuffer)byteBuffer);

I was almost right. But the game use flip and GL11...

#

Same code still crashing ๐Ÿคก

#

This line crash

GL11.glTexImage2D((int)3553, (int)0, (int)6408, w, h, (int)0, (int)6408, (int)5121, (ByteBuffer)byteBuffer);
#

ChatGPT says OpenGL must be initialized but the game already did (?)

#
        GLFW.glfwInit(); // Do not prevent the crash
        //GL.createCapabilities(); // Black screen after loading. Produce Exception

How the fuck I'm I supposed to use OpenGL as the game does?

rare mural
#

@verbal panther has been doing shader stuff, maybe he can help

jagged scarab
#
ERROR: General      f:0, t:1755501083558> ExceptionLogger.logException> Exception thrown
    java.lang.IllegalStateException: There is no OpenGL context current in the current thread. at GL.createCapabilities(GL.java:429).
    Stack trace:
        knot//org.lwjgl.opengl.GL.createCapabilities(GL.java:429)
        knot//org.lwjgl.opengl.GL.createCapabilities(GL.java:358)
        knot//org.lwjgl.opengl.GL.createCapabilities(GL.java:342)
        knot//com.example.UIViewport.<init>(UIViewport.java:130)
        knot//zombie.gameStates.IngameState.handler$zza000$modid$enter(IngameState.java:1928)
        knot//zombie.gameStates.IngameState.enter(IngameState.java:846)
        knot//zombie.gameStates.GameStateMachine.update(GameStateMachine.java:133)
        knot//zombie.GameWindow.logic(GameWindow.java:382)
        knot//zombie.GameWindow.frameStep(GameWindow.java:916)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)
#

No GL context

#

That's probably why

#

The game never call glfwMakeContextCurrent

#

Where the fuck it init OpenglContext

#

It uses

Display.getWindow()

But the Display class is not in the project or Java native

#

Okay intellij imports it

#
long window = Display.getWindow();
GLFW.glfwMakeContextCurrent(window); // <------- Exception
LOG  : General      f:0, t:1755502081932> [LWJGL] GLFW_PLATFORM_ERROR error
    Description : WGL: Failed to make context current: La ressource demandรฉe est en cours dโ€™utilisation. 
    Stacktrace  :
        knot//org.lwjgl.glfw.GLFW.glfwMakeContextCurrent(GLFW.java:5186)
        knot//com.example.UIViewport.<init>(UIViewport.java:133)
        knot//zombie.gameStates.IngameState.handler$zza000$modid$enter(IngameState.java:1928)
        knot//zombie.gameStates.IngameState.enter(IngameState.java:846)
        knot//zombie.gameStates.GameStateMachine.update(GameStateMachine.java:133)
        knot//zombie.GameWindow.logic(GameWindow.java:382)
        knot//zombie.GameWindow.frameStep(GameWindow.java:916)
        knot//zombie.GameWindow.mainThreadStep(GameWindow.java:642)
        knot//zombie.MainThread.mainLoop(MainThread.java:76)
        java.base/java.lang.Thread.run(Thread.java:840)

OpenGL already initialized

#

@Jab can you help me please?

#
System.out.println("CONTEXT = " + GLFW.glfwGetCurrentContext());

Prints

CONTEXT = 0

But still, aside from the fact that there is no context,

WGL: Failed to make context current: The requested resource is currently in use.
fresh nexus
#

How much software do I need to install to get working with this?

#

Iv no idea about compiling/decompiling java..

floral sluice
#

it is recommended to have at least a basic understanding of Java and mixin to use

rare mural
#

Black Moons has a good head and is motivated

#

So I think we can help him out a little more. I'm sure he can use the internet to learn Java and Mixin as he goes but we can help him over hurdles

#

Maybe the example mod configuration does that automagically, I can't remember. @floral sluice

floral sluice
#

does what

rare mural
#

@floral sluice does the example mod configuration automatically install leaf-loader?

#

or do you need to do that explicitly yourself

floral sluice
#

yes it does, without it you wouldn't be able to load the game

rare mural
#

I think the order I did things in was:

  • used steamcmd to install an extra copy of zomboid 42 in a custom location
  • use leaf-installer to install leaf-loader into that zomboid
  • set the environment variable to tell the example mod config where my zomboid was
  • clone the example mod, edit that one configuration file to tell it to use the version of something for zomboid 42
  • then gradle sync

if all is well at that point you're probably good to go

rare mural
#

@fresh nexus also make sure you use IntelliJ IDEA

#

will make everything much smoother

floral sluice
#

read the pinned messages in this thread

#

theres not much but its somethign

rare mural
#

Ah yes, make sure to install the minecraft idea plugin, it makes using Mixin a lot nicer

#

Eventually I can show you how to get hotswapping working, so you don't have to restart the game after changing your code

fresh nexus
#

Soo few questions before I get started...

rare mural
#

i bet

fresh nexus
#

Will people need to 'manually install' my mod? (or just 'leaf' or whatever?)

rare mural
#

People will indeed need to install leaf

#

The goal is that leaf becomes so valuable (and easy to use, make java mods in) that it's just a thing you do

#

the leaf installer is basic now

fresh nexus
#

How likely is my mod to break next B42 update?

rare mural
#

but it can be made nicer

floral sluice
#

it's all basically dependent on TIS

rare mural
#

exactly

#

same with the lua api

#

it's no different

fresh nexus
#

Ok, but its not guarenteed to break because of some annoying obfusicated api functions changing every single version right?

rare mural
#

nope

fresh nexus
#

(ala minecraft IIRC?)

floral sluice
#

Though Java is more likely to break compared to Lua purely because they consider Lua when changing method names but not really as much for Java. But it's not like a given statistic

floral sluice
rare mural
#

Java is like an internal implementation detail, yeah

fresh nexus
#

Iv already got an LUA functional 'torque boost'...

floral sluice
#

Also Fabric has intermediary mapping layer that gets rid of most of the hassle with obfuscation. Leaf has that stripped out because the game isn't obfuscated, so there's no need for it

rare mural
#

Then again, lua is their scripting language, so you imagine that as the game matures, the Java will change less, and the lua more

fresh nexus
rare mural
#

doc is trying to write a custom 3D renderer for the game lol

fresh nexus
#

And then maybe I'll reproduce my summer car in PZ.

rare mural
#

If you get a handle on Leaf modding you'll be able to do a lot

#

And by using it you can help us (well aoqia) figure out how to make it better

fresh nexus
#

I mean I can already do most of it in LUA

#

(Sure would be nice if horsepower worked in forward and not just reverse..)

rare mural
#

@floral sluice It'd be kinda crazy if Leaf exposed a lua API that used Mixin under the hood, allowing Lua modders to effectively inject lua closures in the same places, etc that Mixin allows for

fresh nexus
#

Still kinda sad that for as bad as PZ's vehicle code is, im pretty sure the transmission in snowrunner is even worse ๐Ÿ˜›

rare mural
#

though I guess it's not a realistic idea because of how Mixin is annotation based, etc. It's not an imperative patching API.

#

I guess the other way is to just hook everything with Mixin, then build an API ontop of all those fixed extension points.

#

Not as flexible but, whatyagondo

floral sluice
fresh nexus
#

so, since PZ is not obfusicated, will I be able to see a rather clean version of the java source?

rare mural
#

we'd have to make our own mixin-like thing using ASM (bytecode library) directly

floral sluice
#

As far as I know about mixin, it's happens at a certain stage where mixins get put in-place into classes and then once the mixin stage is done then it doesn't do any more class modifications. you could maybe expose like bytecode patching but something like this is best suited for java mod

fresh nexus
#

And can I just copy that source into my own mod and start making changes, and override the java function with my own?

rare mural
#

no

floral sluice
#

Class, method and field names are kept original human-readable names. Locals don't get names stored in compiled Java code, so they will be generic like string0 or int4

rare mural
#

well, kinda, but it's more involved than just copy pasting

#

I'm working on a tool to help us share local-variable renames so that it can improve over time

floral sluice
rare mural
#

but it's already quite easy to understand

#

a surgeon yeah lol

fresh nexus
rare mural
#

That's fine, that's something Mixin is good at

floral sluice
#

are you doing like an entire vehicle overhaul thing?

rare mural
#

You inject at a point and completely take over a method, ignoring the original code

fresh nexus
#

And by that I mean Iv already done one in LUA, but the fact I can't edit the engine noise annoys me.

floral sluice
#

you would basically redirect the original methods to your custom implementation

rare mural
#

yup, and you can cut it as high-level or low-level as you want

#

with Mixin you can literally hook anywhere, even in the middle of methods. O_O

fresh nexus
#

Cool cool... So.. steamcmd for another install of PZ...

rare mural
#

that's what I did to just keep it clean

fresh nexus
#

Oh?

#

I assume I can just steam validate to restore PZ if needed?

rare mural
#

eh just use steamcmd it's one command

#

then you don't have to worry about anything

fresh nexus
#

ok but what command is it?

rare mural
#

๐Ÿ™„

#

chatgpt what is the steamcmd command to install pz

#

hehe

fresh nexus
#

I don't chatgpt.

rare mural
#

ยฏ_(ใƒ„)_/ยฏ

#

a search engine that you can ask clarifying questions of

#

pretty op

verbal panther
rare mural
#

@verbal panther spill the beans

verbal panther
#

You're not going to be doing any render code execution outside the render context / render thread.

#

I'd go learn how to write a basic LWJGL application / demo game before trying to modify something as built / complicated as PZ's render thread / context.

#

In my case I've done several, specifically with LWJGL however it looks like this person hasn't or hasn't messed with LWJGL much.

floral sluice
#

Leaf doesn't modify any game files, even in dev

fresh nexus
#

I dunno, idlework said to.

rare mural
#

It's what I did before I knew about run/

floral sluice
#

You can have a folder of different game versions, that what I have, but only because I need to test frequently between stable and unstable

fresh nexus
#

im just gonna run unstable..

rare mural
#

using steamcmd to get games is easy so i figured why not ยฏ_(ใƒ„)_/ยฏ

fresh nexus
#

...

floral sluice
#

that's what the steam client is for?

fresh nexus
#

"its so easy, I can't even tell you how to do it!" isn't instilling confidence.

rare mural
#

dude you haven't found it yet??

floral sluice
#

I believe there was a valve wiki page on it or something

rare mural
#

steamcmd.exe

#

login anonymous

#

force_install_dir ./wherever_you_want

#

app_update 380870 validate

floral sluice
#

but I don't even know why you would use steamcmd over steam client

rare mural
#

there ya go

#

because it's easier to just put a game at a specific place

floral sluice
#

steamcmd is doing the exact same thing as installing your game does. and if you care about storage space, it'll make for 3 versions of the game

rare mural
#

app_update 380870 -beta unstable validate

#

if you want 42

floral sluice
fresh nexus
rare mural
#

hehe

floral sluice
#

but for 99% of people the plug and play solution of auto detecting the game is good

rare mural
#

i'm an old man obssesed with automation

#

too old to change ๐Ÿ˜ญ

fresh nexus
#

How is that automation vs clicking INSTALL?

rare mural
#

i already had pz installed, that wasn't the issue

fresh nexus
#

thats manualmation.

rare mural
#

it's "this thing doesn't touch anything else so i don't have to think about that class of problems"

floral sluice
fresh nexus
#

Yea I just want 42, the rest of you PZ players are outta luck. Nothing can fix the mess that is vehicles in PZ41 MP

rare mural
#

lol

floral sluice
#

although most games are just 1 verify game files away from fixing random issues, like render engine guy who had pz's steam app id file set to a completely different game somehow

rare mural
#

probably asked gpt for it and it hallucinated

#

lol

fresh nexus
jagged scarab
rare mural
#

@verbal panther got anymore you can say?

verbal panther
fresh nexus
#

assuming I have.. 0 software for java in particular.

verbal panther
#

The code isn't being executed inside of the render context.

#

It's that simple.

rare mural
#

GL programming in PZ, maybe it'd be cool if you could show a minimal example that draws a square viewport with a shader that just draws a triangle

jagged scarab
rare mural
verbal panther
#

You won't be able to draw the world in the world layer without modifying the Java code.

fresh nexus
rare mural
#

We can look at it, and go research the related info

rare mural
#

hehe

verbal panther
#

It'd take a bit of time to do any of that and I have active projects + a commission to work on atm so I couldn't be helpful.

jagged scarab
#

Sorry for not responding Discord didn't load your messages

rare mural
#

While doc's eventual goals are pretty grand, I think we're happy to just do baby's first opengl triangle in pz for now

#

well, alright no worries man

#

thanks for the context tip at least hehe

verbal panther
#

Sure. I can tell you what's wrong but a guide? Nah.

#

If PZ was my actual job then hell yeah

rare mural
#

just a little code example is what i had in mind

#

if your gui stuff open source / on github @verbal panther ?

jagged scarab
rare mural
#

Maybe we could look at that stuff

verbal panther
rare mural
#

a man of the lord

#

๐Ÿ™

verbal panther
#

Just not some Java but yeah all Lua and some Java is.

valid nova
# rare mural app_update 380870 validate

Didn't think about using steamcmd to install two versions of the game. Tho the app ID you use here is not PZ. Unless you're not talking about pz ? I haven't read the full thing

rare mural
#

(i asked gpt for the commands so i'm not surprised the id is wrong lol)

valid nova
#

Bruh

fresh nexus
#

Anndd this is why I don't chatgpt.

#

shakes head

rare mural
#

i even said it above

verbal panther
#

If you use AI then I can't help you. It'll break.

valid nova
#

But I'll look into it and add it to the steamcmd wiki page sibce that can be used to install both B41 and B42

verbal panther
#

But good luck.

fresh nexus
rare mural
#

....

valid nova
# rare mural i even said it above

Yea I didn't read the full chat I was looking and saw you discussed steacmd so I got curious since I played a bit with it and made a wiki page about it

fresh nexus
#

will get incorrect AI awnsers with no notice that they are AI generated or incorrect.

rare mural
#

I literally joked about it!

valid nova
#

I don't think idle here is stupid here and doesn't know about the risks of ai

rare mural
#

I've been doing software engineering for 25 years professionally, but I don't need to give you help that's fine

#

Having run those steamcmds many times, I knew they were right.

fresh nexus
#

except for the app ID, that would have caused me to download some random game...

#

illegally..

rare mural
#

Getting the ID wrong was inevitable but an easy thing to look up

#

lol you can't just steamcmd any game

#

to that point, you need to login as yourself not anonymous which is only gonna work for dedicated servers and stuff

jagged scarab
#

I cannot

viewport2.setData(byteBuffer);

Of my Texture

#

It crashes

fresh nexus
#

So yea, if anyone has a non AI generated guide on how to use leaf (getting that example mod to compile or whatever), without extra steps that I don't need to do if im not trying to develope for multiple versions of PZ, im interested.

#

Else i'll just go back to my LUA modding.

jagged scarab
#

@verbal panther Why Texture::getWhite method have a GL context and not my function?

#

There is literally no keyword referring to the cretation or fetching of a GL context

floral sluice
jagged scarab
#

But still the game accepts without crashing the call GL11.glTexImage2D

floral sluice
#

0 is shared resources depot, 1 2 3 are linux, mac, windows

#

same with 108601 (1..4) with PZ game client

floral sluice
jagged scarab
#

Why the fuck drawing a square is so complicated?

floral sluice
#

did warn you ๐Ÿ˜„

jagged scarab
#

Only a Texture class

#

With no getter or setters

#

Well there is setData method for Texture

#

But it crashes

#

And when you read you see a bunch of stupid variables but not the actual data is absent

valid nova
#

If it was this easy

jagged scarab
#

Where this stupid game stores pixels ? If not in Texture?

fresh nexus
#

shrugs

valid nova
rare mural
#

He's trying to figure out how to manipulate PZ Textures

jagged scarab
#
    public static final HashSet<String> nullTextures = new HashSet();// Unrealated
    private static final long serialVersionUID = 7472363451408935314L;// Unrealated
    private static final ObjectRenderEffects objRen = ObjectRenderEffects.alloc();// Maybe ?
    public static int BindCount = 0;// Unrealated
    public static boolean bDoingQuad = false;// Unrealated
    public static float lr;// Unrealated
    public static float lg;// Unrealated
    public static float lb;// Unrealated
    public static float la;// Unrealated
    public static int lastlastTextureID;// Unrealated
    public static int totalTextureID;// Unrealated
    private static Texture white;// Unrealated
    private static Texture errorTexture;// Unrealated
    private static Texture mipmap;// Unrealated
    public static int lastTextureID;// Unrealated
    public static boolean WarnFailFindTexture;// Unrealated
    private static final HashMap<String, Texture> textures;// Unrealated
#
    private static final HashMap<String, Texture> s_sharedTextureTable;// Unrealated
    private static final HashMap<Long, Texture> steamAvatarMap;// Unrealated
    public boolean flip = false;// Unrealated
    public float offsetX = 0.0f;// Unrealated
    public float offsetY = 0.0f;// Unrealated
    public boolean bindAlways = false;// Unrealated
    public float xEnd = 1.0f;// Unrealated
    public float yEnd = 1.0f;// Unrealated
    public float xStart = 0.0f;// Unrealated
    public float yStart = 0.0f;// Unrealated
    protected TextureID dataid;// Unrealated
    protected Mask mask;// Unrealated
    protected String name;// Unrealated
    protected boolean solid;// Unrealated
    protected int width;// Unrealated
    protected int height;// Unrealated
    protected int heightOrig;// Unrealated
    protected int widthOrig;// Unrealated
    private int realWidth = 0;// Unrealated
    private int realHeight = 0;// Unrealated
    private boolean destroyed = false;// Unrealated
    private Texture splitIconTex;// Unrealated
    private int splitX = -1;// Unrealated
    private int splitY;// Unrealated
    private int splitW;// Unrealated
    private int splitH;// Unrealated
    protected FileSystem.SubTexture subTexture;// Unrealated
    public TextureAssetParams assetParams;// Unrealated
    private static final ThreadLocal<PNGSize> pngSize;// Unrealated
    public static final AssetType ASSET_TYPE;// Unrealated

The Texture class variables

#

Full of random data

#

Do you see any 32bit element array? Do you see any pixel value?

fresh nexus
#

Testures in openGl are just a 32bit int that references some internal thing for opengl...

#

(at least, in C++)

jagged scarab
#

Oh ObjectRenderEffects do not hold anything

#

That means Texture is just a empty shell

floral sluice
#

eh one number off

floral sluice
rare mural
#

guards!

#

take him to jail!

jagged scarab
#

But when you dig you find nothing

#

You'll find maybe OpenGL calls that are not possible to do anywhere outside because this is not the "Rendering context" @verbal panther

floral sluice
jagged scarab
#

I like magik tricks too because I'm lazy

#

But this magik is too powerful I'm just a developer, not a wizard

rare mural
#

@jagged scarab I think like this:

RenderThread.invokeOnRenderContext(() -> {
    GL11.glTexImage2D(textureTarget, mipmapLevel, internalFormat, width, height, borderWidth, pixelFormat, pixelType, pixelData);
});
#

you pass a lambda/closure to invokeOnRenderContext

#

which I guess runs the closure on the render thread

jagged scarab
#

For example, what's the point of a setWidth method if you cannot access the inner pixels?............. Is it some sort of design pattern do makes thing incomprehensible?..

floral sluice
rare mural
#

I just mean this is how you run stuff on the render thread

floral sluice
#

There's so much info here from just looking simply at the Texture class, I don't know how you could miss this

rare mural
#

but yeah someTexture.render(x, y, renderWidth, renderHeight);

floral sluice
#

Literally in the constructor of TextureID - RenderThread.queueInvokeOnRenderContext(() -> this.createTexture(false));

rare mural
#

I just looked for the first time 5 minutes ago and found it

#

oh you mean doc

floral sluice
#

Like even look at ```java
TextureID.generateHwId(boolean)

jagged scarab
jagged scarab
rare mural
#

@jagged scarab try this

int size = 64;
Texture tex = new Texture(size, size, "whatever", 0);
int bytesPerPixel = 4;
int totalPixels = size * size;
ByteBuffer pixels = ByteBuffer.allocateDirect(totalPixels * bytesPerPixel);
pixels.put(2048, 255);
pixels.flip();
tex.setData(pixels);
tex.render(200, 200, size, size);
#

if it don't work, try using two for-loops to set every pixel

rare mural
#

i'm curious if it'll work

jagged scarab
rare mural
#

mmok

jagged scarab
#

but ill try...

floral sluice
#

dont construct new texture, get it from game files

#

how are you using Texture exactly?

#

like whats the purpose of you using it

rare mural
#

the whole point is to render something custom at realtime

#

like obviously it's not gonna be performant enough for what he needs

floral sluice
#

like an image?

rare mural
#

using the cpu like that

#

but i think he's just demoralized

#

and wants to render literally anything

#

to keep the juices going

#

๐Ÿ˜‚

jagged scarab
#

Yes

#

I just want to render something the optimization part can be fixed later with the right method (maybe @Jab knows)

rare mural
#

once you get one pixel working

#

you can make PZ-Paint

floral sluice
#

if he wants to render an image from the media folder you include, it can be done via

final int flags = 0;
Texture tex = Texture.getSharedTexture("media/path/to/YourTexture.png", flags);
rare mural
#

๐Ÿ˜‚

floral sluice
#

but it wouldn't be doing pixel stuff, that you need to go more internal to do

rare mural
#

yeah rendering images from disk is ezpz

#

i think my snippet might work

#

if setData doesn't inexplicably crash the game

floral sluice
#

But you'd want to extend UIElement probably and override the functions like render.

#

Otherwise it won't display

rare mural
#

nah there's no reason really to go through UIElement

#

we did it already

#

it just calls .render

#

and that ends up just using SpriteRender to draw stuff

#

so just take out the middleman

#

how to do thinnest draw shape to screen

floral sluice
#

essentially, but if you're having issues then that'd be the best place to look

rare mural
#

yeah we got that working already at least

#

can fall back if need but I looked pretty good and UIElement just calls render on its children which potentially override .render to do spriterenderer stuff

#

like UIWindow, etc

#

Ah you know what

#

It looks like you do need to call setData on the render thread

#

so more liek this:

int size = 64;
Texture tex = new Texture(size, size, "whatever", 0);
int bytesPerPixel = 4;
int totalPixels = size * size;
ByteBuffer pixels = ByteBuffer.allocateDirect(totalPixels * bytesPerPixel);
pixels.put(2048, (byte)255);
pixels.flip();

RenderThread.invokeOnRenderContext(() -> {
    tex.setData(pixels);
    tex.render(200, 200, size, size);
});
fresh nexus
jagged scarab
rare mural
#

Though to @floral sluice's point, you'd want the render call to happen each frame

fresh nexus
#

... Hmm, Don't have an IDE or a gradle.. or a loom.

jagged scarab
#

RenderThread.invokeOnRenderContext crashes the game too !

fresh nexus
#

welp, I guess that counts me out.

floral sluice
#

yea I see it UIElement does ```java
SpriteRender.instance.render(Texture, x, y, width, height, r, g, b, a, null);

#

What was the problem with this?

rare mural
#

what do you mean?

#

the goal is to draw custom runtime rendered stuff to screen

floral sluice
#

you only need IDEA, which comes with gradle and loom and everything else

rare mural
#

@floral sluice is your recommendation to use a UIElement just for the benefit of getting your .render called each frame so you don't have to figure out a different way of rendering repeatedly?

fresh nexus
#

And whats the website for 'IDEA' so I don't have to google a very common english word and hope to end up remotely in the correct place and not a malware lookalike site?

floral sluice
rare mural
#

intellij IDEA

dusk pebbleBOT
floral sluice
#

Jetbrains IntelliJ IDEA Community Edition ^

jagged scarab
floral sluice
#

Most likely, the main KahLua thread has it's own render method

fresh nexus
#

I assume community edition?

rare mural
#

Yeah that's what we were dealing with. What I had him do was take UIElement, and scrap all the functionality related to lua, children, etc etc

#

All that was left was the original .render and all we left in there was the debug outline code which we got to render by adding it to the UIManager

#

So it's a nice way to create a class that can be added to UIManager naturally ๐Ÿ™‚

fresh nexus
floral sluice
#

Most UI that was made in Java back then and still a little now, extend UIElement

fresh nexus
#

"you do things, Kinda like I wanna do.. but.. not really. BUT NOW YOU WILL"

floral sluice
#

I think they have some boilerplate still in Lua to make it not die

fresh nexus
#

rips out old code, does code transplant

rare mural
#

I mean you can just implement UIElementInterface, but I didn't feel like guiding through that

#

"delete all the stuff that isn't also in UIElementInterface" was an easy directive to follow hehe

rare mural
#

@jagged scarab so that's what I actually recommend

#

go back to our UIViewport or whatever you called it

#

and put this texture snippet I shared inside the render

#

you can delete that debug drawing code and just keep the new texture code

jagged scarab
# rare mural <@536179643875852294> so that's what I actually recommend

The compiler says

C:\Users\asdsadasd\.gradle\caches\leaf-loom\42.11.0-unstable.30715\dev.aoqia.leaf.yarn.42_11_0_unstable_30715.41.78.16+build.1-v2\mappings.jar: The process cannot access the file because it is being used by another process.

So I'm trying to kill processes but it still won't compile

fresh nexus
#

Clone the repository or use the template feature provided by GitHub. so do I have to clone the repo or can I just download a copy to disk?

fresh nexus
#

.. I did

floral sluice
fresh nexus
#

im talking about the mod template

floral sluice
#

you dont need to clone the installer, nor do you need to actually use it (for dev in IDE)

rare mural
#

the build configuration in the example-mod does it magically

fresh nexus
#

... so I download the example mod as a zip, extract it somewhere anddd...?

#

... why is the open project dialog *.*

jagged scarab
#

I'm deleting the cache.........

fresh nexus
#

iv got literally no idea what file to open

jagged scarab
#

Open directory

#

This directory is the root

fresh nexus
#

.... open directory?

rare mural
#

@jagged scarab look at your dms

fresh nexus
#

Oh. Its one of those file dialogs thats a folder dialog -_-

#

even though it says to open a filename...

#

Hmm, where are the enviroment variables...

floral sluice
#

it's because technically you can open a project just fro ma file

fresh nexus
#

for the LEAF_CLIENT_GAME_PATH = D:\SteamLibrary\steamapps\common\ProjectZomboid thing..

floral sluice
#

if you select and open the build.gradle file

floral sluice
#

search up on google how to set environment variables

#

if you're using the default steam install and it's at the default location, you dont need to do this

fresh nexus
#

.. oh, those enviroment variables...

#

please for the love of god people stop using those...

#

the 'fun' when you.. suddenly run outta space, because your path is like 900000000 long and has 3 compilers with the same damn name in them

floral sluice
#

??? the max path limit assuming its extended is fairly large

#

also they are objectively the best way to handle system-specific configuration

#

I tried having project-specific, but it's no wonder and I knew it wouldn't be good, because people commit their install path to git and then everyone cant build the project.

#

thats why I said it's super easy for most users that have everything default. Most people install their games on the drive Steam is installed (C:) and it auto detects it

#

I did think about parsing the regedit paths of Steam and the vdf files to get PZ game directory, but this is much code for only small benefit (dev environment only), and it's still not even guaranteed to work

fresh nexus
#

.. despite setting the enviroment variable, I still get

#

Client game file 'C:\Program Files (x86)\Steam\steamapps\common\ProjectZomboid\media\AnimSets\player\climbwindow\end.xml' does not exist.

fresh nexus
#

Bonus points when your MMORPG's refuse to let you develope while running your shop in the background because 'omg GCC.exe must be some kinda hacker tool'

#

So any clue what I did wrong?

fresh nexus
floral sluice
#

I won't question why it's at C:\Steam, in any case that should theoretically work

#

make sure you completely shutdown and restart the IDE, environment variables only update after the program is restarted

fresh nexus
#

ah k

floral sluice
#

environment variables are imported once at hte start of a program and they dont change until you restart it

fresh nexus
#

java.io.IOException: Failed to copy file from (C:\Steam\steamapps\common\ProjectZomboid\media\AnimSets\zombie\hitreaction\Shot\ShotChestStepR.xml) to (C:\Users\Black Moons.gradle\caches\leaf-loom\41.78.16\extracted\media\AnimSets\zombie\hitreaction\Shot\ShotChestStepR.xml)

#

(and many more like that)

floral sluice
#

update your game version in the example mod's gradle\libs.versions.toml

fresh nexus
#

... why is it trying to copy to black moons.gradle\ ?

floral sluice
#

leaf-loader to 1.4.1, leaf-loom to 0.6.0 and game version (assuming you're unstable branch) is 42.11.0-unstable.20715

floral sluice
fresh nexus
#

No

#

im saying, that user doesn't exist

#

black moons\ exists, black moons.gradle\ is.. a failure to properly concat paths together

floral sluice
#

I am unsure. It might be an error with spaces in user folder. I've never seen a space personally in a user folder before

fresh nexus
#

Sigh.

floral sluice
#

You can override that by doing GRADLE_HOME environment variable to C:\Users\Black Moons\.gradle

#

or I think that should work at least

#

oop it's GRADLE_USER_HOME

fresh nexus
#

Failed to find zomboid version: 42.11.0-unstable.20715

floral sluice
#

30715, not 20715

#

I mispelt it

#

if only keys weren't right next to each other ๐Ÿ˜ญ

#

also I forgot to mention, I added the clearLoomCache gradle task a version or two ago and forgot to mention it here I think. So here I was telling you to manually delete the cache when you can just run that lol

fresh nexus
#

seems to be spending its time doing things.

floral sluice
#

that will be the game copying

#

it scales based on drive write speed, it will take not too long on a slow SSD, and if you're on a m.2 basically like 3-4 minutes at most. HDD as albion showed me (RIPPP) is like 50 minutes

#

ok like I mentioned 2 days ago, im going to be heavily focusing on everything docs related. It's mainly going to be going towards mod setup and the quirks with leaf. I don't think there is too much to document honestly

#

I do need to update the readme's for loom and loader, but these don't need as much attention as they are mainly for developing leaf and not the user

fresh nexus
#

Ok it seems to be odne without exploding.

#

so.... do I now have a decompiled PZ somewhere for me to look at?

#

(I assume in IDEA?)

floral sluice
#

in IDEA, on the right sidebar I think is where the gradle drawer usually is

#

most of this is on the example mod readme, or it should be

fresh nexus
#

yea, the readme doesn't help at all because it doesn't tell me where on earth of the 1000+ odd buttons this IDE has where to click

floral sluice
#

Well it's generally not IDE specific, you can even run it in the cli via .\gradlew genSources

rare mural
#

yeah the ide has a gradel panel

#

just double click genSources

fresh nexus
floral sluice
#

I should really specify that people have an understanding of this stuff, since not to be harsh but I don't want leaf to be filled up with questions asking about how the IDE or gradle works, since all of this is very accessible with a quick google

floral sluice
fresh nexus
#

It would also help to say leaf->gensources since there is like 10 different tabs to look through on that page

fresh nexus
rare mural
#

gpt, what is .\gradlew

floral sluice
#

Anyone who knows how to use Gradle with IDEA knows that a "leaf" tab would probably suggest something related to the leaf project you're using

floral sluice
rare mural
#

lol i know what it is

floral sluice
#

oh it wasn't a question ๐Ÿ˜ญ

fresh nexus
#

I thought I made that clear already?

floral sluice
#

It'll become a thread less about leaf and more of a general tech support for how to use java...

#

I never intended anyone unexperienced with Java and mixin to use leaf. That is the purpose of leaf, people who are experienced enough make java mods that expose functionality in Lua, so people who know Lua which is far simpler without the hassle of mixin can reap the rewards of Java modding

#

I'm not saying you can't become experienced either, it's just in general feels like a punch in the gut to have people ask more questions that are easily google like how to use their IDE rather than leaf-related questions, in the leaf mod project

fresh nexus
#

Sorry, just no idea where else to even ask.

#

Where does GenSources put the PZ sources?

floral sluice
#

in the loom gradle cache

#

alongside the game files that were copied over

#

more specifically, %GRADLE_USER_HOME%\caches\leaf-loom\decompile

fresh nexus
#

So.. .the .jar's in C:\Users\Black Moons.gradle\caches\leaf-loom\42.11.0-unstable.30715\extracted ?

floral sluice
#

no, that is the game

fresh nexus
#

Oh, decompile

floral sluice
#

zomboidMaven is the folder that contains the final game files that are used by the IDE in dev environment only

fresh nexus
#

its a zip of... randomly named files of text.

#

scratches head...

floral sluice
#

and com.theindiestone is a fake maven prefix I've created because I felt zombie.* was a too broad and possibly conflicting prefix to have in buildscripts. THough, it is still zombie.* in the actual class structure and code

floral sluice
#

If you're trying to read them, you do it through the IDE via search files or control click when you import a class, not through reading the raw decompiled files

#

Though if you really really want to read the decompiled sources externally, they in the zomboidMaven with the suffix -sources.jar

fresh nexus
#

No I want it in the IDE...

#

via search files edit->find->find in files?

floral sluice
#

yes, CTRL+SHIFT+F keybind, search for something

#

if you want to search the name of a class, I believe it's CTRL+N/CTRL+SHIFT+N but I've modified my keymap so im not sure

#

keep in mind that IDEA's default search filters might not search through sources of any kind, so you have to change those

fresh nexus
#

Erm, do I have to extract the zip first?

floral sluice
#

no..

#

you dont have to touch anything in the gradle cache folder at all

fresh nexus
#

trying find in files: C:\Users\Black Moons.gradle\caches\leaf-loom\decompile... getting nothing?

#

for things like 'log' and 'vehicle'

rare mural
#

just do in project, yea?

fresh nexus
#

still nothing?

rare mural
#

dunno i don't have leaf stuff open atm

fresh nexus
#

log only has this: