*Basic* instructions for converting add-ons to new system

This sub-forum is dedicated to add-ons and texture packs for Better Than Wolves.
Post Reply
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

*Basic* instructions for converting add-ons to new system

Post by FlowerChild »

Ok guys, as usual, I'm not going to get into modding tutorials or what have you, and you're largely on your own in terms of figuring out how to write an add-on for BTW.

However, I did want to create this quick post to help people potentially convert any existing add-ons that use Modloader to the new system I'll be putting out with the next release:

-First, obviously BaseMod is no longer present. Your mod class should now inherit from FCAddOn, and one additional step is required to "register" your mod, and that is to instantiate its class as follows:

Code: Select all

public class FCBetterThanWolves extends FCAddOn
{
	public static FCBetterThanWolves m_instance = new FCBetterThanWolves();
}
Instantiating in this manner will automatically register your mod with the overall mod handler so that your hooks will be called at the appropriate times.

-FCAddOn contains a single abstract member function which you will need to override (a compile error will result otherwise), which is the Inititialize() function. As the name indicates, this is called when Minecraft first starts up, and is generally where you should do such things as registering blocks, etc.

-The FCAddOn class itself is extremely bare bones. I do not include any "convenience" functions in it (basically...this is a "pure" API with no "library" type functionality), of which Modloader has a number for handling things like registering blocks, creating custom packets for opening guis, and that kind of thing. The only time I include hooks is if the existing vanilla code structure makes doing something impossible otherwise without base class modifications. If you are uncertain as to how to do something as a result, then I suggest taking a look at how BTW is doing such things, as it is itself an FCAddOn. If you need a specific additional hook that I haven't included (I've only added ones for what I need myself and for what others have told me they need), then post the request to the appropriate thread as you usually would.

-There is no functionality present for specifying which mod is initialized before or after which others. However, knowing that for add-ons it may be important to do so before or after other mods (particularly BTW), I've included PreInitialize() and PostInitialize() functions in FCAddOn that are called before and after *all* mods are initialized. Thus, if any part of your initialization process is dependent on order, just override those and plop those parts into the appropriate function within your mod class.

-Unlike ModLoader, this obviously all works for both client and server compiles. However, if you haven't done server coding before, you should be aware that not all functions that exist on the client also exist on the server, thus your mod may require slight changes (usually removing code that pertains specifically to the client) in order to function. In the case of FCAddOn, all functions that only apply to the client version are clearly prefaced with "Client".

-I've included basic logger functionality in the FCAddOnHandler class to provide a central place where BTW and add-ons can log relevant information (similar to how modloader.txt works), so that players will know where to look if something goes wrong (it outputs to BTWLog.txt). If you want to make use of it, check out FCAddOnHandler.LogMessage(). Note that messages logged via this method will also appear in the server window if you're running an SMP server.

-As a final note: keep in mind, this isn't intended to be in any way noob-friendly. As I said, I've kept it extremely bare bones to minimize my own development investment here. It works, and should work very well, but I'm certainly not performing all the error checking and hand holding that ModLoader tends to within its code. Thus, if you fuck something up, don't expect a nice little message indicating what it was that you fucked up; expect a crash, or for your add-on to just not function.


I think that covers the basics. If there are questions pertaining *specifically* to the above, I'll endeavor to answer them, but please don't turn this into a "does it have 'foo' hook?" thread. In such cases, assume the answer is 'no' by default, and request it in the appropriate thread if you really need it.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

Oh, also worth mentioning: unlike modloader, you can call your mod class whatever you want. The code does not automatically search for names like "mod_" or what have you, which is why your mod class needs to be manually instantiated.

The need for that prefix in ML actually always drove me nuts, as it acts as a big exception to my own file naming convention which aids me in easily identifying mod files while working with them.
Bynari
Posts: 9
Joined: Thu Sep 13, 2012 8:03 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by Bynari »

Not a criticism- but I am curious as to your reasoning for ditching Modloader in favor of your own system. I can understand moving away from the monstrosity that is Forge, but in my experience Modloader has been a fairly friendly system with a lot of reference material available.

What motivated the change?
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

That has been discussed elsewhere, and is off-topic for this thread.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

Just a small change to what I described in the OP:

I'm changing the name of the FCMod class to FCAddOn because while porting to the server I realized that the FCMod thing is causing me quite the pain in the ass because I label all changes I make to vanilla code with "FCMOD" comments, which I can then easily search for.

Obviously, having classes using that naming convention as well causes a lot of false positives on such searches, and slows down the version update process as a result.

Just wanted to let you guys know about it to avoid any confusion when I release this thing.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

Ok, for clarity, here's the example code for instantiating your add-on using the new naming convention:

Code: Select all

public class FCBetterThanWolves extends FCAddOn
{
	public static FCBetterThanWolves m_instance = new FCBetterThanWolves();
}
I'll modify the OP to reflect this as well to avoid any misunderstandings.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

Also just added the following note to the OP:

-I've included basic logger functionality in the FCAddOnHandler class to provide a central place where BTW and add-ons can log relevant information (similar to how modloader.txt works), so that players will know where to look if something goes wrong (it outputs to BTWLog.txt). If you want to make use of it, check out FCAddOnHandler.LogMessage(). Note that messages logged via this method will also appear in the server window if you're running an SMP server.
Six
Posts: 599
Joined: Sat Jun 02, 2012 6:27 am

Re: *Basic* instructions for converting add-ons to new syste

Post by Six »

Just a note on something DNoved1 and I both ran into, decompilling with the latest MCP gets one naming thing wrong which needs to be changed. In EntityAnimal from the client, the methods 'setRevengeTarget' and 'OnNearbyAnimalAttacked' need 'this.breeding' to be changed to 'entityLivingToAttack'. Both should have two occurrences of it.

Changing those should fix it up.

--Edit--
Further note as I work through this stuff myself. Make sure to decompile, make those changes stated above first, recompile, then regenerate the md5 values (updatemd5.bat). I imagine there is another way to solve this by changing some of the mcp mappings, but this should do the trick.
User avatar
ExpHP
Posts: 302
Joined: Sun Jun 03, 2012 1:45 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by ExpHP »

DNoved1 and I have been messing around with this, and have found that, even following the instuctions to the letter, our addon class will still not be loaded until we add a reference to it somewhere in a vanilla class; something to make the java classloader care about it.

To give an idea of the nature of our problem, simply adding a static, void, empty method to our class and calling it in an early vanilla method (like the Block constructor) is enough to make it load.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

K, I'll take a look at the above and try to work something out for it tomorrow. Strange that.
TheGroovyWorkshed
Posts: 20
Joined: Sun Dec 16, 2012 11:53 am

Re: *Basic* instructions for converting add-ons to new syste

Post by TheGroovyWorkshed »

ExpHP wrote:DNoved1 and I have been messing around with this, and have found that, even following the instuctions to the letter, our addon class will still not be loaded until we add a reference to it somewhere in a vanilla class; something to make the java classloader care about it.
I'm having the exact same problem. Thanks for saying something because I was scared of making a fool of myself, especially considering how rightly annoyed FC gets about code questions from newbies like myself. Also, ditto on the EntityAnimal issue. Apologies for the low-content post but I've been trying to get this to work for a little while now and finding someone else with the same problem compelled me to respond, so thanks again.
User avatar
Uristqwerty
Posts: 30
Joined: Sat Nov 03, 2012 2:51 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by Uristqwerty »

The JVM specification, section 5.5, says that a Class isn't initialized until a static field is accessed, a static method is invoked, or an instance of that class is created. (or a few technical cases, such as reflection, Class.forName, whatever class contains main(), or if a subclass is initialized).

That initialization includes running all static{} blocks and static field initialization.

It certainly complicates loading mods, which is why ModLoader requires mod_ in the name (can be read from the filesystem/zip/jar before trying to load the class), and FML uses some sort of assembly library to inspect all .class files in each mod, looking for the ones that have a certain annotation.

Last I looked at bukkit, two years ago, you had to specify the class in a text file. It might have changed since, though.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

K, think I got it sorted to automatically scan for add ons, load their classes, and instantiate them so that you no longer have to do it manually. Also figured out a way to do it so that it doesn't require a specific file-naming convention like modloader does, since as I mentioned that was always a bit of a pet-peeve of mine.

I'll likely put out a test release later today so you guys can give it a try before the next official release.
User avatar
FlowerChild
Site Admin
Posts: 18753
Joined: Mon Jul 04, 2011 7:24 pm

Re: *Basic* instructions for converting add-ons to new syste

Post by FlowerChild »

Sorry guys, but the auto class loader I prepared for 4.85 blew up in my face at the last minute as I was testing on a release version of MC.

I decided to revert to the old code to get the release out, and will attempt to fix it up tomorrow. My apologies if anyone was waiting on that.
Post Reply