Right now almost everything is in the toml. We have this lovely definition file that lets you define basically all the information for displaying your mod in the mods list, but it doesn't define the main class needed for loading tht mod.
The main class is only found when forge goes on a round-trip visiting every type on the classpath and checking if any of them have the @Mod annotation, which is... horribly inefficient, not to mention, as I've experience, not terribly reliable either. The only configuration that has worked for me has been the unmodified mdk setup that's provided from the website.
So I figure why don't we get rid of the @Mod and forego class discovery entirely from 1.14 onwards?
Note I don't necessarily mean the annotation has to go away (forge can still use it for validation purposes), but rather we should shift its responsibility to a line in the toml:
[[mods]]
modId="examplemod"
mainClass="com.example.mod.ExampleMod"
IAmADisgraceToModdingAndCantBeBotheredLearningHowToWriteProperModsSoPleaseMakeThisModOnlyWorkOnThe=POTATO
version="1.0.0"
displayName="Example Mod"
displayURL="http://mod.example.com/"
credits="Author, Author, Author, et. al."
authors="Doge"
description='''
An Example Mod
'''
Aren't there other things that benefit of the classes scan too? For example if I guess correctly ObjectHolders or EventBusSubscribers would still require this scan (Presuming I guess correctly and they use the same scan data), so how could one get around these?
Even if the classes scan would need to stay, it would presumably be clearer to have all mod-metadata collected in one single file...
@MajorTuvok That's a good point, I hadn't thought of that. Usages inside the main class could _just work_ since the class is going to loaded directly by the reference in the toml.
As for other ones: I suppose you could hook into the class loading and parse the annotations at that stage? That would work well of ObjectHolder, it's only the EvenBusSubscribers that might either need to be explicitly registered from the main class, or otherwise declared in the toml as submodules of your mod.
This was based on the premise that forge is specifically scanning for mod classes separate from other things first.
it would presumably be clearer to have all mod-metadata collected in one single file...
The main class is not 'mod metadata' (IMHO). It changes sometimes (like when you refactor your mod), has nothing to do with all the other attributes and is annoying to construct.
Also, ensuring the mod's code is properly loaded is the job of the relevant language loader. The information in mods.toml however is generic and (at least currently) not dependant on which language loader loads the mod. Having a mainClass attribute in there is semantically wrong since a mod might not have a main class (if it's written in say JavaScript), or have multiple ones (I mean some kind of loader that considers multiple main classes per mod), or or or. It also destroys the neat seperation between code and data.
Edit: If you wonder what FML/forge actually does, it in fact collects all annotations and just gets the relevant ones later-
The main class is not 'mod metadata' (IMHO). It changes sometimes (like when you refactor your mod), has nothing to do with all the other attributes and is annoying to construct.
I see it differently from that. The main class doesn't necessarily have to be _a class_ but rather a way of saying "this is where the mod starts." The value could point to a javascript file or a php file, and how it's handled is left down to whatever language handler is being used--which just so happens to _also_ be defined in the toml.
The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml" #mandatory
A version range to match for said mod loader - for regular FML @Mod it will be the forge version
loaderVersion="[25,)" #mandatory (24 is current forge version)
or have multiple ones, or or or
Or, or, or, It was my understanding that you can define multiple "mod" blocks in the toml. Though who knows, I may have entirely misread that part of the mdk.
[[mods]]
modId="examplemod"
mainClass="com.example.mod.ExampleMod"
[[mods]]
modId="exampleclientmod"
mainClass="com.example.mod.client.ExampleClientMod"
Edit: If you wonder what FML/forge actually does, it in fact collects all annotations and just gets the relevant ones later-
I may have forgotten that part. I remember hearing it being mentioned and wondering to myself why that can't be turned into a build task. Annotations like that can be just as much considered part of the runtime data for the mod.
Edit: Markdown, why do you do this to me >..>
which just so happens to also be defined in the toml.
That's because every mod has and by definition needs a loader to be considered a mod by forge. Whereas the notion of an entryPoint (which is a way better name than mainClass) might not apply to all mods.
Also reread my last comment. And we should probably continue this conversation on discord (?)..
Sure, I'll be open to discuss it further on Discord a bit later, @JoJoDeveloping .
You don't really seem to understand how annotation scanning works. This system has been in place for ages, and it's always worked completely fine. There's no reason to change it now, writing class names into resources is way more flimsy than an annotation.
Most helpful comment
The main class is not 'mod metadata' (IMHO). It changes sometimes (like when you refactor your mod), has nothing to do with all the other attributes and is annoying to construct.
Also, ensuring the mod's code is properly loaded is the job of the relevant language loader. The information in mods.toml however is generic and (at least currently) not dependant on which language loader loads the mod. Having a mainClass attribute in there is semantically wrong since a mod might not have a main class (if it's written in say JavaScript), or have multiple ones (I mean some kind of loader that considers multiple main classes per mod), or or or. It also destroys the neat seperation between code and data.
Edit: If you wonder what FML/forge actually does, it in fact collects all annotations and just gets the relevant ones later-