Jump to content

[1.9.4] Why is a mod version defined by both the mcmod.info file and the @mod?


DavidTriphon

Recommended Posts

Everything I've been taught in my Java classes revolves around unify, unify, unify. There should never be 2 places for the same thing, or a way for you to change a constant that might break the usability of the code. I understand that they're stored different ways, one as a constant within the mod class (presumably) and as text in the mcmod.info text file, but is there any practical way to unify these? Like read the version from the mcmod.info to declare the version constant in the mod class?

 

I've just started to learn how to use git (from this) so that I have version control over my mod projects as I learn, (and have a public host for my code when I request help) but I don't want to have to worry about forgetting to change both version specifications and goofing something up.

 

And yes, I already know that all you FML devs want me to use "MCVERSION-MAJORMOD.MAJORAPI.MINOR.PATCH" for versioning.

Always, RESEARCH before asking a question. It's likely someone has already asked your question in the past. Filter your google searches with "site:www.minecraftforge.net/forum" to have a better chance finding your problem.

Link to comment
Share on other sites

The reason it is in two places is so that repositories (like Curse) can identify the mod version without having to decompile the java classes.

 

If you want to change it in one place, use gradle's

replace

feature to do it for you.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Oh, well, okay then. I think I'll stick with what I have then. I know nothing about gradle, much less the compile process for forge mods, which is the subject that I immediately come across when I do a quick google search of '"gradle replace" forge'. Hopefully I'll learn something relevant to automating version counting in that git guide I linked to.

Always, RESEARCH before asking a question. It's likely someone has already asked your question in the past. Filter your google searches with "site:www.minecraftforge.net/forum" to have a better chance finding your problem.

Link to comment
Share on other sites

It's super easy.

 

I have this in my gradle build file:

minecraft {
    version = "1.7.10-10.13.2.1291"
    runDir = "eclipse"
    assetDir = "eclipse/assets"
    replace "{@version:lib}":libVersion,"{@version:ore}":oresVersion,"{@version:haz}":hazardsVersion,"{@version:wld}":wildlifeVersion,"{@version:ind}":industryVersion,"required-after:HardLib""required-after:HardLib@["+releaseVersion+"."+majorVersion+",]"),"/*{uncomment}":"","{uncomment}*/":""
}

 

That last, monster, of a line is a list of a->b replacements.  The variables are set up like so:

 

def releaseVersion  = "15"
def majorVersion    = "26"
def minorVersion    = "1"
//bugpatch or testing versions
def libVersion      = "a"
def oresVersion     = "b"
def hazardsVersion  = "a"
def wildlifeVersion = "b"
def industryVersion = "a"
def prePend = "1.7.10-"
def packageVersion  = releaseVersion+"."+majorVersion+"."+minorVersion+libVersion+oresVersion+hazardsVersion+wildlifeVersion+industryVersion

libVersion = releaseVersion+"."+majorVersion+"."+minorVersion+libVersion
oresVersion = releaseVersion+"."+majorVersion+"."+minorVersion+oresVersion
hazardsVersion = releaseVersion+"."+majorVersion+"."+minorVersion+hazardsVersion
wildlifeVersion = releaseVersion+"."+majorVersion+"."+minorVersion+wildlifeVersion
industryVersion = releaseVersion+"."+majorVersion+"."+minorVersion+industryVersion

 

(It is outside of all blocks).  I've got effectively six mods in the same environment, but they're all closely related so I like to test them side by side.  The last replacement is for a chunk of code that I can compile, but not run in Eclipse because Reika doesn't supply deobf versions of any of his stuff.  It was easier to just say "fuck it" and only have the code for release (which now doesn't work anyway, because Reika doesn't realize that APIs are supposed to be a contract saying that they won't suddenly change and cause crashes, not that what I wanted to do in the first place worked anyway because his API was using reflection to access his own methods and was Doing it Wrong).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Okay, so after taking some time to stare at your code, I think I understand the syntax, but I'm not quite sure how this unifies the numbers. The minecraft portion and the replace command would go something like this I think for me:

 

minecraft
{
   version = "1.9.4-12.17.0.1976"
   runDir = "run"
   replace "{@version:cubex}":cubexVersion
}

I assume that runDir might need to be changed to eclipse? Or do you have your project structured differently? If I change runDir does that change the directory that the game save runs in? I don't know if that would break my compiling completely or not matter at all. I am using 1.9.4 (quickly adds it to the title). The last time I did anything in 1.7.10 was when I was first modding before I had even taken a java class, I was self-teaching myself through the oracle tutorials, so I don't remember any of that. :P

 

Oh, and of course my defines would probably look like this, since I only have one mod (going by the shortened name of "cubex").

 

def mcVersion         = "1.9.4-"
def majorModVersion   = "0"
def apiModVersion     = "0"
def minorModVersion   = "1"
def cubexPatchVersion = "0"

def cubexVersion = mcVersion+majorModVersion+"."+apiModVersion+"."+minorModVersion+"."+cubexPatchVersion

So... how much of this did I get right and how much of it is wrong? Oh, and what exactly does replace replace? Does it only replace the text in my mcmod.info file, or does it override the constant version supplied to @mod in my mod class?

 

Also, thanks for changing that "gradle" earlier to Monaco font. I wouldn't have known that was an available font for in line code if you hadn't done it. I'll be doing that more in the future.

Always, RESEARCH before asking a question. It's likely someone has already asked your question in the past. Filter your google searches with "site:www.minecraftforge.net/forum" to have a better chance finding your problem.

Link to comment
Share on other sites

my rundir is "eclipse", yes.  I don't know what it looks like for other environements (IntelliJ, etc)

 

So... how much of this did I get right and how much of it is wrong? Oh, and what exactly does replace replace? Does it only replace the text in my mcmod.info file, or does it override the constant version supplied to @mod in my mod class?

 

Ok, so.  The only thing I'd change is drop the

mcVersion

from your cubexVersion string.  That can just be on the jarfile, your mod's version number shouldn't need to be prefixed with that (but it's not hurting anything).  I'd probably also swap "major version" and "api version."  Your API should be changing less often than the mod itself and you ABSOLUTELY want the api version change to trigger a mod version change.*

 

As for what the

replace

command does: the paramers passed are comma separated key:value pairs where your entire codebase is searched for the "key" and replaced (before compiling occurs) with the "value."  That's why in the code you use a semi-unique string for anything you want to replace.  Hence the {@} characters.  (Replacing something like "version" would nab

string versionNum = ...

and make that not compile...on account of now reading

String 1.9.4-0.0.1.0Num = ...

).

 

Also, thanks for changing that "gradle" earlier to Monaco font.

 

That's just the code tag. I didn't do anything. :P

 

*You can also do a replacement on your dependency's version numbers!  My numbering system ended up being crap, but it made sense when I started ("number-of-times-released (major)"-"internal (major)"-"minor" and regretted it as soon as I had to fix a bug in the API).  So you could have an "{@version:api}" string in your "required:after" dependency notation in your @mod and let gradle automatically fill that in when your API changes.  Assuming you treat your API like a separate mod (which you should be, so other modders don't need your whole mod in their workspace to integrate with your API).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

my rundir is "eclipse", yes.  I don't know what it looks like for other environements (IntelliJ, etc)

 

Yeah, I'm also running eclipse, I think that the run directory is the same for everything though and mine is default to run just because it's probably changed since 1.7.10 to free up the 'actually for eclipse' folder.

 

That's just the code tag. I didn't do anything. :P

 

Oops, I meant the "replace" in your first post reply, posted here:

 

If you want to change it in one place, use gradle's
replace

feature to do it for you.

 

Which now that I quote you, I see that you just used teletype "<tt>replace</tt>".

 

Okay, now onto the actually important stuff:

 

Your API should be changing less often than the mod itself and you ABSOLUTELY want the api version change to trigger a mod version change.

 

Hmm! This makes sense, I wonder why the FML devs opt for the other order on the documentation. I guess it's not stringent or absolutely necessary, so I think I'll follow your lead.

 

As for what the replace command does: the paramers passed are comma separated key:value pairs where your entire codebase is searched for the "key" and replaced (before compiling occurs) with the "value."  That's why in the code you use a semi-unique string for anything you want to replace.  Hence the {@} characters.  (Replacing something like "version" would nab string versionNum = ... and make that not compile...on account of now reading String 1.9.4-0.0.1.0Num = ...).

 

I had to read that about 10 times, but I get it now. So in my main mod class, I would want to change ... :

 

@Mod(modid = CubularExpansion.MODID, version = CubularExpansion.VERSION,
      acceptedMinecraftVersions = CubularExpansion.ACCEPTED_VERSIONS)
public class CubularExpansion
{
   // STATIC CONSTANTS

   public static final String     MODID             = "cubex";
   public static final String     NAME              = "Cubular Expansion Mod";
   public static final String     VERSION           = "1.9.4-0.0.1.0";
   public static final String     ACCEPTED_VERSIONS = "1.9.4";

   ...

}

 

to ...

 

@Mod(modid = CubularExpansion.MODID, version = CubularExpansion.VERSION,
      acceptedMinecraftVersions = CubularExpansion.ACCEPTED_VERSIONS)
public class CubularExpansion
{
   // STATIC CONSTANTS

   public static final String     MODID             = "cubex";
   public static final String     NAME              = "Cubular Expansion Mod";
   public static final String     VERSION           = "@mcVersion-@apiVersion-@cubexVersion";
   public static final String     ACCEPTED_VERSIONS = "@mcVersion"; // only if I wanted it to only work for the current version

   ...

}

 

I would probably separate mcVersion from cubexVersion and any other mod or api versions I had in my gradle then. I'm already seeing all the advantages of replacing those @variables in my code while programming multiple mods. Oh, and if I put "@mcVersion" in my mcmod.info file, it would also replace that, correct?

 

This is very interesting, very interesting indeed. You've helped me a lot today, thanks for spending time helping me with this. I greatly appreciate it!

 

Thought, your last comment does make me begin to think:

 

*You can also do a replacement on your dependency's version numbers!  My numbering system ended up being crap, but it made sense when I started ("number-of-times-released (major)"-"internal (major)"-"minor" and regretted it as soon as I had to fix a bug in the API).  So you could have an "{@version:api}" string in your "required:after" dependency notation in your @mod and let gradle automatically fill that in when your API changes.  Assuming you treat your API like a separate mod (which you should be, so other modders don't need your whole mod in their workspace to integrate with your API).

 

If I had an API (which I currently don't), I would probably want to separate it and all my other mods into separate gits, so that for each version I could test it on top of a lib of any version of my API or other mods. I'm thinking that I'm going to keep the mcVersion in the version for my mods in case I ever decide to keep support for multiple mc versions of a mod. However, if I use separate gits for each mod, then that would mean I would have to keep them in different project spaces, right? Suddenly another question comes to mind: If I need to make libraries from my other projects, and I have a different build.gradle for a different project, will it overwrite the @version's in that library, or are libraries created from compiled code? like what is generated in the bin folder? I'm going to have to think about this much more later, I must have spent more than an hour writing this. XP

Always, RESEARCH before asking a question. It's likely someone has already asked your question in the past. Filter your google searches with "site:www.minecraftforge.net/forum" to have a better chance finding your problem.

Link to comment
Share on other sites

Oops, I meant the "replace" in your first post reply

Which now that I quote you, I see that you just used teletype "<tt>replace</tt>".

 

Oh yeah. :D <tt> is a great tag.

 

Okay, now onto the actually important stuff:

 

Hmm! This makes sense, I wonder why the FML devs opt for the other order on the documentation. I guess it's not stringent or absolutely necessary, so I think I'll follow your lead.

 

Either one is probably fine.  API for me just seems "more bigger" than their details there, though this is my first time seeing that.  Don't sweat it too much.

 

I had to read that about 10 times, but I get it now. So in my main mod class, I would want to change ... :

 

to ...

 

   public static final String     VERSION           = "@mcVersion-@apiVersion-@cubexVersion";
   public static final String     ACCEPTED_VERSIONS = "@mcVersion"; // only if I wanted it to only work for the current version

 

I would probably separate mcVersion from cubexVersion and any other mod or api versions I had in my gradle then. I'm already seeing all the advantages of replacing those @variables in my code while programming multiple mods. Oh, and if I put "@mcVersion" in my mcmod.info file, it would also replace that, correct?

 

I'd actually do this:

 

   public static final String     VERSION           = "{@cubexVersion}";
   public static final String     ACCEPTED_VERSIONS = "{@mcVersion}"; // only if I wanted it to only work for the current version

 

Which matches the gradle file:

 

def cubexVersion = mcVersion+majorModVersion+"."+apiModVersion+"."+minorModVersion+"."+cubexPatchVersion
//...
replace "{@cubexVersion}:cubexVersion,"{@mcVersion}":mcVersion

 

Just "@cubexVersion" is probably fine (as long as that matches the gradle replace command), but wrapping it in curly braces makes it very clear "this is an external variable."

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Oh, one question I forgot to ask, do the defines in the build.gradle file go in

dependencies {

or something else?

Always, RESEARCH before asking a question. It's likely someone has already asked your question in the past. Filter your google searches with "site:www.minecraftforge.net/forum" to have a better chance finding your problem.

Link to comment
Share on other sites

The defines go outside all of the blocks in the gradle file, eg:

buildscript {
    ...
}

apply plugin: 'forge'

def apiVersion  = "1"
def majorVersion    = "0"
def minorVersion    = "0"

minecraft {
    ...
}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • When i try to launch Minecraft Java 1.20.1 forge with mods (82 mods),on start it loaded all mods,but at end Java just crashed.  p.s i allocated 8GB ram for minecraft and i didn't runned another instance.Log file pp.s I use ATlauncher   Environment: Organising filesystem [24/04/2024 23:40:08 PM] ATLauncher Version: 3.4.36.3 [11ae0b2334c236e93ee8128de980952b2a1b8900] [24/04/2024 23:40:08 PM] App Arguments: ["--install-method=aur","--no-launcher-update"] [24/04/2024 23:40:08 PM] JVM Arguments: ["-Dawt.useSystemAAFontSettings=on","-Dswing.aatext=true"] [24/04/2024 23:40:08 PM] Java Version: Java 22 (22) [24/04/2024 23:40:08 PM] Java Path: /usr/lib/jvm/java-22-openjdk [24/04/2024 23:40:08 PM] 64 Bit Java: true [24/04/2024 23:40:08 PM] RAM Available: 14931MB [24/04/2024 23:40:08 PM] Launcher Directory: **USERSDIR** [24/04/2024 23:40:08 PM] GPU: IvyBridge GT2 [HD Graphics 4000] (Intel Corporation (0x8086)) unknown 256MB VRAM [24/04/2024 23:40:08 PM] CPU: Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz 4 cores/8 threads [24/04/2024 23:40:08 PM] Operating System: EndeavourOS (unknown (unknown) build 6.8.7-arch1-1) [24/04/2024 23:40:08 PM] Bitness: 64 [24/04/2024 23:40:08 PM] Uptime: 15889 [24/04/2024 23:40:08 PM] Manufacturer: GNU/Linux
    • If you have nvidia graphics, don't touch your amd drivers, otherwise it might fix it but keep running on integrated graphics, which will result in terrible performance. For nvidia graphics, you need to tell windows and nvidia control panel that anything Minecraft related (the launcher, java, etc...) should prefer high performance graphics so that it actually uses your nvidia gpu
    • In the ever-evolving landscape of technology, the rise of cryptocurrencies and digital assets has introduced both unparalleled opportunities and unprecedented challenges. As these digital currencies become increasingly prevalent, so too does the risk of theft and loss. Yet, amidst the complexity and uncertainty, there exists a beacon of hope: ADRIAN LAMO HACKER. Technology has indeed become more sophisticated and enhanced, presenting new challenges in the realm of asset recovery. However, just as any other currency can be stolen or lost, crypto and digital assets are not beyond redemption. With the right expertise and guidance, recovery is possible and achievable. Contact ADRIAN LAMO HACKER via the website: https://adrianlamohackpro.online/ , a trusted, honest, and certified agency specializing in the retrieval of stolen or lost digital assets. In my own experience, I found myself in dire straits after falling victim to cybercriminals who absconded with a significant portion of my crypto holdings. It was a daunting situation, but I refused to succumb to despair. Upon engaging ADRIAN LAMO HACKER, their professionalism, and integrity immediately struck me, as an unwavering commitment to their clients. They deeply understand blockchain technology and utilize advanced methodologies to trace and recover lost or stolen funds. Their approach is meticulous, their expertise unparalleled, and their results speak for themselves. In a matter of days, ADRIAN LAMO HACKER successfully traced and recovered over 90% of my stolen funds, a feat I once believed to be unattainable. Their fees were fair and transparent, and communication throughout the process was nothing short of excellent. They kept me informed every step of the way, providing reassurance and guidance when I needed it most. For anyone who has fallen victim to crypto theft or loss, I wholeheartedly recommend ADRIAN LAMO HACKER. They are not just experts in their field; they are guardians of justice in the digital realm. With their assistance, you can reclaim what's rightfully yours and emerge stronger than ever before. So, if you find yourself grappling with the devastation of lost or stolen digital assets, don't despair. Reach out to ADRIAN LAMO HACKER via website: https://adrianlamohackpro.online/  / Telegram: @ADRIANLAMOHACKERTECH and let them guide you toward a brighter tomorrow.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.