-
Posts
765 -
Joined
-
Last visited
-
Days Won
27
Paint_Ninja last won the day on September 15
Paint_Ninja had the most liked content!
Recent Profile Visitors
502164 profile views
Paint_Ninja's Achievements
World Shaper (7/8)
55
Reputation
-
Way back in the Forge 1.17 days, work started for adding JPMS (Java Platform Module Support) to ModLauncher and ForgeModLoader. This has been used internally by Forge and some libraries for a while now, but mods (those with mods.toml specifically) have not been able to take advantage of it. As of Forge 1.21.1 and 1.21.3, this is now possible! What is JPMS and what does it mean for modders? JPMS is the Java Platform Module System, introduced in Java 9. It allows you to define modules, which are collections of packages and resources that can be exported or hidden from other modules. This allows for much more fine-tuned control over visibility, cleaner syntax for service declarations and support for sealed types across packages. For example, you might have a mod with a module called `com.example.mod` that exports `com.example.mod.api` and `com.example.mod.impl` to other mods, but hides `com.example.mod.internal` from them. This would allow you to have a clean API for other mods to use, while keeping your internal implementation details hidden from IDE hints, helping prevent accidental usage of internals that might break without prior notice. This is particularly useful if you'd like to use public records with module-private constructors or partially module-private record components, as you can create a sealed interface that only your record implements, having the interface be exported and the record hidden. It's also nice for declaring and using services, as you'll get compile-time errors from the Java compiler for typos and the like, rather than deferring to runtime errors. In more advanced cases, you can also have public methods that are only accessible to specific other modules -- handy if you want internal interactions between multiple of your own mods. How do I bypass it? We understand there may be drama in implementing a system that prevents mods from accessing each other's internals when necessary (like when a mod is abandoned or you need to fix a compat issue) -- after all, we are already modding a game that doesn't have explicit support for Java mods yet. We have already thought of this and are offering APIs from day one to selectively bypass module restrictions. Let me be clear: Forge mods are not required to use JPMS. If you don't want to use it, you don't have to. The default behaviour is to have fully open, fully exported automatic modules. In Java, you can use the `Add-Opens` and `Add-Exports` manifest attributes to selectively bypass module restrictions of other mods at launch time, and we've added explicit support for these when loading your Forge mods. At compile-time, you can use existing solutions such as the extra-java-module-info Gradle plugin to deal with non-modular dependencies and add extra opens and exports to other modules. Here's an example on how to make the internal package `com.example.examplemod.internal` open to your mod in your build.gradle: tasks.named('jar', Jar) { manifest { attributes([ 'Add-Opens' : 'com.example.examplemod/com.example.examplemod.internal' 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors // (...) ]) } } With the above in your mod's jar manifest, you can now reflectively access the classes inside that internal package. Multiple entries are separated with a space, as per Java's official spec. You can also use Add-Exports to directly call without reflection, however you'd need to use the Gradle plugin mentioned earlier to be able to compile. The syntax for Add-Exports is the same as Add-Opens, and instructions for the compile-time step with the Gradle plugin are detailed later in this post. Remember to prefer the opens and exports keywords inside module-info.java for sources you control. The Add-Opens/Add-Exports attributes are only intended for forcing open other mods. What else is new with module support? Previously, the runtime module name was always forced to the first mod ID in your `mods.toml` file and all packages were forced fully open and exported. Module names are now distinguished from mod IDs, meaning the module name in your module-info.java can be different from the mod ID in your `mods.toml`. This allows you to have a more descriptive module name that doesn't have to be the same as your mod ID, however we strongly recommend including your mod ID as part of your module name to aid troubleshooting. The `Automatic-Module-Name` manifest attribute is now also honoured, allowing you to specify a module name for your mod without needing to create a `module-info.java` file. This is particularly useful for mods that don't care about JPMS features but want to have a more descriptive module name and easier integration with other mods that do use JPMS. How do I use it? The first step is to create a `module-info.java` file in your mod's source directory. This file should be in the same package as your main mod class, and should look something like this: open module com.example.examplemod { requires net.minecraftforge.eventbus; requires net.minecraftforge.fmlcore; requires net.minecraftforge.forge; requires net.minecraftforge.javafmlmod; requires net.minecraftforge.mergetool.api; requires org.slf4j; requires logging; } For now, we're leaving the whole module open to reflection, which is a good starting point. When we know we want to close something off, we can remove the open modifier from the module and open or export individual packages instead. Remember that you need to be open to Forge (module name net.minecraftforge.forge), otherwise it can't call your mod's constructor. Next is fixing modules in Gradle. While Forge and Java support modules properly, Gradle does not put automatic modules on the module path by default, meaning that the logging module (from com.mojang:logging) is not found. To fix this, add the Gradle plugin and add a compile-time module definition for that Mojang library: plugins { // (...) id 'org.gradlex.extra-java-module-info' version "1.9" } // (...) extraJavaModuleInfo { failOnMissingModuleInfo = false automaticModule("com.mojang:logging", "logging") } The automatic module override specified in your build.gradle should match the runtime one to avoid errors. You can do the same for any library or mod dependency that is missing either a module-info or explicit Automatic-Module-Name, however be aware that you may need to update your mod once said library adds one. That's all you need to get started with module support in your mods. You can learn more about modules and how to use them at dev.java.
-
Forge version: 53.0.0 Minecraft version: 1.21.3 Downloads: Downloads page Note that as this is the start of a new version, it is recommended that you check the downloads page and use the latest version to receive any bug fixes, as the first ever build of Forge for any MC version is usually buggy. Intro: The first build for Forge 1.21.3 has been released! It is based on 52.0.22 for 1.21.1, however we'll still be releasing new builds for both 1.21.1 and older Minecraft versions, of course. We skipped 1.21.2 because it had some known bugs that were fixed shortly after release in 1.21.3 - similar to the 1.20.3 and 1.20.4 situation. If you find any issues, please let us know on the Discord.
-
It's a long time coming, but it's finally here -- as of Forge 1.21.1, we've now implemented the de-facto common tags! With the introduction of the de-facto common tags in Forge, there are now numerous tags that are shared across all major mod loaders. This means greater compatibility between mods across different loaders and a huge selection of new tags now bundled with Forge that are available for use in mods. It also means that datapack authors are less likely to need duplicate data or even separate datapacks for different loaders. We wanted to make it worth the wait, so we've gone above and beyond to ensure that the implementation of the common tags in Forge is as comprehensive and seamless as possible. Not only have we implemented all the tags -- including accounting for the many changes and additions made overtime -- we've also written tools that dump tags between the different loaders to identify differences, have comprehensive documentation on how to migrate to the new tags, bouncer fields to automatically make some old code use the new tags, avoided breaking changes entirely and adopted a stricter policy that clearly distinguishes between loader-specific and common tags. If you see a `c:` tag definition in Forge for a given version, you can be confident that it'll always work on all loaders that support the common tags. Many Neo-specific/Fabric-specific `c:` tags have also been added to Forge, under the `forge:` namespace, but we'll actively migrate them to `c:` as soon as they're adopted by the other loaders and provide a graceful deprecation period for the old tags. Overtime, we'll be working with other loaders to help further improve parity and keep things more in sync across versions moving forward, as well as updating Forge as new tags are added to other loaders, of course. We hope it has been worth the wait! Developers can find more information on Forge's implementation, including the common tags dumper and migration guides, in the description of pull request 9955. Background As for that wait, why did it take so long to implement in Forge after the other loaders? Shouldn't it have been a simple copy-and-paste job? Well... there were many hurdles to overcome that made implementing this feature in Forge difficult. A lot of work went into this, and I'd like to share just some of the many challenges faced. First of which was documentation and ease of migration: Early experiments of implementing this on Forge involved a simple copy-and-paste from Neo, however it quickly came apparent that this was not a good fit for Forge. There were many deliberate breaking changes that were initially undocumented, with various `forge:` namespaced tags being removed with no `c:` equivalents, around a hundred Neo-specific `c:` tags that were not available on Fabric despite having a dedicated `neoforge:` namespace for loader-specific tags and a "tag convention warning" system that would recommend migrating to the wrong tags as well as containing migration definitions from non-existent tags to `c:` equivalents and vice-versa. The discussions as to why certain tags were added, renamed, added, changed or removed were done across multiple PRs, Discord servers and channels. I'm aware of many different Discord channels where the tags were discussed, spanning multiple servers and thousands of messages, not to mention over 40 separate PRs made to the two loaders after the initial PRs and their associated filed issues, some of which contained further breaking changes. With no centralised discussion or documentation, combined with both loaders having differing goals that led to loader-specific `c:` tags on both sides, as well as bugs in the automated warning systems, it was very challenging to find the correct mappings and understand the reasoning behind them. Second was the approach taken by the other loaders: My understanding is that there were multiple attempts to create a central repo containing the code for common tags that the loaders could pull from so that it would be easy to update the tags in one place and have them propagate to all loaders, with clear indicators of what tags are available for a given version as well as well-documented parity across loaders, which is exactly what Forge was asking for in the past. However, all these attempts fell through over disagreements on management and permissions. As a last-ditch effort, the main person organising these discussions ended up directly creating PRs to the two loaders, but excluded Forge. These two initial big PRs were done accounting for loader-specific requests and with the intent of getting at least something done, rather than throwing away all the work that had been done so far. Bizarrely, the start of the description of both PRs implies that Forge was not interested in supporting the new tags, despite multiple Forge team members publicly expressing the opposite. Other loaders had the luxury of having the PRs made for them, which they could then review and merge, while Forge was left out of the loop. To make matters worse, said main person also refused to review my work in progress implementation to ensure consistency across loaders, stating that he doesn't use Forge anymore. I was essentially left to figure out the whole thing single-handedly, cross-referencing thousands of comments across multiple places, accounting for loader-specific differences and trying to get it up to Forge's standards. While working on Forge's implementation, people expressed frustration over this approach, as it looked like a deliberate attempt to make it hard for Forge to adopt the new tags. Even without considering the possibility of malice, it would've been easier to keep track of changes and loader-specific differences if a centralised document was maintained after loaders accept changes (that way the document would not require agreement from loaders). In my opinion, the manual approach of PRs to both sides and manually implementing parity improvements as they were requested without keeping track anywhere is more error-prone and labour-intensive. The following day I received an stern DM accusing me of spreading conspiracies about him making it hard for Forge to implement the new tags, along with a brief explanation of why the centralised repo didn't happen which further shaped my understanding explained here. I took the opportunity to thank him for reaching out with an explanation and provided more context on the frustrations people had with the approach taken, highlighting things such as the spread out nature of discussions, the lack of clear documentation and his refusal to review my implementation. I offered to work with him to fix some of the bugs I found on other loaders and we came to an understanding. This turned out to be pretty beneficial as I was able to directly ask him about the tags, get updates on new follow-up PRs made to other loaders and made him aware of some bugs and mistakes with the warning system and tags. I'm thankful for his willingness to reach out and help. Third is the sheer amount of tags and the moving target: Due to the approach taken by other loaders as explained earlier, there is no versioning for the de-facto spec. This has its own benefits and drawbacks. The main drawback being that the tags are out of sync across Minecraft versions -- you may see some tags on both loaders for the latest version, but only on one loader when going back an MC version. This is due to the differences in approach between the two loaders, where one is more focused on the latest version while the other supports multiple versions. This isn't entirely without its benefits though, as it allows Neo to deliver new tags faster by not needing to worry about older versions. There are many tags added, across many categories. Some existing Forge tags gained new contents, too. This is the biggest collaborative tag update the Minecraft modding community has ever seen, with a wide-reaching impact in terms of tags, which is a big win for interoperability and closely aligns with Forge's goal of being a compatibility layer for mods. Since the first big two PRs were made and Forge started working on its implementation, I've been keeping track of many amendment PRs made, cross-referencing them with each loader and Forge itself to ensure parity. A lot of new things have been further added and parity has been improving, but this does mean it's a moving target. Catching up with something that's continuously evolving means you need to be quick but thorough, which is a difficult balance to strike. While I've mostly been doing this single-handedly, I'd like to thank the people who have helped me along the way, such as Jonathan, Lex, TelepathicGrunt and others who have worked with me to overcome all of these hurdles and finally deliver Forge's implementation of the de-facto common tags. Conclusion I hope this document has provided some insight into some of the challenges faced when implementing the de-facto common tags in Forge, as well as the benefits it brings to the wider MC modding community. Now that all major mod loaders have adopted the common tags, I'm looking forward to seeing players, datapack authors and mod devs alike benefit from the compatibility benefits it brings to the whole MC modding ecosystem, no matter which loader you use.
-
Please share a link to your crash report on https://paste.ee, as explained in the FAQ
-
Joining causes block IDs to pop up on a modded server
Paint_Ninja replied to WinterArcGrind's topic in Support & Bug Reports
This is the Forge forums, we do not support Fabric here. Read the FAQ -
1.20.1 Annoying Lag Spikes when playing after a few minutes
Paint_Ninja replied to Cripjey's topic in Support & Bug Reports
You allocated too much RAM to the game, so the OS, drivers and other things are fighting for resources. Close as many things as you can when playing, allocate 3GB or 3.5GB max, do not set a min. In task manager go to the startup tab and disable things you don’t need to start and have always running when you turn on your PC, but ignore the AMD ones in the list (they’re needed). Use Java 21 instead of Java 17. Consider removing Alex’s Mobs. Update your Radeon drivers (see the FAQ). Consider buying more physical RAM for your PC -
AlphaIceCube started following Paint_Ninja
-
Forge version: 52.0.0 Minecraft version: 1.21.1 Downloads: Downloads page Note that as this is the start of a new version, it is recommended that you check the downloads page and use the latest version to receive any bug fixes, as the first ever build of Forge for any MC version is usually buggy. Intro: The first build for Forge 1.21.1 has been released! It is based on 51.0.33 for 1.21.0. We expect most existing 1.21.0 mods to work on 1.21.1 without needing any changes, as the only notable differences from Vanilla 1.21.0 -> 1.21.1 are a couple of new languages and a bugfix for an exploit that could be used to crash servers... as such, we strongly encourage all 1.21.0 players and mod developers to move to 1.21.1. From a mod dev perspective, BlockEntities now validate their block during construction - as long as that's fine you should be good to go. 1.21.0 has been moved to our minimal support tier, as explained in our tiered support policy - use 1.21.1 instead. If you find any issues, please let us know on the Discord. Sidenote: I'm sorry for not making these release posts for Forge betas of the past few MC versions. While I forgot to make some posts, we still released Forge builds for newer MC. When in doubt, check the sidebar on the files site. Same-day ports of Forge to new MC versions are common.
-
CV1122 started following Paint_Ninja
-
So, uh, no one responded to my pervious post, so imma try again.
Paint_Ninja replied to fnafer5634's topic in ForgeGradle
First, the solution: use the mdk and don't touch anything in it before checking that it works. You seemed to have changed something that broke it. You're also targeting 1.20.0 - *don't use this!* - it is a known buggy and abandoned version that people dropped in favour of 1.20.1 which came out shortly after. Next, a couple of things about your post: 1) you tagged it with "broken mod", which is commonly used to indicate that your issue has been solved and that the problem was that one of the mod's you installed was broken 2) please use code embeds. It's hard to interpret an arrow pointing to the issue in your error when the arrow doesn't line up properly -
CPU Lag Spikes Seem To Crash Server With Increasing Frequency
Paint_Ninja replied to shmunky's topic in Support & Bug Reports
Please share a link to your crash report on https://paste.ee, as explained in the FAQ. Dumping it directly into the thread often triggers the anti-spam and makes it hard to read due to word wrapping -
This is the Forge forums. We do not support NeoForge here - use Forge instead if you want help.
-
They were intended to be used on tutorial posts so that people could easily find tutorials based on their skill level, but instead the tags were abused for unrelated things that made the original intent useless... for example, people often posted crash reports with the "beginner" tag, so instead of finding tutorials for beginners, you got crash reports showing up in searches.
-
You can't mix mods for different MC versions.
-
1.20.1 Forge server lag and FPS drops near base
Paint_Ninja replied to Colonizer_Void's topic in Support & Bug Reports
Spark definitely has downloads available for Forge 1.20.1 on the CurseForge website. 47.0.35 is a very old beta version of Forge. You should be running 47.3.0 -
Forge crashes on any version newer than 1.12.2
Paint_Ninja replied to Forgeuser1253872's topic in Support & Bug Reports
Please share your crash report or log, as explained in the FAQ