Porting Java-based mods to Lua
#1
Keep in mind: I am not an expert in either Java or Lua

I came across jnlua: https://code.google.com/p/jnlua/

It claims to be able to access both java and lua functions.

My question is would this be a viable option for using established mods for the proprietary Minecraft Server by doing the following:

1. Installing said java server mods in a separate plugin directory
2. Writing a plugin that is able to call those mods (Think of Forge API)
3. Writing individual lua plugins for those mods to handle the I/O between the server and the java mods
4. Profit????

The only reason I can see that this wouldn't work is that the server uses the standard lua interpreter.

Let me know if this would ever be a possibility or if it sounds like the ramblings of a mad man.

I repeat: I am not an expert in Java or Lua.
Reply
Thanks given by:
#2
In an attempt to test if this theory is indeed possible, I wrote the following short plugin to do one thing: Create a JavaVM and print "Hello, world!" to the screen.

Note: lua5.1.dll has been replaced with jnlua5.1.dll and renamed to access the jnlua functions.

function Initialize(Plugin)
	Plugin:SetName("JavaVM")
	Plugin:SetVersion(1)
	
	-- Hooks
	cPluginManager.AddHook(cPluginManager.HOOK_WORLD_STARTED, initiatejavavm)
  
  function initiatejavavm(javavm)
    javavm = require("javavm")
    javavm.create("-Djava.class.path=jnlua-0.9.6.jar")
    System = java.require("java.lang.System")
    System.out:println("Hello, world!")
    javavm.destroy()
    end
  
	PLUGIN = Plugin -- NOTE: only needed if you want OnDisable() to use GetName() or something like that
	
	-- Command Bindings

	LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
	return true
end

function OnDisable()
	LOG(PLUGIN:GetName() .. " is shutting down...")
end

This plugin gives the following error:

Warn [22:40:00] cPluginManager:AddHook(): bad parameters. Expected
HOOK_TYPE and CallbackFunction, got number, nil, no value. Hook not added.
Warn [22:40:00] Stack trace:
Warn [22:40:00] [C](-1): AddHook
Warn [22:40:00] Plugins/JavaVM/main.lua(8): (no name)
Warn [22:40:00] Stack trace end
[22:40:00] Initialised JavaVM v.1

Since I am lost as to why the AddHook call is not recognizing the CallbackFunction, can someone please point it out to me?
Reply
Thanks given by:
#3
Further edit of the code:

function Initialize(Plugin)
	Plugin:SetName("JavaVM")
	Plugin:SetVersion(1)
	
	-- Hooks
	cPluginManager.AddHook(cPluginManager.HOOK_WORLD_STARTED, initiatejavavm())
  
  function initiatejavavm()
    javavm = require("javavm")
    javavm.create("-Djava.class.path=jnlua-0.9.6.jar")
    System = java.require("java.lang.System")
    System.out:println("Hello, world!")
    javavm.destroy()
    return true
    end
  
	PLUGIN = Plugin -- NOTE: only needed if you want OnDisable() to use GetName() or something like that
	
	-- Command Bindings

	LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
	return true
end

function OnDisable()
	LOG(PLUGIN:GetName() .. " is shutting down...")
end

Produces this error:

Warn [22:58:08] LUA: Plugins/JavaVM/main.lua:8: attempt to call global 'initiatejavavm' (a nil value)
Warn [22:58:08] Stack trace:
Warn [22:58:08] Plugins/JavaVM/main.lua(8): (no name)
Warn [22:58:08] Stack trace end
Warn [22:58:08] Error in plugin JavaVM calling function Initialize()
Warn [22:58:08] Error in plugin JavaVM: Cannot call the Initialize() function. Plugin is temporarily disabled.

Any ideas?
Reply
Thanks given by:
#4
function Initialize(Plugin)
    Plugin:SetName("JavaVM")
    Plugin:SetVersion(1)
     
    -- Hooks
  cPluginManager.AddHook(cPluginManager.HOOK_WORLD_STARTED, function(World)
      javavm = require("javavm")
      javavm.create("-Djava.class.path=jnlua-0.9.6.jar")
      System = java.require("java.lang.System")
      System.out:println("Hello, world!")
      javavm.destroy()
      return true
   end
   
    PLUGIN = Plugin -- NOTE: only needed if you want OnDisable() to use GetName() or something like that
     
    -- Command Bindings
 
    LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
    return true
end
 
function OnDisable()
    LOG(PLUGIN:GetName() .. " is shutting down...")
end
Reply
Thanks given by: Atro
#5
Hello, welcome to the forum.
Unfortunately this will not work. You may be able to create a simple Java VM from within Lua, but the proprietary server mods are not only about Java, they are about accessing functions within the Java server itself (that's why mods are generally not compatible with multiple minecraft versions and need to be updated). That is, the mod doesn't call just system.out.something(), but it also calls minecraft.client.gui.something, and there's just no way of making this work in MCS, simply because the underlying implementation is completely different.

Now, why your simple example didn't work - in Lua you need to first define anything before using it. Lua goes top-to-bottom when parsing your program. In your first attempt (which has the correct form), you were using function "initializejavavm" on line 6, but declaring it on line 8. If you first declared the function and then used it (just move line 6 down after line 15) the error would have gone away and it might have actually worked.
Still, as I said, mods are mostly about being dependent on Java server's API.
Reply
Thanks given by: Atro
#6
Thanks for your reply. At least now I know why my proof-of-concept failed.
On that note, what would be the realistic limitations of introducing plugins based on existing mods for the Java server?

I am new to lua, but I am more than willing to put in some time and effort to port some popular mods if I can.

The reason being that I think MCServer is absolutely the best Minecraft server available and with proper functionality it would definitely gain more traction.

The main complaint that people I have shown it to have had is that they do not enjoy vanilla minecraft.

Which is why I am asking those who are more knowledgeable than myself if I would be wasting my time by dissecting things and re-creating them.

Any advice is appreciated.

Update: I was able to run the proof-of-concept from the first attempt with the changes you mentioned. The Java VM that this project provides does not include lua_pushboolean which would require a lua proxy to pull it from another version. I had fun trying thoughBig Grin
Reply
Thanks given by:
#7
Right now I think the biggest limitation is that there are a zillion requests for plugins and only a handful of people who actually do write plugins. Anyone helping out on the programming front is a big help.

If you have some feedback from people, the best thing to do about it is try to collect it and refine it. Ask for details, what exactly it is that they don't like, try to find out the core of the problem. Only then we will know what to do to improve. They say they don't enjoy vanilla - ask them why, what's better about non-vanilla, what they need to enjoy a server. Try to make them answer questions like "if vanilla had this one feature added to it, would it be what is missing in it for you?" Make them pick one single feature that is the dealbreaker, then we can focus on that.

I'm not sure if dissecting existing mods is the right way to go. For me, programming has always been a slightly different process - first find out what exactly you want to do, try to think about all the possible interactions, what could go wrong, what could go right. Consult others about their ideas, you'd be surprised how often this takes you far away from your original idea to something even more awesome. Then, when you have this vision, start coding. Do small increments, don't try to code everything at once. Implement one small feature at a time, test it, let people test it and give you feedback. Quite often you will find out that things behave slightly different than you anticipated, and you will make changes to your grand plan. But this way you will move forward, and most importantly, if you ever feel tired, someone else can take over because things will be in a reasonably consistent state.
Dissecting existing stuff is only good for example for finding out some fine details, such as, say, exact sizes of mobs, or exact physics constants used, or maximum message length etc.

If you want to start coding, have a look at the plugin request subforum, there are a million ideas there that need refining and then implementing Smile
Reply
Thanks given by: tigerw
#8
(01-13-2015, 06:14 PM)xoft Wrote: Right now I think the biggest limitation is that there are a zillion requests for plugins and only a handful of people who actually do write plugins. Anyone helping out on the programming front is a big help.

If you have some feedback from people, the best thing to do about it is try to collect it and refine it. Ask for details, what exactly it is that they don't like, try to find out the core of the problem. Only then we will know what to do to improve. They say they don't enjoy vanilla - ask them why, what's better about non-vanilla, what they need to enjoy a server. Try to make them answer questions like "if vanilla had this one feature added to it, would it be what is missing in it for you?" Make them pick one single feature that is the dealbreaker, then we can focus on that.

I'm not sure if dissecting existing mods is the right way to go. For me, programming has always been a slightly different process - first find out what exactly you want to do, try to think about all the possible interactions, what could go wrong, what could go right. Consult others about their ideas, you'd be surprised how often this takes you far away from your original idea to something even more awesome. Then, when you have this vision, start coding. Do small increments, don't try to code everything at once. Implement one small feature at a time, test it, let people test it and give you feedback. Quite often you will find out that things behave slightly different than you anticipated, and you will make changes to your grand plan. But this way you will move forward, and most importantly, if you ever feel tired, someone else can take over because things will be in a reasonably consistent state.
Dissecting existing stuff is only good for example for finding out some fine details, such as, say, exact sizes of mobs, or exact physics constants used, or maximum message length etc.

If you want to start coding, have a look at the plugin request subforum, there are a million ideas there that need refining and then implementing Smile

100% agree with you. Wink
Reply
Thanks given by:
#9
It's offtopic, but why not a Mod API? So wie can make New mods with this API Wink
Reply
Thanks given by:
#10
I think, the server would need a major refactoring to allow this.
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)